diff --git a/src/cli/cli.go b/src/cli/cli.go index dee007f..9f8a4a9 100644 --- a/src/cli/cli.go +++ b/src/cli/cli.go @@ -87,6 +87,7 @@ func Run() { } app.Before = func(c *cli.Context) error { cr = croc.Init(c.GlobalBool("debug")) + cr.Version = Version cr.AllowLocalDiscovery = true cr.Address = c.GlobalString("addr") cr.AddressTCPPorts = strings.Split(c.GlobalString("addr-tcp"), ",") diff --git a/src/croc/croc.go b/src/croc/croc.go index 11442c4..fd11e20 100644 --- a/src/croc/croc.go +++ b/src/croc/croc.go @@ -17,6 +17,8 @@ func init() { // Croc options type Croc struct { + // Version is the version of croc + Version string // Options for all Debug bool // ShowText will display text on the stderr diff --git a/src/croc/sender.go b/src/croc/sender.go index 7e67111..f4b898c 100644 --- a/src/croc/sender.go +++ b/src/croc/sender.go @@ -26,7 +26,6 @@ import ( "github.com/schollz/pake" progressbar "github.com/schollz/progressbar/v2" "github.com/schollz/spinner" - "github.com/tscholl2/siec" ) // Send is the async call to send data @@ -37,8 +36,11 @@ func (cr *Croc) startSender(forceSend int, serverAddress string, tcpPorts []stri if err != nil { if !strings.HasPrefix(err.Error(), "websocket: close 100") { fmt.Fprintf(os.Stderr, "\n"+err.Error()) + err = errors.Wrap(err, "error in sender:") + c.WriteMessage(websocket.TextMessage, []byte(err.Error())) + time.Sleep(50 * time.Millisecond) + cr.StateString = err.Error() } - cr.StateString = err.Error() } done <- struct{}{} @@ -91,12 +93,10 @@ func (cr *Croc) send(forceSend int, serverAddress string, tcpPorts []string, isL spin.Writer = os.Stderr defer spin.Stop() - // pick an elliptic curve - curve := siec.SIEC255() // both parties should have a weak key pw := []byte(codephrase) // initialize sender P ("0" indicates sender) - P, err := pake.Init(pw, 0, curve, 1*time.Millisecond) + P, err := pake.InitCurve(pw, 0, cr.CurveType, 1*time.Millisecond) if err != nil { return } @@ -113,6 +113,9 @@ func (cr *Croc) send(forceSend int, serverAddress string, tcpPorts []string, isL if messageType == websocket.TextMessage && bytes.Equal(message, []byte("interrupt")) { return errors.New("\rinterrupted by other party") } + if messageType == websocket.TextMessage && bytes.HasPrefix(message, []byte("err")) { + return errors.New("\r" + string(message)) + } log.Debugf("got %d: %s", messageType, message) switch step { case 0: @@ -123,11 +126,24 @@ func (cr *Croc) send(forceSend int, serverAddress string, tcpPorts []string, isL } else { ip, _ = utils.PublicIP() } - // send my IP address - c.WriteMessage(websocket.BinaryMessage, []byte(ip)) + + initialData := models.Initial{ + CurveType: cr.CurveType, + IPAddress: ip, + VersionString: cr.Version, // version should match + } + bInitialData, _ := json.Marshal(initialData) + // send the initial data + c.WriteMessage(websocket.BinaryMessage, bInitialData) case 1: - // first receive the IP address from the sender - cr.OtherIP = string(message) + // first receive the initial data from the recipient + var initialData models.Initial + err = json.Unmarshal(message, &initialData) + if err != nil { + err = errors.Wrap(err, "incompatible versions of croc") + return + } + cr.OtherIP = initialData.IPAddress log.Debugf("recipient IP: %s", cr.OtherIP) go func() {