0
0
Fork 0
mirror of https://github.com/schollz/croc.git synced 2025-10-11 21:30:16 +02:00

require mutual consent

This commit is contained in:
Zack Scholl 2018-06-23 10:57:25 -07:00
parent 51a87f1110
commit 6e69b2760e
2 changed files with 100 additions and 25 deletions

View file

@ -144,7 +144,7 @@ func NewConnection(config *AppConfig) (*Connection, error) {
if c.Debug { if c.Debug {
SetLogLevel("debug") SetLogLevel("debug")
} else { } else {
SetLogLevel("warn") SetLogLevel("error")
} }
return c, nil return c, nil
@ -296,6 +296,8 @@ func (c *Connection) runClient(serverName string) error {
responses.Lock() responses.Lock()
responses.startTime = time.Now() responses.startTime = time.Now()
responses.Unlock() responses.Unlock()
var okToContinue bool
fileTransfered := false
for id := 0; id < c.NumberOfConnections; id++ { for id := 0; id < c.NumberOfConnections; id++ {
go func(id int) { go func(id int) {
defer wg.Done() defer wg.Done()
@ -366,7 +368,36 @@ func (c *Connection) runClient(serverName string) error {
log.Debugf("[%d] got ok from relay: %s", id, message) log.Debugf("[%d] got ok from relay: %s", id, message)
publicKeyRecipient := receiveMessage(connection) publicKeyRecipient := receiveMessage(connection)
// check if okay again // check if okay again
sendMessage("okay with sender", connection) if id == 0 {
fmt.Fprintf(os.Stderr, "to %s\n", publicKeyRecipient)
getOK := "y"
if !c.Yes {
getOK = getInput("ok? (y/n): ")
}
responses.Lock()
responses.gotOK = true
responses.Unlock()
if getOK == "y" {
okToContinue = true
} else {
okToContinue = false
}
}
for {
responses.RLock()
ok := responses.gotOK
responses.RUnlock()
if ok {
break
}
time.Sleep(10 * time.Millisecond)
}
if okToContinue {
sendMessage("ok", connection)
} else {
sendMessage("no", connection)
return
}
if id == 0 { if id == 0 {
passphraseString := RandStringBytesMaskImprSrc(20) passphraseString := RandStringBytesMaskImprSrc(20)
log.Debugf("passphrase: [%s]", passphraseString) log.Debugf("passphrase: [%s]", passphraseString)
@ -424,7 +455,9 @@ func (c *Connection) runClient(serverName string) error {
c.bar.Reset() c.bar.Reset()
} }
if err := c.sendFile(id, connection); err != nil { if err := c.sendFile(id, connection); err != nil {
log.Error(err) log.Warn(err)
} else {
fileTransfered = true
} }
} }
} else { // this is a receiver } else { // this is a receiver
@ -523,11 +556,21 @@ func (c *Connection) runClient(serverName string) error {
sendMessage("ok", connection) sendMessage("ok", connection)
encryptedPassword := receiveMessage(connection) encryptedPassword := receiveMessage(connection)
log.Debugf("[%d] got encrypted passphrase: %s", id, encryptedPassword) log.Debugf("[%d] got encrypted passphrase: %s", id, encryptedPassword)
if encryptedPassword == "" {
return
}
encryptedPasswordBytes, err := base64.StdEncoding.DecodeString(encryptedPassword) encryptedPasswordBytes, err := base64.StdEncoding.DecodeString(encryptedPassword)
if err != nil { if err != nil {
panic(err) panic(err)
} }
if publicKeySender == "" {
return
}
decryptedPassphrase, err := c.keypair.Decrypt(encryptedPasswordBytes, publicKeySender) decryptedPassphrase, err := c.keypair.Decrypt(encryptedPasswordBytes, publicKeySender)
if err != nil {
log.Warn(err)
return
}
c.encryptedPassword = string(decryptedPassphrase) c.encryptedPassword = string(decryptedPassphrase)
log.Debugf("decrypted password to: %s", c.encryptedPassword) log.Debugf("decrypted password to: %s", c.encryptedPassword)
if err != nil { if err != nil {
@ -550,6 +593,8 @@ func (c *Connection) runClient(serverName string) error {
} }
if err := c.receiveFile(id, connection); err != nil { if err := c.receiveFile(id, connection); err != nil {
log.Debug(errors.Wrap(err, "no file to recieve")) log.Debug(errors.Wrap(err, "no file to recieve"))
} else {
fileTransfered = true
} }
} }
} }
@ -567,7 +612,9 @@ func (c *Connection) runClient(serverName string) error {
timeSinceStart := time.Since(responses.startTime).Nanoseconds() timeSinceStart := time.Since(responses.startTime).Nanoseconds()
if c.IsSender { if !fileTransfered {
fmt.Fprintf(os.Stderr, "\nNo mutual consent")
} else if c.IsSender {
if responses.gotTimeout { if responses.gotTimeout {
fmt.Println("Timeout waiting for receiver") fmt.Println("Timeout waiting for receiver")
return nil return nil
@ -576,7 +623,7 @@ func (c *Connection) runClient(serverName string) error {
if c.File.IsDir { if c.File.IsDir {
fileOrFolder = "Folder" fileOrFolder = "Folder"
} }
fmt.Printf("\n%s sent", fileOrFolder) fmt.Fprintf(os.Stderr, "\n%s sent", fileOrFolder)
} else { // Is a Receiver } else { // Is a Receiver
if responses.notPresent { if responses.notPresent {
fmt.Println("Either code is incorrect or sender is not ready. Use -wait to wait until sender connects.") fmt.Println("Either code is incorrect or sender is not ready. Use -wait to wait until sender connects.")
@ -777,7 +824,7 @@ func (c *Connection) sendFile(id int, connection net.Conn) error {
c.bar.Add(int(written)) c.bar.Add(int(written))
} }
if errWrite != nil { if errWrite != nil {
log.Error(errWrite) return errWrite
} }
if err == io.EOF { if err == io.EOF {
//End of file reached, break out of for loop //End of file reached, break out of for loop

View file

@ -21,6 +21,7 @@ type connectionMap struct {
potentialReceivers map[string]struct{} potentialReceivers map[string]struct{}
rpublicKey map[string]string rpublicKey map[string]string
spublicKey map[string]string spublicKey map[string]string
sconsent map[string]string
passphrase map[string]string passphrase map[string]string
receiverReady map[string]bool receiverReady map[string]bool
sync.RWMutex sync.RWMutex
@ -71,6 +72,7 @@ func (r *Relay) Run() {
r.connections.spublicKey = make(map[string]string) r.connections.spublicKey = make(map[string]string)
r.connections.rpublicKey = make(map[string]string) r.connections.rpublicKey = make(map[string]string)
r.connections.passphrase = make(map[string]string) r.connections.passphrase = make(map[string]string)
r.connections.sconsent = make(map[string]string)
r.connections.potentialReceivers = make(map[string]struct{}) r.connections.potentialReceivers = make(map[string]struct{})
r.connections.receiverReady = make(map[string]bool) r.connections.receiverReady = make(map[string]bool)
r.connections.Unlock() r.connections.Unlock()
@ -139,6 +141,23 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
switch connectionType { switch connectionType {
case "s": // sender connection case "s": // sender connection
defer func() {
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)
delete(r.connections.spublicKey, key)
delete(r.connections.rpublicKey, key)
delete(r.connections.receiverReady, key)
delete(r.connections.passphrase, key)
r.connections.Unlock()
logger.Debug("deleted sender and receiver")
}()
if r.connections.IsSenderConnected(key) { if r.connections.IsSenderConnected(key) {
sendMessage("no", connection) sendMessage("no", connection)
return return
@ -177,8 +196,14 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
sendMessage(receiversPublicKey, connection) sendMessage(receiversPublicKey, connection)
// TODO ASK FOR OKAY HERE TOO // TODO ASK FOR OKAY HERE TOO
isokay := receiveMessage(connection) sconsent := receiveMessage(connection)
logger.Debug(isokay) r.connections.Lock()
r.connections.sconsent[key] = sconsent
r.connections.Unlock()
logger.Debugf("got consent: %+v", sconsent)
if sconsent != "ok" {
return
}
logger.Debug("waiting for encrypted passphrase") logger.Debug("waiting for encrypted passphrase")
encryptedPassphrase := receiveMessage(connection) encryptedPassphrase := receiveMessage(connection)
@ -205,21 +230,6 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
logger.Debug("piping connections") logger.Debug("piping connections")
Pipe(con1, con2) Pipe(con1, con2)
logger.Debug("done piping") 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)
delete(r.connections.spublicKey, key)
delete(r.connections.rpublicKey, key)
delete(r.connections.receiverReady, key)
delete(r.connections.passphrase, key)
r.connections.Unlock()
logger.Debug("deleted sender and receiver")
case "r", "c": // receiver case "r", "c": // receiver
if r.connections.IsPotentialReceiverConnected(key) { if r.connections.IsPotentialReceiverConnected(key) {
sendMessage("no", connection) sendMessage("no", connection)
@ -267,6 +277,24 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) {
sendMessage(sendersPublicKey, connection) sendMessage(sendersPublicKey, connection)
r.connections.RUnlock() r.connections.RUnlock()
// check for senders consent
sendersConsent := ""
for {
r.connections.RLock()
if _, ok := r.connections.sconsent[key]; ok {
sendersConsent = r.connections.sconsent[key]
logger.Debugf("got sender passphrase: %s", sendersConsent)
}
r.connections.RUnlock()
if sendersConsent != "" {
break
}
}
if sendersConsent != "ok" {
// TODO: delete everything
return
}
// now get passphrase // now get passphrase
sendersPassphrase := "" sendersPassphrase := ""
for { for {
@ -337,8 +365,8 @@ func receiveMessage(connection net.Conn) string {
} }
_, err = connection.Read(messageByte) _, err = connection.Read(messageByte)
if err != nil { if err != nil {
logger.Warn(err) logger.Debug(err)
logger.Warn("no response") logger.Debug("no response")
return "" return ""
} }
return strings.TrimRight(string(messageByte), ":") return strings.TrimRight(string(messageByte), ":")