diff --git a/README.md b/README.md index 59cfbdb..a4227ef 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,15 @@ You can send with your own code phrase (must be more than 4 characters). croc send --code [code-phrase] [file(s)-or-folder] ``` +### Allow overwriting without prompt + +By default, croc will prompt whether to overwrite a file. You can automatically overwrite files by using the `--overwrite` flag (recipient only). For example, receive a file to automatically overwrite: + +``` +croc --yes --overwrite +``` + + ### Use pipes - stdin and stdout You can pipe to `croc`: @@ -173,6 +182,14 @@ You can use a proxy as your connection to the relay by adding a proxy address wi croc --socks5 "127.0.0.1:9050" send SOMEFILE ``` +### Change encryption curve + +You can choose from several different elliptic curves to use for encryption by using the `--curve` flag. Only the recipient can choose the curve. For example, receive a file using the P-521 curve: + +``` +croc --curve p521 +``` + ### Self-host relay The relay is needed to staple the parallel incoming and outgoing connections. By default, `croc` uses a public relay but you can also run your own relay: diff --git a/go.mod b/go.mod index 5263932..2e02498 100644 --- a/go.mod +++ b/go.mod @@ -1,31 +1,28 @@ module github.com/schollz/croc/v8 - go 1.13 - replace github.com/schollz/pake3 => ../pake3 - require ( - github.com/OneOfOne/xxhash v1.2.5 // indirect - github.com/cespare/xxhash v1.1.0 - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect - github.com/denisbrodbeck/machineid v1.0.1 - github.com/kalafut/imohash v1.0.0 - github.com/kr/pretty v0.1.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/schollz/cli/v2 v2.2.1 - github.com/schollz/logger v1.2.0 - github.com/schollz/mnemonicode v1.0.1 - github.com/schollz/pake/v2 v2.0.7 - github.com/schollz/pake3 v0.0.0-00010101000000-000000000000 - github.com/schollz/peerdiscovery v1.6.3 - github.com/schollz/progressbar/v3 v3.7.6 - github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/stretchr/testify v1.6.1 - github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094 - golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 - golang.org/x/net v0.0.0-20210326220855-61e056675ecf - golang.org/x/sys v0.0.0-20210326220804-49726bf1d181 // indirect - golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 // indirect - golang.org/x/text v0.3.5 // indirect - gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect -) +github.com/OneOfOne/xxhash v1.2.5 // indirect +github.com/cespare/xxhash v1.1.0 +github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect +github.com/denisbrodbeck/machineid v1.0.1 +github.com/kalafut/imohash v1.0.0 +github.com/kr/pretty v0.1.0 // indirect +github.com/russross/blackfriday/v2 v2.1.0 // indirect +github.com/schollz/cli/v2 v2.2.1 +github.com/schollz/logger v1.2.0 +github.com/schollz/mnemonicode v1.0.1 +github.com/schollz/pake/v2 v2.0.7 +github.com/schollz/pake3 v0.0.0-00010101000000-000000000000 +github.com/schollz/peerdiscovery v1.6.3 +github.com/schollz/progressbar/v3 v3.7.6 +github.com/spaolacci/murmur3 v1.1.0 // indirect +github.com/stretchr/testify v1.6.1 +github.com/tscholl2/siec v0.0.0-20191122224205-8da93652b094 +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 +golang.org/x/net v0.0.0-20210326220855-61e056675ecf +golang.org/x/sys v0.0.0-20210326220804-49726bf1d181 // indirect +golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 // indirect +golang.org/x/text v0.3.5 // indirect +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect +) \ No newline at end of file diff --git a/src/cli/cli.go b/src/cli/cli.go index b3fb14d..7978f76 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -20,6 +20,7 @@ import ( "github.com/schollz/croc/v8/src/tcp" "github.com/schollz/croc/v8/src/utils" log "github.com/schollz/logger" + pake "github.com/schollz/pake3" ) // Version specifies the version @@ -87,6 +88,7 @@ func Run() (err error) { &cli.BoolFlag{Name: "local", Usage: "force to use only local connections"}, &cli.BoolFlag{Name: "ignore-stdin", Usage: "ignore piped stdin"}, &cli.BoolFlag{Name: "overwrite", Usage: "do not prompt to overwrite"}, + &cli.StringFlag{Name: "curve", Value: "siec", Usage: "choose an encryption curve (" + strings.Join(pake.AvailableCurves(), ", ") + ")"}, &cli.StringFlag{Name: "ip", Value: "", Usage: "set sender ip if known e.g. 10.0.0.1:9009, [::1]:9009"}, &cli.StringFlag{Name: "relay", Value: models.DEFAULT_RELAY, Usage: "address of the relay", EnvVars: []string{"CROC_RELAY"}}, &cli.StringFlag{Name: "relay6", Value: models.DEFAULT_RELAY6, Usage: "ipv6 address of the relay", EnvVars: []string{"CROC_RELAY6"}}, @@ -195,6 +197,7 @@ func send(c *cli.Context) (err error) { SendingText: c.String("text") != "", NoCompress: c.Bool("no-compress"), Overwrite: c.Bool("overwrite"), + Curve: c.String("curve"), } if crocOptions.RelayAddress != models.DEFAULT_RELAY { crocOptions.RelayAddress6 = "" @@ -391,6 +394,7 @@ func receive(c *cli.Context) (err error) { OnlyLocal: c.Bool("local"), IP: c.String("ip"), Overwrite: c.Bool("overwrite"), + Curve: c.String("curve"), } if crocOptions.RelayAddress != models.DEFAULT_RELAY { crocOptions.RelayAddress6 = "" diff --git a/src/croc/croc.go b/src/croc/croc.go index 697597d..fd078ce 100644 --- a/src/croc/croc.go +++ b/src/croc/croc.go @@ -66,6 +66,7 @@ type Options struct { NoCompress bool IP string Overwrite bool + Curve string } // Client holds the state of the croc transfer @@ -165,11 +166,9 @@ func New(ops Options) (c *Client, err error) { c.conn = make([]*comm.Comm, 16) - // initialize pake - if c.Options.IsSender { - c.Pake, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, "siec") - } else { - c.Pake, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 0, "siec") + // initialize pake for recipient + if !c.Options.IsSender { + c.Pake, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 0, c.Options.Curve) } if err != nil { return @@ -694,8 +693,9 @@ func (c *Client) transfer(options TransferOptions) (err error) { log.Debug("ready") if !c.Options.IsSender && !c.Step1ChannelSecured { err = message.Send(c.conn[0], c.Key, message.Message{ - Type: "pake", - Bytes: c.Pake.Bytes(), + Type: "pake", + Bytes: c.Pake.Bytes(), + Bytes2: []byte(c.Options.Curve), }) if err != nil { return @@ -825,12 +825,23 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error func (c *Client) processMessagePake(m message.Message) (err error) { log.Debug("received pake payload") - err = c.Pake.Update(m.Bytes) - if err != nil { - return - } var salt []byte if c.Options.IsSender { + // initialize curve based on the recipient's choice + log.Debugf("using curve %s", string(m.Bytes2)) + c.Pake, err = pake.InitCurve([]byte(c.Options.SharedSecret[5:]), 1, string(m.Bytes2)) + if err != nil { + log.Error(err) + return + } + + // update the pake + err = c.Pake.Update(m.Bytes) + if err != nil { + return + } + + // generate salt and send it back to recipient log.Debug("generating salt") salt = make([]byte, 8) if _, rerr := rand.Read(salt); err != nil { @@ -844,6 +855,10 @@ func (c *Client) processMessagePake(m message.Message) (err error) { Bytes2: salt, }) } else { + err = c.Pake.Update(m.Bytes) + if err != nil { + return + } salt = m.Bytes2 } // generate key