mirror of
https://github.com/schollz/croc.git
synced 2024-11-24 08:02:33 +03:00
working
This commit is contained in:
parent
859130a988
commit
c1c8e39499
7
go.mod
7
go.mod
@ -4,17 +4,20 @@ require (
|
||||
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575
|
||||
github.com/denisbrodbeck/machineid v1.0.1
|
||||
github.com/fatih/color v1.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20190404155422-f8f10df84213 // indirect
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.7 // indirect
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/schollz/mnemonicode v1.0.1
|
||||
github.com/schollz/pake v1.1.0
|
||||
github.com/schollz/progressbar/v2 v2.10.0
|
||||
github.com/schollz/progressbar/v2 v2.12.0
|
||||
github.com/schollz/spinner v0.0.0-20180925172146-6bbc5f7804f9
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/urfave/cli v1.20.0
|
||||
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c // indirect
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313 // indirect
|
||||
)
|
||||
|
11
go.sum
11
go.sum
@ -7,8 +7,12 @@ github.com/denisbrodbeck/machineid v1.0.1 h1:geKr9qtkB876mXguW2X6TU4ZynleN6ezuMS
|
||||
github.com/denisbrodbeck/machineid v1.0.1/go.mod h1:dJUwb7PTidGDeYyUBmXZ2GphQBbjJCrnectwCyxcUSI=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/google/pprof v0.0.0-20190404155422-f8f10df84213 h1:y77GPNuZbqlt3/OjKA9yysnnxxqW+XwLaGY3ol9Mgmc=
|
||||
github.com/google/pprof v0.0.0-20190404155422-f8f10df84213/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
@ -28,9 +32,13 @@ github.com/schollz/pake v1.1.0 h1:+tYqsPVkuirFpmeRePjYTUhIHHKLufdmd7QfuspaXCk=
|
||||
github.com/schollz/pake v1.1.0/go.mod h1:pL7Z08gnQ4OQ3G27s5e5T6TEzp6cFc5GzCwLm0f75Io=
|
||||
github.com/schollz/progressbar/v2 v2.10.0 h1:AxYYUjr5fOPlA0Pcqc3R3kDBrqyLFWk2P7LRLdXb3yE=
|
||||
github.com/schollz/progressbar/v2 v2.10.0/go.mod h1:l6tn6yU6ZdQoF8lwX/VoAUQ3FjhCbrcZDnl9xeWZzYw=
|
||||
github.com/schollz/progressbar/v2 v2.12.0 h1:eTkmx9oWkRqi+rAzSDsreLbwGHvlrLJDR8xzmO0ccDI=
|
||||
github.com/schollz/progressbar/v2 v2.12.0/go.mod h1:fBI3onORwtNtwCWJHsrXtjE3QnJOtqIZrvr3rDaF7L0=
|
||||
github.com/schollz/spinner v0.0.0-20180925172146-6bbc5f7804f9 h1:y08o5oQ/slxXE/F0uh5dd8mdVvb+w4NLcNSDSq4c2F0=
|
||||
github.com/schollz/spinner v0.0.0-20180925172146-6bbc5f7804f9/go.mod h1:kCMoQsqzx4MzGJWaALr6tKyCnlrY0kILGLkA1FOiLF4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -38,6 +46,8 @@ github.com/tscholl2/siec v0.0.0-20180721101609-21667da05937 h1:lhssCpSe3TjKcbvUo
|
||||
github.com/tscholl2/siec v0.0.0-20180721101609-21667da05937/go.mod h1:KL9+ubr1JZdaKjgAaHr+tCytEncXBa1pR6FjbTsOJnw=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c h1:Rx/HTKi09myZ25t1SOlDHmHOy/mKxNAcu0hP1oPX9qM=
|
||||
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -47,3 +57,4 @@ golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjW
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
209
src/croc/croc.go
209
src/croc/croc.go
@ -3,9 +3,11 @@ package croc
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/elliptic"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@ -17,6 +19,7 @@ import (
|
||||
"github.com/denisbrodbeck/machineid"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/schollz/croc/v6/src/comm"
|
||||
"github.com/schollz/croc/v6/src/compress"
|
||||
"github.com/schollz/croc/v6/src/crypt"
|
||||
"github.com/schollz/croc/v6/src/logger"
|
||||
"github.com/schollz/croc/v6/src/message"
|
||||
@ -254,25 +257,35 @@ func (c *Client) transfer(options TransferOptions) (err error) {
|
||||
// listen for incoming messages and process them
|
||||
for {
|
||||
var data []byte
|
||||
var done bool
|
||||
data, err = c.conn[0].Receive()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = c.processMessage(data)
|
||||
done, err = c.processMessage(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if done {
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) processMessage(payload []byte) (err error) {
|
||||
func (c *Client) processMessage(payload []byte) (done bool, err error) {
|
||||
m, err := message.Decode(c.Key, payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch m.Type {
|
||||
case "finished":
|
||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||
Type: "finished",
|
||||
})
|
||||
done = true
|
||||
return
|
||||
case "pake":
|
||||
// if // c.spinner.Suffix != " performing PAKE..." {
|
||||
// // c.spinner.Stop()
|
||||
@ -294,11 +307,25 @@ func (c *Client) processMessage(payload []byte) (err error) {
|
||||
log.Debug("session key is verified, generating encryption")
|
||||
key, err := c.Pake.SessionKey()
|
||||
if err != nil {
|
||||
return err
|
||||
return true, err
|
||||
}
|
||||
c.Key, err = crypt.New(key, []byte(c.Options.SharedSecret))
|
||||
if err != nil {
|
||||
return err
|
||||
return true, err
|
||||
}
|
||||
|
||||
// connects to the other ports of the server for transfer
|
||||
for i := 1; i < len(c.Options.RelayPorts); i++ {
|
||||
c.conn[i], err = tcp.ConnectToTCPServer(
|
||||
fmt.Sprintf("%s:%s", c.Options.RelayAddress, c.Options.RelayPorts[i]),
|
||||
fmt.Sprintf("%s-%d", utils.SHA256(c.Options.SharedSecret)[:7], i),
|
||||
)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if !c.Options.IsSender {
|
||||
go c.receiveData(i)
|
||||
}
|
||||
}
|
||||
c.Step1ChannelSecured = true
|
||||
}
|
||||
@ -306,7 +333,7 @@ func (c *Client) processMessage(payload []byte) (err error) {
|
||||
// c.spinner.Stop()
|
||||
fmt.Print("\r")
|
||||
err = fmt.Errorf("peer error: %s", m.Message)
|
||||
return err
|
||||
return true, err
|
||||
case "fileinfo":
|
||||
var senderInfo SenderInfo
|
||||
err = json.Unmarshal(m.Bytes, &senderInfo)
|
||||
@ -331,7 +358,7 @@ func (c *Client) processMessage(payload []byte) (err error) {
|
||||
Type: "error",
|
||||
Message: "refusing files",
|
||||
})
|
||||
return fmt.Errorf("refused files")
|
||||
return true, fmt.Errorf("refused files")
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "\rReceiving %s (%s) from machine '%s'\n", fname, utils.ByteCountDecimal(totalSize), senderInfo.MachineID)
|
||||
@ -354,7 +381,6 @@ func (c *Client) processMessage(payload []byte) (err error) {
|
||||
log.Debug("sending close-recipient")
|
||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||
Type: "close-recipient",
|
||||
Num: m.Num,
|
||||
})
|
||||
case "close-recipient":
|
||||
c.Step4FileTransfer = false
|
||||
@ -421,6 +447,53 @@ func (c *Client) updateState() (err error) {
|
||||
// start initiating the process to receive a new file
|
||||
log.Debugf("working on file %d", c.FilesToTransferCurrentNum)
|
||||
|
||||
// recipient sets the file
|
||||
pathToFile := path.Join(
|
||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderRemote,
|
||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].Name,
|
||||
)
|
||||
folderForFile, _ := filepath.Split(pathToFile)
|
||||
os.MkdirAll(folderForFile, os.ModePerm)
|
||||
var errOpen error
|
||||
c.CurrentFile, errOpen = os.OpenFile(
|
||||
pathToFile,
|
||||
os.O_WRONLY, 0666)
|
||||
truncate := false
|
||||
if errOpen == nil {
|
||||
stat, _ := c.CurrentFile.Stat()
|
||||
truncate = stat.Size() != c.FilesToTransfer[c.FilesToTransferCurrentNum].Size
|
||||
} else {
|
||||
c.CurrentFile, errOpen = os.Create(pathToFile)
|
||||
if errOpen != nil {
|
||||
errOpen = errors.Wrap(errOpen, "could not create "+pathToFile)
|
||||
log.Error(errOpen)
|
||||
return errOpen
|
||||
}
|
||||
truncate = true
|
||||
}
|
||||
if truncate {
|
||||
err := c.CurrentFile.Truncate(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "could not truncate "+pathToFile)
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// setup the progressbar
|
||||
c.bar = progressbar.NewOptions64(
|
||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].Size,
|
||||
progressbar.OptionOnCompletion(func() {
|
||||
fmt.Println(" ✔️")
|
||||
}),
|
||||
progressbar.OptionSetWidth(8),
|
||||
progressbar.OptionSetDescription(c.FilesToTransfer[c.FilesToTransferCurrentNum].Name),
|
||||
progressbar.OptionSetRenderBlankState(true),
|
||||
progressbar.OptionSetBytes64(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size),
|
||||
progressbar.OptionSetWriter(os.Stderr),
|
||||
progressbar.OptionThrottle(100*time.Millisecond),
|
||||
)
|
||||
|
||||
// recipient requests the file and chunks (if empty, then should receive all chunks)
|
||||
bRequest, _ := json.Marshal(RemoteFileRequest{
|
||||
CurrentFileChunks: c.CurrentFileChunks,
|
||||
@ -434,35 +507,123 @@ func (c *Client) updateState() (err error) {
|
||||
return
|
||||
}
|
||||
c.Step3RecipientRequestFile = true
|
||||
// TODO: receive
|
||||
}
|
||||
if c.Options.IsSender && c.Step3RecipientRequestFile && !c.Step4FileTransfer {
|
||||
log.Debug("start sending data!")
|
||||
// TODO: send
|
||||
c.Step4FileTransfer = true
|
||||
// setup the progressbar
|
||||
c.bar = progressbar.NewOptions64(
|
||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].Size,
|
||||
progressbar.OptionOnCompletion(func() {
|
||||
fmt.Println(" ✔️")
|
||||
}),
|
||||
progressbar.OptionSetWidth(8),
|
||||
progressbar.OptionSetDescription(c.FilesToTransfer[c.FilesToTransferCurrentNum].Name),
|
||||
progressbar.OptionSetRenderBlankState(true),
|
||||
progressbar.OptionSetBytes64(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size),
|
||||
progressbar.OptionSetWriter(os.Stderr),
|
||||
progressbar.OptionThrottle(100*time.Millisecond),
|
||||
)
|
||||
for i := 1; i < len(c.Options.RelayPorts); i++ {
|
||||
go c.sendData(i)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Encode encodes the input in base64
|
||||
// It can optionally zip the input before encoding
|
||||
func Encode(obj interface{}) string {
|
||||
b, err := json.Marshal(obj)
|
||||
func (c *Client) receiveData(i int) {
|
||||
|
||||
for {
|
||||
data, err := c.conn[i].Receive()
|
||||
if err != nil {
|
||||
log.Errorf("%s: %s", i, err.Error())
|
||||
}
|
||||
data, err = c.Key.Decrypt(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data = compress.Decompress(data)
|
||||
|
||||
// get position
|
||||
var position uint64
|
||||
rbuf := bytes.NewReader(data[:8])
|
||||
err = binary.Read(rbuf, binary.LittleEndian, &position)
|
||||
if err != nil {
|
||||
fmt.Println("binary.Read failed:", err)
|
||||
}
|
||||
positionInt64 := int64(position)
|
||||
|
||||
c.mutex.Lock()
|
||||
n, err := c.CurrentFile.WriteAt(data[8:], positionInt64)
|
||||
c.mutex.Unlock()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.bar.Add(n)
|
||||
if c.bar.State().CurrentBytes == float64(c.FilesToTransfer[c.FilesToTransferCurrentNum].Size) {
|
||||
log.Debug("finished receiving!")
|
||||
c.CurrentFile.Close()
|
||||
log.Debug("sending close-sender")
|
||||
err = message.Send(c.conn[0], c.Key, message.Message{
|
||||
Type: "close-sender",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Client) sendData(i int) {
|
||||
pathToFile := path.Join(
|
||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].FolderSource,
|
||||
c.FilesToTransfer[c.FilesToTransferCurrentNum].Name,
|
||||
)
|
||||
log.Debugf("opening %s to read", pathToFile)
|
||||
f, err := os.Open(pathToFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return base64.StdEncoding.EncodeToString(b)
|
||||
}
|
||||
pos := uint64(0)
|
||||
curi := float64(0)
|
||||
for {
|
||||
// Read file
|
||||
data := make([]byte, 1000)
|
||||
n, err := f.Read(data)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Decode decodes the input from base64
|
||||
// It can optionally unzip the input after decoding
|
||||
func Decode(in string, obj interface{}) (err error) {
|
||||
b, err := base64.StdEncoding.DecodeString(in)
|
||||
if err != nil {
|
||||
return
|
||||
if math.Mod(curi, float64(len(c.Options.RelayPorts)-1))+1 == float64(i) {
|
||||
posByte := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(posByte, pos)
|
||||
|
||||
dataToSend, err := c.Key.Encrypt(
|
||||
compress.Compress(
|
||||
append(posByte, data[:n]...),
|
||||
),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = c.conn[i].Send(dataToSend)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.bar.Add(n)
|
||||
}
|
||||
|
||||
curi++
|
||||
pos += uint64(n)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(b, obj)
|
||||
return
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user