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 {
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

View File

@ -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), ":")