mirror of
https://github.com/schollz/croc.git
synced 2024-11-24 16:23:47 +03:00
commit
94a4b23bae
10
README.md
10
README.md
@ -10,7 +10,7 @@
|
||||
|
||||
<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?**
|
||||
|
||||
@ -18,6 +18,12 @@ 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)
|
||||
|
||||
|
||||
**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
|
||||
|
||||
*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
|
||||
|
||||
|
16
connect.go
16
connect.go
@ -221,7 +221,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)
|
||||
}
|
||||
@ -332,7 +332,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: "))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -426,8 +428,13 @@ 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))
|
||||
newFile, err := os.Create(c.File.Name + ".enc." + strconv.Itoa(id))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -486,7 +493,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 {
|
||||
|
40
relay.go
40
relay.go
@ -114,22 +114,27 @@ func (r *Relay) listener(id int) (err error) {
|
||||
}
|
||||
|
||||
func (r *Relay) clientCommuncation(id int, connection net.Conn) {
|
||||
sendMessage("who?", connection)
|
||||
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
|
||||
@ -164,13 +169,18 @@ 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)
|
||||
delete(r.connections.potentialReceivers, key)
|
||||
r.connections.Unlock()
|
||||
logger.Debug("deleted sender and receiver")
|
||||
} else { //receiver connection "r"
|
||||
} else if connectionType == "r" || connectionType == "c" {
|
||||
//receiver
|
||||
if r.connections.IsPotentialReceiverConnected(key) {
|
||||
sendMessage("no", connection)
|
||||
return
|
||||
@ -212,6 +222,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
|
||||
}
|
||||
@ -222,8 +234,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(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)
|
||||
}
|
||||
|
||||
|
8
utils.go
8
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] {
|
||||
|
Loading…
Reference in New Issue
Block a user