1
0
mirror of https://github.com/schollz/croc.git synced 2024-11-28 09:35:14 +03:00

Merge pull request #1 from schollz/master

sync up
This commit is contained in:
Camille 2017-10-22 11:45:43 +02:00 committed by GitHub
commit 94a4b23bae
4 changed files with 58 additions and 16 deletions

View File

@ -10,7 +10,7 @@
<p align="center">Secure transfer of stuff from one side of the internet to the other.</p> <p align="center">Secure transfer of stuff from one side of the internet to the other.</p>
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?** **Don't we have enough open-source peer-to-peer file-transfer utilities?**
@ -18,6 +18,12 @@ This is more or less (but mostly *less*) a Golang port of [@warner's](https://gi
# Example # 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)
**Sender:** **Sender:**
``` ```
@ -61,7 +67,7 @@ Or, if you are like my good friend Jessie and "*just can't even*" with programmi
## Run your own relay ## 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 I recommend you run your own relay, it is very easy. On your server, `your-server.com`, just run

View File

@ -221,7 +221,7 @@ func (c *Connection) runClient() error {
connection, err := net.Dial("tcp", c.Server+":"+port) connection, err := net.Dial("tcp", c.Server+":"+port)
if err != nil { if err != nil {
if c.Server == "cowyo.com" { 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 { } else {
fmt.Printf("\nCould not connect to relay %s\n", c.Server) fmt.Printf("\nCould not connect to relay %s\n", c.Server)
} }
@ -332,7 +332,9 @@ func (c *Connection) runClient() error {
if id == 0 { if id == 0 {
fmt.Printf("\n\nReceiving (<-%s)..\n", sendersAddress) 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: "))
}
} }
} }
} }
@ -426,8 +428,13 @@ func (c *Connection) receiveFile(id int, connection net.Conn) error {
fileSizeInt, _ := strconv.Atoi(fileDataString) fileSizeInt, _ := strconv.Atoi(fileDataString)
chunkSize := int64(fileSizeInt) chunkSize := int64(fileSizeInt)
logger.Debugf("chunk size: %d", chunkSize) 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)) 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)) newFile, err := os.Create(c.File.Name + ".enc." + strconv.Itoa(id))
if err != nil { if err != nil {
panic(err) panic(err)
@ -486,7 +493,10 @@ func (c *Connection) sendFile(id int, connection net.Conn) error {
return err return err
} }
logger.Debugf("sending chunk size: %d", fi.Size()) 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 // show the progress
if !c.Debug { if !c.Debug {

View File

@ -114,22 +114,27 @@ func (r *Relay) listener(id int) (err error) {
} }
func (r *Relay) clientCommuncation(id int, connection net.Conn) { func (r *Relay) clientCommuncation(id int, connection net.Conn) {
sendMessage("who?", connection)
m := strings.Split(receiveMessage(connection), ".")
connectionType, codePhrase, metaData := m[0], m[1], m[2]
key := codePhrase + "-" + strconv.Itoa(id)
logger := log.WithFields(log.Fields{ logger := log.WithFields(log.Fields{
"id": id, "id": id,
"codePhrase": codePhrase, "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)
if connectionType == "s" { // sender connection if connectionType == "s" { // sender connection
if r.connections.IsSenderConnected(key) { if r.connections.IsSenderConnected(key) {
sendMessage("no", connection) sendMessage("no", connection)
return return
} }
logger.Debug("got sender")
r.connections.Lock() r.connections.Lock()
r.connections.metadata[key] = metaData r.connections.metadata[key] = metaData
r.connections.sender[key] = connection r.connections.sender[key] = connection
@ -164,13 +169,18 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
Pipe(con1, con2) Pipe(con1, con2)
logger.Debug("done piping") logger.Debug("done piping")
r.connections.Lock() 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.sender, key)
delete(r.connections.receiver, key) delete(r.connections.receiver, key)
delete(r.connections.metadata, key) delete(r.connections.metadata, key)
delete(r.connections.potentialReceivers, key) delete(r.connections.potentialReceivers, key)
r.connections.Unlock() r.connections.Unlock()
logger.Debug("deleted sender and receiver") logger.Debug("deleted sender and receiver")
} else { //receiver connection "r" } else if connectionType == "r" || connectionType == "c" {
//receiver
if r.connections.IsPotentialReceiverConnected(key) { if r.connections.IsPotentialReceiverConnected(key) {
sendMessage("no", connection) sendMessage("no", connection)
return return
@ -212,6 +222,8 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
r.connections.receiver[key] = connection r.connections.receiver[key] = connection
r.connections.Unlock() r.connections.Unlock()
} }
} else {
logger.Debugf("Got unknown protocol: '%s'", connectionType)
} }
return return
} }
@ -222,8 +234,20 @@ func sendMessage(message string, connection net.Conn) {
} }
func receiveMessage(connection net.Conn) string { func receiveMessage(connection net.Conn) string {
logger := log.WithFields(log.Fields{
"func": "receiveMessage",
"ip": connection.RemoteAddr().String(),
})
messageByte := make([]byte, BUFFERSIZE) messageByte := make([]byte, BUFFERSIZE)
connection.Read(messageByte) err := connection.SetDeadline(time.Now().Add(60 * time.Minute))
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) return strings.Replace(string(messageByte), ":", "", -1)
} }

View File

@ -7,23 +7,25 @@ import (
"math" "math"
"os" "os"
"strconv" "strconv"
"github.com/pkg/errors"
) )
func CatFiles(files []string, outfile string, remove ...bool) error { func CatFiles(files []string, outfile string, remove ...bool) error {
finished, err := os.Create(outfile) finished, err := os.Create(outfile)
defer finished.Close() defer finished.Close()
if err != nil { if err != nil {
return err return errors.Wrap(err, "CatFiles create: ")
} }
for i := range files { for i := range files {
fh, err := os.Open(files[i]) fh, err := os.Open(files[i])
if err != nil { if err != nil {
return err return errors.Wrap(err, "CatFiles open "+files[i]+": ")
} }
_, err = io.Copy(finished, fh) _, err = io.Copy(finished, fh)
if err != nil { if err != nil {
return err return errors.Wrap(err, "CatFiles copy: ")
} }
fh.Close() fh.Close()
if len(remove) > 0 && remove[0] { if len(remove) > 0 && remove[0] {