From 6e69b2760ee2d4d8a8e129cf6306d31f6fa11660 Mon Sep 17 00:00:00 2001 From: Zack Scholl Date: Sat, 23 Jun 2018 10:57:25 -0700 Subject: [PATCH] require mutual consent --- connect.go | 59 +++++++++++++++++++++++++++++++++++++++++++----- relay.go | 66 ++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 100 insertions(+), 25 deletions(-) diff --git a/connect.go b/connect.go index 6c299f28..d23ac59c 100644 --- a/connect.go +++ b/connect.go @@ -144,7 +144,7 @@ func NewConnection(config *AppConfig) (*Connection, error) { if c.Debug { SetLogLevel("debug") } else { - SetLogLevel("warn") + SetLogLevel("error") } return c, nil @@ -296,6 +296,8 @@ func (c *Connection) runClient(serverName string) error { responses.Lock() responses.startTime = time.Now() responses.Unlock() + var okToContinue bool + fileTransfered := false for id := 0; id < c.NumberOfConnections; id++ { go func(id int) { defer wg.Done() @@ -366,7 +368,36 @@ func (c *Connection) runClient(serverName string) error { log.Debugf("[%d] got ok from relay: %s", id, message) publicKeyRecipient := receiveMessage(connection) // 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 { passphraseString := RandStringBytesMaskImprSrc(20) log.Debugf("passphrase: [%s]", passphraseString) @@ -424,7 +455,9 @@ func (c *Connection) runClient(serverName string) error { c.bar.Reset() } if err := c.sendFile(id, connection); err != nil { - log.Error(err) + log.Warn(err) + } else { + fileTransfered = true } } } else { // this is a receiver @@ -523,11 +556,21 @@ func (c *Connection) runClient(serverName string) error { sendMessage("ok", connection) encryptedPassword := receiveMessage(connection) log.Debugf("[%d] got encrypted passphrase: %s", id, encryptedPassword) + if encryptedPassword == "" { + return + } encryptedPasswordBytes, err := base64.StdEncoding.DecodeString(encryptedPassword) if err != nil { panic(err) } + if publicKeySender == "" { + return + } decryptedPassphrase, err := c.keypair.Decrypt(encryptedPasswordBytes, publicKeySender) + if err != nil { + log.Warn(err) + return + } c.encryptedPassword = string(decryptedPassphrase) log.Debugf("decrypted password to: %s", c.encryptedPassword) if err != nil { @@ -550,6 +593,8 @@ func (c *Connection) runClient(serverName string) error { } if err := c.receiveFile(id, connection); err != nil { 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() - if c.IsSender { + if !fileTransfered { + fmt.Fprintf(os.Stderr, "\nNo mutual consent") + } else if c.IsSender { if responses.gotTimeout { fmt.Println("Timeout waiting for receiver") return nil @@ -576,7 +623,7 @@ func (c *Connection) runClient(serverName string) error { if c.File.IsDir { fileOrFolder = "Folder" } - fmt.Printf("\n%s sent", fileOrFolder) + fmt.Fprintf(os.Stderr, "\n%s sent", fileOrFolder) } else { // Is a Receiver if responses.notPresent { 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)) } if errWrite != nil { - log.Error(errWrite) + return errWrite } if err == io.EOF { //End of file reached, break out of for loop diff --git a/relay.go b/relay.go index 371c70e9..8f10c11f 100644 --- a/relay.go +++ b/relay.go @@ -21,6 +21,7 @@ type connectionMap struct { potentialReceivers map[string]struct{} rpublicKey map[string]string spublicKey map[string]string + sconsent map[string]string passphrase map[string]string receiverReady map[string]bool sync.RWMutex @@ -71,6 +72,7 @@ func (r *Relay) Run() { r.connections.spublicKey = make(map[string]string) r.connections.rpublicKey = 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.receiverReady = make(map[string]bool) r.connections.Unlock() @@ -139,6 +141,23 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { switch connectionType { 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) { sendMessage("no", connection) return @@ -177,8 +196,14 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { sendMessage(receiversPublicKey, connection) // TODO ASK FOR OKAY HERE TOO - isokay := receiveMessage(connection) - logger.Debug(isokay) + sconsent := receiveMessage(connection) + 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") encryptedPassphrase := receiveMessage(connection) @@ -205,21 +230,6 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { logger.Debug("piping connections") 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) - 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 if r.connections.IsPotentialReceiverConnected(key) { sendMessage("no", connection) @@ -267,6 +277,24 @@ func (r *Relay) clientCommuncation(id int, connection net.Conn) { sendMessage(sendersPublicKey, connection) 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 sendersPassphrase := "" for { @@ -337,8 +365,8 @@ func receiveMessage(connection net.Conn) string { } _, err = connection.Read(messageByte) if err != nil { - logger.Warn(err) - logger.Warn("no response") + logger.Debug(err) + logger.Debug("no response") return "" } return strings.TrimRight(string(messageByte), ":")