From c42302d3de61b653a134be87149e8fc4892b59dd Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 14:29:48 -0600 Subject: [PATCH 01/14] More errors --- connect.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/connect.go b/connect.go index 4d910fa0..0740d6b0 100644 --- a/connect.go +++ b/connect.go @@ -292,7 +292,9 @@ func (c *Connection) runClient() error { if id == 0 { fmt.Printf("\n\nReceiving (<-%s)..\n", sendersAddress) } - c.receiveFile(id, connection) + if err := c.receiveFile(id, connection); err != nil { + log.Error(errors.Wrap(err, "Problem receiving the file: ")) + } } } } From 0f5b52ff3565ec1c8075f1723ceadbb04de36a74 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 14:34:59 -0600 Subject: [PATCH 02/14] Better error handling --- utils.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utils.go b/utils.go index b15a4b90..459bc283 100644 --- a/utils.go +++ b/utils.go @@ -7,23 +7,25 @@ import ( "math" "os" "strconv" + + "github.com/pkg/errors" ) func CatFiles(files []string, outfile string, remove ...bool) error { finished, err := os.Create(outfile) defer finished.Close() if err != nil { - return err + return errors.Wrap(err, "CatFiles create: ") } for i := range files { fh, err := os.Open(files[i]) if err != nil { - return err + return errors.Wrap(err, "CatFiles open "+files[i]+": ") } _, err = io.Copy(finished, fh) if err != nil { - return err + return errors.Wrap(err, "CatFiles copy: ") } fh.Close() if len(remove) > 0 && remove[0] { From 79c81a3c5d835d026193bc4e86d9e564a066dc8a Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 14:38:27 -0600 Subject: [PATCH 03/14] Better error handling --- connect.go | 1 + 1 file changed, 1 insertion(+) diff --git a/connect.go b/connect.go index 0740d6b0..62144e61 100644 --- a/connect.go +++ b/connect.go @@ -389,6 +389,7 @@ func (c *Connection) receiveFile(id int, connection net.Conn) error { logger.Debugf("chunk size: %d", chunkSize) os.Remove(c.File.Name + ".enc." + strconv.Itoa(id)) + log.Debug("Making " + c.File.Name + ".enc." + strconv.Itoa(id)) newFile, err := os.Create(c.File.Name + ".enc." + strconv.Itoa(id)) if err != nil { panic(err) From 0a834599c4ee8c1e86a03c894ba18f45115c3b86 Mon Sep 17 00:00:00 2001 From: Zack Date: Sat, 21 Oct 2017 14:55:49 -0600 Subject: [PATCH 04/14] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 66a5dbcd..db305f91 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ This is more or less (but mostly *less*) a Golang port of [@warner's](https://gi # Example +![send](https://user-images.githubusercontent.com/6550035/31855780-35140b88-b66f-11e7-86cb-c23e2cb4fa86.gif) +![receive](https://user-images.githubusercontent.com/6550035/31855781-3632b384-b66f-11e7-8b29-9ba61ec374d4.gif) + + **Sender:** ``` From 8ecd2c30b891f8490fc36877f71a8cad83b77dcc Mon Sep 17 00:00:00 2001 From: Zack Date: Sat, 21 Oct 2017 14:58:57 -0600 Subject: [PATCH 05/14] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index db305f91..114d354f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ This is more or less (but mostly *less*) a Golang port of [@warner's](https://gi # Example +_These two gifs should run in sync if you force-reload (Ctl+F5)_ + ![send](https://user-images.githubusercontent.com/6550035/31855780-35140b88-b66f-11e7-86cb-c23e2cb4fa86.gif) ![receive](https://user-images.githubusercontent.com/6550035/31855781-3632b384-b66f-11e7-8b29-9ba61ec374d4.gif) From 54a5a8896dd7634f1cb9288d387bd5609e91caff Mon Sep 17 00:00:00 2001 From: Zack Date: Sat, 21 Oct 2017 15:22:32 -0600 Subject: [PATCH 06/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 114d354f..bbf67a34 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Or, if you are like my good friend Jessie and "*just can't even*" with programmi ## Run your own relay -*croc* relies on a TCP relay to staple the parallel incoming and outgoing connections. The relay temporarily stores connection information and the encrypted meta information. The default uses my server, `cowyo.com`, which has no guarantees except that I guarantee to turn if off as soon as it gets abused. +*croc* relies on a TCP relay to staple the parallel incoming and outgoing connections. The relay temporarily stores connection information and the encrypted meta information. The default uses a public relay at, `cowyo.com`, which has no guarantees except that I guarantee to turn if off as soon as it gets abused ([click here to check the current status of the public relay](https://stats.uptimerobot.com/lOwJYIgRm)). I recommend you run your own relay, it is very easy. On your server, `your-server.com`, just run From 9ab46073e99a111b640584634d396a0538946d41 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 15:29:35 -0600 Subject: [PATCH 07/14] disallow connections without the proper messaging --- relay.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/relay.go b/relay.go index 12921e3b..6dad46d7 100644 --- a/relay.go +++ b/relay.go @@ -117,6 +117,10 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { sendMessage("who?", connection) m := strings.Split(receiveMessage(connection), ".") + if len(m) != 3 { + sendMessage("not enough information", connection) + return + } connectionType, codePhrase, metaData := m[0], m[1], m[2] key := codePhrase + "-" + strconv.Itoa(id) logger := log.WithFields(log.Fields{ From dc23087dbc23fd5fda565ea2bc737e4e64acd7df Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 15:32:00 -0600 Subject: [PATCH 08/14] Oops --- relay.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/relay.go b/relay.go index 6dad46d7..d64ebd5b 100644 --- a/relay.go +++ b/relay.go @@ -117,7 +117,7 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { sendMessage("who?", connection) m := strings.Split(receiveMessage(connection), ".") - if len(m) != 3 { + if len(m) < 3 { sendMessage("not enough information", connection) return } From ac31f61a50fe12eb3ddcf2e555333230761f9285 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 15:35:58 -0600 Subject: [PATCH 09/14] Add bitly link for public server --- connect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/connect.go b/connect.go index 62144e61..b5d5c556 100644 --- a/connect.go +++ b/connect.go @@ -181,7 +181,7 @@ func (c *Connection) runClient() error { connection, err := net.Dial("tcp", c.Server+":"+port) if err != nil { if c.Server == "cowyo.com" { - fmt.Println("\nThe public server is down. Please tweet the webmaster: @yakczar") + fmt.Println("\nCheck http://bit.ly/croc-relay to see if the public server is down or contact the webmaster: @yakczar") } else { fmt.Printf("\nCould not connect to relay %s\n", c.Server) } From cb3f94880db51d2a8dfbc266343f580223ca4f77 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 15:50:32 -0600 Subject: [PATCH 10/14] Relay is more transparent about unknown connections --- relay.go | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/relay.go b/relay.go index d64ebd5b..40c28a26 100644 --- a/relay.go +++ b/relay.go @@ -114,26 +114,29 @@ func (r *Relay) listener(id int) (err error) { } func (r *Relay) clientCommuncation(id int, connection net.Conn) { - sendMessage("who?", connection) + defer connection.Close() + logger := log.WithFields(log.Fields{ + "id": id, + "ip": connection.RemoteAddr().String(), + }) + + sendMessage("who?", connection) m := strings.Split(receiveMessage(connection), ".") if len(m) < 3 { + logger.Debug("exiting, not enough information") sendMessage("not enough information", connection) return } connectionType, codePhrase, metaData := m[0], m[1], m[2] key := codePhrase + "-" + strconv.Itoa(id) - logger := log.WithFields(log.Fields{ - "id": id, - "codePhrase": codePhrase, - }) if connectionType == "s" { // sender connection if r.connections.IsSenderConnected(key) { sendMessage("no", connection) return } - logger.Debug("got sender") + r.connections.Lock() r.connections.metadata[key] = metaData r.connections.sender[key] = connection @@ -174,7 +177,7 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { delete(r.connections.potentialReceivers, key) r.connections.Unlock() logger.Debug("deleted sender and receiver") - } else { //receiver connection "r" + } else if connectionType == "r" { //receiver connection "r" if r.connections.IsPotentialReceiverConnected(key) { sendMessage("no", connection) return @@ -216,6 +219,8 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { r.connections.receiver[key] = connection r.connections.Unlock() } + } else { + logger.Debugf("Got unknown protocol: '%s'", connectionType) } return } @@ -226,8 +231,20 @@ func sendMessage(message string, connection net.Conn) { } func receiveMessage(connection net.Conn) string { + logger := log.WithFields(log.Fields{ + "func": "receiveMessage", + "ip": connection.RemoteAddr().String(), + }) messageByte := make([]byte, BUFFERSIZE) - connection.Read(messageByte) + err := connection.SetDeadline(time.Now().Add(30 * time.Second)) + if err != nil { + logger.Warn(err) + } + _, err = connection.Read(messageByte) + if err != nil { + logger.Warn("read deadline, no response") + return "" + } return strings.Replace(string(messageByte), ":", "", -1) } From 3bb5f43c072817eb1b0e92231e7900e65135c334 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 15:54:51 -0600 Subject: [PATCH 11/14] Fix bug in relay --- relay.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/relay.go b/relay.go index 40c28a26..c3b6e00d 100644 --- a/relay.go +++ b/relay.go @@ -177,7 +177,8 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { delete(r.connections.potentialReceivers, key) r.connections.Unlock() logger.Debug("deleted sender and receiver") - } else if connectionType == "r" { //receiver connection "r" + } else if connectionType == "r" || connectionType == "c" { + //receiver if r.connections.IsPotentialReceiverConnected(key) { sendMessage("no", connection) return @@ -236,7 +237,7 @@ func receiveMessage(connection net.Conn) string { "ip": connection.RemoteAddr().String(), }) messageByte := make([]byte, BUFFERSIZE) - err := connection.SetDeadline(time.Now().Add(30 * time.Second)) + err := connection.SetDeadline(time.Now().Add(60 * time.Minute)) if err != nil { logger.Warn(err) } From 23e19b009ca2e610ba88fb73aa78427891bd9c77 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 16:07:44 -0600 Subject: [PATCH 12/14] Broken --- connect.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/connect.go b/connect.go index b5d5c556..fd913fe3 100644 --- a/connect.go +++ b/connect.go @@ -387,6 +387,10 @@ func (c *Connection) receiveFile(id int, connection net.Conn) error { fileSizeInt, _ := strconv.Atoi(fileDataString) chunkSize := int64(fileSizeInt) logger.Debugf("chunk size: %d", chunkSize) + if chunkSize == 0 { + logger.Debug(fileSizeBuffer) + return errors.New("chunk size is empty!") + } os.Remove(c.File.Name + ".enc." + strconv.Itoa(id)) log.Debug("Making " + c.File.Name + ".enc." + strconv.Itoa(id)) @@ -448,7 +452,10 @@ func (c *Connection) sendFile(id int, connection net.Conn) error { return err } logger.Debugf("sending chunk size: %d", fi.Size()) - connection.Write([]byte(fillString(strconv.FormatInt(int64(fi.Size()), 10), 10))) + _, err = connection.Write([]byte(fillString(strconv.FormatInt(int64(fi.Size()), 10), 10))) + if err != nil { + return errors.Wrap(err, "Problem sending chunk data: ") + } // show the progress if !c.Debug { From 0ee7f75a221e26da298a7862059ee8cf45e0acf2 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 21 Oct 2017 16:19:34 -0600 Subject: [PATCH 13/14] Need to close connections correctly --- relay.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/relay.go b/relay.go index c3b6e00d..2ba0a20d 100644 --- a/relay.go +++ b/relay.go @@ -114,8 +114,6 @@ func (r *Relay) listener(id int) (err error) { } func (r *Relay) clientCommuncation(id int, connection net.Conn) { - defer connection.Close() - logger := log.WithFields(log.Fields{ "id": id, "ip": connection.RemoteAddr().String(), @@ -171,6 +169,10 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { Pipe(con1, con2) logger.Debug("done piping") r.connections.Lock() + // close connections + r.connections.sender[key].Close() + r.connections.receiver[key].Close() + // delete connctions delete(r.connections.sender, key) delete(r.connections.receiver, key) delete(r.connections.metadata, key) From 8145d61e38e73abc924b7d78ca209602ac299188 Mon Sep 17 00:00:00 2001 From: Zack Date: Sat, 21 Oct 2017 16:54:18 -0600 Subject: [PATCH 14/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bbf67a34..35eeede6 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

Secure transfer of stuff from one side of the internet to the other.

-This is more or less (but mostly *less*) a Golang port of [@warner's](https://github.com/warner) [*magic-wormhole*](https://github.com/warner/magic-wormhole) which allows you to directly transfer files between computers. I wrote this because I wanted to send my friend Jessie a file using *magic-wormhole*. However, Jessie doesn't like the idea of putting Python on her computer because it is a giant snake. So, nominally, this is a version of *magic-wormhole* without the dependencies that you can just double-click on your computer, even if you use Windows. +This is more or less (but mostly *less*) a Golang port of [@warner's](https://github.com/warner) [*magic-wormhole*](https://github.com/warner/magic-wormhole) which allows you to directly transfer files between computers. I wrote this because I wanted to send my friend Jessie a file using *magic-wormhole*. However, when I told Jessie how to install the dependencies for *magic-wormhole* she made this face: :sob:. So, nominally, *croc* does the same thing (file transfer directly between computers) without dependencies so you can just double-click on your computer, even if you use Windows. **Don't we have enough open-source peer-to-peer file-transfer utilities?**