Browse Source

Added end-to-end AES encryption

main 1.2.0
Unbewohnte 3 years ago
parent
commit
f4c8f2d728
  1. 7
      README.md
  2. 30
      encryption/decrypt.go
  3. 24
      encryption/encrypt.go
  4. 27
      encryption/key.go
  5. 15
      main.go
  6. 6
      protocol/headers.go
  7. 33
      protocol/packet.go
  8. 38
      receiver/receiver.go
  9. 78
      sender/sender.go

7
README.md

@ -35,7 +35,7 @@ Thus, with a connection and a way of communication, the sender will send some pa
- Lack of proper error-handling; somewhat FIXED - [x] - Lack of proper error-handling; somewhat FIXED - [x]
- Lack of information about the process of transferring (ETA, lost packets, etc.); FIXED - [ ] - Lack of information about the process of transferring (ETA, lost packets, etc.); FIXED - [ ]
- No way to verify if the transferred file is not corrupted; FIXED via checksum- [x] - No way to verify if the transferred file is not corrupted; FIXED via checksum- [x]
- No encryption; FIXED - [ ] - No encryption; FIXED via AES encryption of packets` body - [x]
- Messy and hard to follow code && file structure; FIXED? - [x] - Messy and hard to follow code && file structure; FIXED? - [x]
- No way to stop the download/upload and resume it later or even during the next connection; FIXED - [ ] - No way to stop the download/upload and resume it later or even during the next connection; FIXED - [ ]
- No tests; FIXED - [ ] - No tests; FIXED - [ ]
@ -66,9 +66,10 @@ Thus, with a connection and a way of communication, the sender will send some pa
`./FTU [FLAGS_HERE]` or `FTU [FLAGS_HERE]` `./FTU [FLAGS_HERE]` or `FTU [FLAGS_HERE]`
### Flags ### Flags
`./FTU --help` - to get all flags` description
- `-port` (int) - specifies a working port (if sending - listens on this port, else - tries to connect to this port); - `-port` (int) - specifies a working port (if sending - listens on this port, else - tries to connect to this port);
- `addr` (string) - specifies an address to connect to; - `-addr` (string) - specifies an address to connect to;
- `-sharefile` (string) - specifies path to a file you want to share, if given a valid path - sender will offer to download this file to receiver; - `-sharefile` (string) - specifies path to a file you want to share, if given a valid path - sender will offer to download this file to receiver;
- `-downloadto` (string) - specifies path to a folder where the receiver wants to store downloaded file; - `-downloadto` (string) - specifies path to a folder where the receiver wants to store downloaded file;

30
encryption/decrypt.go

@ -0,0 +1,30 @@
package encryption
import (
"crypto/aes"
"crypto/cipher"
"fmt"
)
// Decrypts encrypted aes data with given key.
// https://www.melvinvivas.com/how-to-encrypt-and-decrypt-data-using-aes/ - very grateful to the author, THANK YOU.
func Decrypt(key, dataToDecrypt []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("could not create new AES cipher: %s", err)
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("could not create new GCM: %s", err)
}
nonce, encryptedBytes := dataToDecrypt[:aesGCM.NonceSize()], dataToDecrypt[aesGCM.NonceSize():]
decryptedData, err := aesGCM.Open(nil, nonce, encryptedBytes, nil)
if err != nil {
return nil, fmt.Errorf("could not decrypt given data: %s", err)
}
return decryptedData, nil
}

24
encryption/encrypt.go

@ -0,0 +1,24 @@
package encryption
import (
"crypto/aes"
"crypto/cipher"
"fmt"
)
// Encrypts given data using aes encryption.
// https://www.melvinvivas.com/how-to-encrypt-and-decrypt-data-using-aes/ - very grateful to the author, THANK YOU.
func Encrypt(key, dataToEncrypt []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, fmt.Errorf("could not create new AES cipher: %s", err)
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
return nil, fmt.Errorf("could not create new GCM: %s", err)
}
nonce := make([]byte, aesGCM.NonceSize())
encryptedData := aesGCM.Seal(nonce, nonce, dataToEncrypt, nil)
return encryptedData, nil
}

27
encryption/key.go

@ -0,0 +1,27 @@
package encryption
import (
"math/rand"
"time"
)
// using aes256, so 32 bytes-long key
const KEYLEN uint = 32
const CHARS string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
// Generates 32 pseudo-random bytes to use as a key
func Generate32AESkey() []byte {
var generatedKey []byte
rand.Seed(time.Now().UTC().UnixNano())
// choosing "random" 32 bytes from CHARS
for {
if len(generatedKey) == int(KEYLEN) {
break
}
randomIndex := rand.Intn(len(CHARS))
generatedKey = append(generatedKey, CHARS[randomIndex])
}
return generatedKey
}

15
main.go

@ -12,23 +12,16 @@ import (
// flags // flags
var PORT *int = flag.Int("port", 8080, "Specifies a port for a sender|port to connect to") var PORT *int = flag.Int("port", 8080, "Specifies a port for a sender|port to connect to")
var SENDERADDR *string = flag.String("addr", "", "Specifies an IP for connection") var SENDERADDR *string = flag.String("addr", "", "Specifies an address to connect to")
var DOWNLOADSFOLDER *string = flag.String("downloadto", "", "Specifies where the receiver will store downloaded file") var DOWNLOADSFOLDER *string = flag.String("downloadto", "", "Specifies where the receiver will store downloaded file")
var SHAREDFILE *string = flag.String("sharefile", "", "Specifies what file sender will send") var SHAREDFILE *string = flag.String("sharefile", "", "Specifies what file sender will send")
var SENDING bool var SENDING bool
// helpMessage
var HELPMSG string = `
"-port", default: 8080, Specifies a port for a sender|port to connect to
"-addr", default: "", Specifies an IP for connection
"-downloadto", default: "", Specifies where the receiver will store downloaded file
"-sharefile", default: "", Specifies what file sender will send`
// Input-validation // Input-validation
func processFlags() { func processFlags() {
if *PORT < 0 { if *PORT < 0 {
fmt.Println("Invalid port !\n", HELPMSG) fmt.Println("Invalid port !")
os.Exit(-1) os.Exit(-1)
} }
@ -39,7 +32,7 @@ func processFlags() {
// specifying address to connect to -> receiving // specifying address to connect to -> receiving
if strings.TrimSpace(*SENDERADDR) != "" { if strings.TrimSpace(*SENDERADDR) != "" {
if SENDING { if SENDING {
fmt.Println("Cannot specify an address when sharing !\n", HELPMSG) fmt.Println("Cannot specify an address when sharing !")
os.Exit(-1) os.Exit(-1)
} }
SENDING = false SENDING = false
@ -47,7 +40,7 @@ func processFlags() {
// specifying path to download to -> receiving // specifying path to download to -> receiving
if strings.TrimSpace(*DOWNLOADSFOLDER) != "" { if strings.TrimSpace(*DOWNLOADSFOLDER) != "" {
if SENDING { if SENDING {
fmt.Println("Cannot specify a downloads directory when sharing !\n", HELPMSG) fmt.Println("Cannot specify a downloads directory when sharing !")
os.Exit(-1) os.Exit(-1)
} }
SENDING = false SENDING = false

6
protocol/headers.go

@ -7,6 +7,12 @@ type Header string
//// In the following below examples "|" is PACKETSIZEDELIMETER and "~" is HEADERDELIMETER //// In the following below examples "|" is PACKETSIZEDELIMETER and "~" is HEADERDELIMETER
// ENCRKEY.
// The FIRST header to be sent. Sent immediately after the connection has been established
// by sender. Body contains randomly generated by sender aes encryption key.
// ie: |40|ENCRKEY~SUPER_SECURE_ENCRYPTION_KEY_YESS
const HeaderEncryptionKey Header = "ENCRKEY"
// FILENAME. // FILENAME.
// This header is sent only by sender. The packet with this header // This header is sent only by sender. The packet with this header
// must contain a name of the transported file in BODY. // must contain a name of the transported file in BODY.

33
protocol/packet.go

@ -12,6 +12,8 @@ import (
"fmt" "fmt"
"net" "net"
"strconv" "strconv"
"github.com/Unbewohnte/FTU/encryption"
) )
// Internal representation of packet before|after the transportation // Internal representation of packet before|after the transportation
@ -56,7 +58,7 @@ func SendPacket(connection net.Conn, packetToSend Packet) error {
packetSize := MeasurePacketSize(packetToSend) packetSize := MeasurePacketSize(packetToSend)
if packetSize > uint64(MAXPACKETSIZE) { if packetSize > uint64(MAXPACKETSIZE) {
return fmt.Errorf("invalid packet: HEADER: %s BODY: %s: EXCEEDED MAX PACKETSIZE", packetToSend.Header, packetToSend.Body) return fmt.Errorf("invalid packet!: EXCEEDED MAX PACKETSIZE")
} }
// packetsize between delimeters (ie: |17|) // packetsize between delimeters (ie: |17|)
@ -83,9 +85,28 @@ func SendPacket(connection net.Conn, packetToSend Packet) error {
return nil return nil
} }
// Reads a packet from given connection. // Sends given packet to connection, as the normal `SendPacket` method, but
// encodes given packet`s BODY with AES encryption
func SendEncryptedPacket(connection net.Conn, packetToSend Packet, key []byte) error {
// encrypting packet`s body
encryptedBody, err := encryption.Encrypt(key, packetToSend.Body)
if err != nil {
return fmt.Errorf("could not encrypt packet`s body: %s", err)
}
packetToSend.Body = encryptedBody
// sending the encrypted packet
err = SendPacket(connection, packetToSend)
if err != nil {
return fmt.Errorf("could not send packet: %s", err)
}
return nil
}
// Reads a packet from given connection, returns its bytes.
// ASSUMING THAT THE PACKETS ARE SENT BY `SendPacket` function !!!! // ASSUMING THAT THE PACKETS ARE SENT BY `SendPacket` function !!!!
func ReadFromConn(connection net.Conn) (Packet, error) { func ReadFromConn(connection net.Conn) ([]byte, error) {
var err error var err error
var delimeterCounter int = 0 var delimeterCounter int = 0
var packetSizeStrBuffer string = "" var packetSizeStrBuffer string = ""
@ -114,7 +135,7 @@ func ReadFromConn(connection net.Conn) (Packet, error) {
packetSize, err = strconv.Atoi(packetSizeStrBuffer) packetSize, err = strconv.Atoi(packetSizeStrBuffer)
if err != nil { if err != nil {
return Packet{}, fmt.Errorf("could not convert packetsizeStr into int: %s", err) return nil, fmt.Errorf("could not convert packetsizeStr into int: %s", err)
} }
// have a packetsize, now reading the whole packet // have a packetsize, now reading the whole packet
@ -137,7 +158,5 @@ func ReadFromConn(connection net.Conn) (Packet, error) {
packetBuffer.Write(buff[:read]) packetBuffer.Write(buff[:read])
} }
packet := BytesToPacket(packetBuffer.Bytes()) return packetBuffer.Bytes(), nil
return packet, nil
} }

38
receiver/receiver.go

@ -10,6 +10,7 @@ import (
"time" "time"
"github.com/Unbewohnte/FTU/checksum" "github.com/Unbewohnte/FTU/checksum"
"github.com/Unbewohnte/FTU/encryption"
"github.com/Unbewohnte/FTU/protocol" "github.com/Unbewohnte/FTU/protocol"
) )
@ -19,6 +20,7 @@ type Receiver struct {
Connection net.Conn Connection net.Conn
IncomingPackets chan protocol.Packet IncomingPackets chan protocol.Packet
FileToDownload *File FileToDownload *File
EncryptionKey []byte
ReadyToReceive bool ReadyToReceive bool
Stopped bool Stopped bool
FileBytesPacketCounter uint64 FileBytesPacketCounter uint64
@ -64,7 +66,7 @@ func (r *Receiver) Stop() {
disconnectionPacket := protocol.Packet{ disconnectionPacket := protocol.Packet{
Header: protocol.HeaderDisconnecting, Header: protocol.HeaderDisconnecting,
} }
protocol.SendPacket(r.Connection, disconnectionPacket) protocol.SendEncryptedPacket(r.Connection, disconnectionPacket, r.EncryptionKey)
r.Stopped = true r.Stopped = true
r.Disconnect() r.Disconnect()
} }
@ -110,7 +112,7 @@ func (r *Receiver) HandleFileOffer() error {
rejectionPacket := protocol.Packet{ rejectionPacket := protocol.Packet{
Header: protocol.HeaderReject, Header: protocol.HeaderReject,
} }
err := protocol.SendPacket(r.Connection, rejectionPacket) err := protocol.SendEncryptedPacket(r.Connection, rejectionPacket, r.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send a rejection packet: %s", err) return fmt.Errorf("could not send a rejection packet: %s", err)
} }
@ -147,7 +149,7 @@ func (r *Receiver) HandleFileOffer() error {
acceptancePacket := protocol.Packet{ acceptancePacket := protocol.Packet{
Header: protocol.HeaderAccept, Header: protocol.HeaderAccept,
} }
err = protocol.SendPacket(r.Connection, acceptancePacket) err = protocol.SendEncryptedPacket(r.Connection, acceptancePacket, r.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send an acceptance packet: %s", err) return fmt.Errorf("could not send an acceptance packet: %s", err)
} }
@ -174,16 +176,33 @@ func (r *Receiver) WritePieceOfFile(filePacket protocol.Packet) error {
return nil return nil
} }
// Listens in an endless loop; reads incoming packages and puts them into channel // Listens in an endless loop; reads incoming packets, decrypts their BODY and puts into channel
func (r *Receiver) ReceivePackets() { func (r *Receiver) ReceivePackets() {
for { for {
incomingPacket, err := protocol.ReadFromConn(r.Connection) incomingPacketBytes, err := protocol.ReadFromConn(r.Connection)
if err != nil { if err != nil {
// in current implementation there is no way to receive a working file even if only one packet is missing
fmt.Printf("Error reading a packet: %s\nExiting...", err) fmt.Printf("Error reading a packet: %s\nExiting...", err)
r.Stop() r.Stop()
os.Exit(-1) os.Exit(-1)
} }
incomingPacket := protocol.BytesToPacket(incomingPacketBytes)
// if this is the FIRST packet - it has HeaderEncryptionKey, so no need to decrypt
if incomingPacket.Header == protocol.HeaderEncryptionKey {
r.IncomingPackets <- incomingPacket
continue
}
decryptedBody, err := encryption.Decrypt(r.EncryptionKey, incomingPacket.Body)
if err != nil {
fmt.Printf("Error decrypring incoming packet`s BODY: %s\nExiting...", err)
r.Stop()
os.Exit(-1)
}
incomingPacket.Body = decryptedBody
r.IncomingPackets <- incomingPacket r.IncomingPackets <- incomingPacket
} }
} }
@ -198,7 +217,6 @@ func (r *Receiver) MainLoop() {
for { for {
if r.Stopped { if r.Stopped {
// exit the mainloop
break break
} }
@ -206,7 +224,7 @@ func (r *Receiver) MainLoop() {
readyPacket := protocol.Packet{ readyPacket := protocol.Packet{
Header: protocol.HeaderReady, Header: protocol.HeaderReady,
} }
err := protocol.SendPacket(r.Connection, readyPacket) err := protocol.SendEncryptedPacket(r.Connection, readyPacket, r.EncryptionKey)
if err != nil { if err != nil {
fmt.Printf("Could not send the packet: %s\nExiting...", err) fmt.Printf("Could not send the packet: %s\nExiting...", err)
r.Stop() r.Stop()
@ -225,6 +243,10 @@ func (r *Receiver) MainLoop() {
// handling each packet header differently // handling each packet header differently
switch incomingPacket.Header { switch incomingPacket.Header {
case protocol.HeaderEncryptionKey:
r.EncryptionKey = incomingPacket.Body
fmt.Println("Got the encryption key: ", string(incomingPacket.Body))
case protocol.HeaderFilename: case protocol.HeaderFilename:
r.FileToDownload.Filename = string(incomingPacket.Body) r.FileToDownload.Filename = string(incomingPacket.Body)

78
sender/sender.go

@ -7,6 +7,7 @@ import (
"strconv" "strconv"
"github.com/Unbewohnte/FTU/checksum" "github.com/Unbewohnte/FTU/checksum"
"github.com/Unbewohnte/FTU/encryption"
"github.com/Unbewohnte/FTU/protocol" "github.com/Unbewohnte/FTU/protocol"
) )
@ -17,13 +18,14 @@ type Sender struct {
Listener net.Listener Listener net.Listener
Connection net.Conn Connection net.Conn
IncomingPackets chan protocol.Packet IncomingPackets chan protocol.Packet
EncryptionKey []byte
SentFileBytesPackets uint64 SentFileBytesPackets uint64
TransferAllowed bool TransferAllowed bool
ReceiverIsReady bool ReceiverIsReady bool
Stopped bool Stopped bool
} }
// Creates a new sender with default fields // Creates a new sender with default|necessary fields
func NewSender(port int, filepath string) *Sender { func NewSender(port int, filepath string) *Sender {
fileToTransfer, err := getFile(filepath) fileToTransfer, err := getFile(filepath)
if err != nil { if err != nil {
@ -45,6 +47,10 @@ func NewSender(port int, filepath string) *Sender {
panic(err) panic(err)
} }
// !!!
key := encryption.Generate32AESkey()
fmt.Printf("GENERATED ENCRYPTION KEY: %s\n", key)
var filepacketCounter uint64 var filepacketCounter uint64
fmt.Printf("Created a new sender at %s:%d (remote)\n%s:%d (local)\n", remoteIP, port, localIP, port) fmt.Printf("Created a new sender at %s:%d (remote)\n%s:%d (local)\n", remoteIP, port, localIP, port)
return &Sender{ return &Sender{
@ -54,6 +60,7 @@ func NewSender(port int, filepath string) *Sender {
Connection: nil, Connection: nil,
IncomingPackets: incomingPacketsChan, IncomingPackets: incomingPacketsChan,
SentFileBytesPackets: filepacketCounter, SentFileBytesPackets: filepacketCounter,
EncryptionKey: key,
TransferAllowed: false, TransferAllowed: false,
ReceiverIsReady: false, ReceiverIsReady: false,
Stopped: false, Stopped: false,
@ -65,7 +72,7 @@ func (s *Sender) Stop() {
disconnectionPacket := protocol.Packet{ disconnectionPacket := protocol.Packet{
Header: protocol.HeaderDisconnecting, Header: protocol.HeaderDisconnecting,
} }
err := protocol.SendPacket(s.Connection, disconnectionPacket) err := protocol.SendEncryptedPacket(s.Connection, disconnectionPacket, s.EncryptionKey)
if err != nil { if err != nil {
panic(fmt.Sprintf("could not send a disconnection packet: %s", err)) panic(fmt.Sprintf("could not send a disconnection packet: %s", err))
} }
@ -95,6 +102,21 @@ func (s *Sender) StopListening() {
s.Listener.Close() s.Listener.Close()
} }
// Sends generated earlier eas encryption key to receiver
func (s *Sender) SendEncryptionKey() error {
keyPacket := protocol.Packet{
Header: protocol.HeaderEncryptionKey,
Body: s.EncryptionKey,
}
err := protocol.SendPacket(s.Connection, keyPacket)
if err != nil {
return fmt.Errorf("could not send a packet: %s", err)
}
return nil
}
// Sends multiple packets with all information about the file to receiver // Sends multiple packets with all information about the file to receiver
// (filename, filesize, checksum) // (filename, filesize, checksum)
func (s *Sender) SendOffer() error { func (s *Sender) SendOffer() error {
@ -103,7 +125,7 @@ func (s *Sender) SendOffer() error {
Header: protocol.HeaderFilename, Header: protocol.HeaderFilename,
Body: []byte(s.FileToTransfer.Filename), Body: []byte(s.FileToTransfer.Filename),
} }
err := protocol.SendPacket(s.Connection, filenamePacket) err := protocol.SendEncryptedPacket(s.Connection, filenamePacket, s.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send an information about the file: %s", err) return fmt.Errorf("could not send an information about the file: %s", err)
} }
@ -114,7 +136,7 @@ func (s *Sender) SendOffer() error {
Body: []byte(strconv.Itoa(int(s.FileToTransfer.Filesize))), Body: []byte(strconv.Itoa(int(s.FileToTransfer.Filesize))),
} }
err = protocol.SendPacket(s.Connection, filesizePacket) err = protocol.SendEncryptedPacket(s.Connection, filesizePacket, s.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send an information about the file: %s", err) return fmt.Errorf("could not send an information about the file: %s", err)
} }
@ -124,7 +146,7 @@ func (s *Sender) SendOffer() error {
Header: protocol.HeaderChecksum, Header: protocol.HeaderChecksum,
Body: checksum.ChecksumToBytes(s.FileToTransfer.CheckSum), Body: checksum.ChecksumToBytes(s.FileToTransfer.CheckSum),
} }
err = protocol.SendPacket(s.Connection, checksumPacket) err = protocol.SendEncryptedPacket(s.Connection, checksumPacket, s.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send an information about the file: %s", err) return fmt.Errorf("could not send an information about the file: %s", err)
} }
@ -133,7 +155,7 @@ func (s *Sender) SendOffer() error {
donePacket := protocol.Packet{ donePacket := protocol.Packet{
Header: protocol.HeaderDone, Header: protocol.HeaderDone,
} }
err = protocol.SendPacket(s.Connection, donePacket) err = protocol.SendEncryptedPacket(s.Connection, donePacket, s.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send an information about the file: %s", err) return fmt.Errorf("could not send an information about the file: %s", err)
} }
@ -153,8 +175,8 @@ func (s *Sender) SendPiece() error {
Header: protocol.HeaderFileBytes, Header: protocol.HeaderFileBytes,
} }
// how many bytes we can send at maximum // how many bytes we can send at maximum (including some little space for padding)
maxFileBytes := protocol.MAXPACKETSIZE - uint(protocol.MeasurePacketSize(fileBytesPacket)) maxFileBytes := protocol.MAXPACKETSIZE - (uint(protocol.MeasurePacketSize(fileBytesPacket)) + 90)
fileBytes := make([]byte, maxFileBytes) fileBytes := make([]byte, maxFileBytes)
// if there is less data to send than the limit - create a buffer of needed size // if there is less data to send than the limit - create a buffer of needed size
@ -171,7 +193,7 @@ func (s *Sender) SendPiece() error {
// filling BODY with bytes // filling BODY with bytes
fileBytesPacket.Body = fileBytes fileBytesPacket.Body = fileBytes
err = protocol.SendPacket(s.Connection, fileBytesPacket) err = protocol.SendEncryptedPacket(s.Connection, fileBytesPacket, s.EncryptionKey)
if err != nil { if err != nil {
return fmt.Errorf("could not send a file packet : %s", err) return fmt.Errorf("could not send a file packet : %s", err)
} }
@ -184,15 +206,27 @@ func (s *Sender) SendPiece() error {
return nil return nil
} }
// Listens in an endless loop; reads incoming packages and puts them into channel // Listens in an endless loop; reads incoming packets, decrypts their BODY and puts into channel
func (s *Sender) ReceivePackets() { func (s *Sender) ReceivePackets() {
for { for {
incomingPacket, err := protocol.ReadFromConn(s.Connection) incomingPacketBytes, err := protocol.ReadFromConn(s.Connection)
if err != nil { if err != nil {
// in current implementation there is no way to receive a working file even if only one packet is missing
fmt.Printf("Error reading a packet: %s\nExiting...", err) fmt.Printf("Error reading a packet: %s\nExiting...", err)
s.Stop()
os.Exit(-1)
}
incomingPacket := protocol.BytesToPacket(incomingPacketBytes)
decryptedBody, err := encryption.Decrypt(s.EncryptionKey, incomingPacket.Body)
if err != nil {
fmt.Printf("Error decrypting an incoming packet: %s\nExiting...", err)
s.Stop()
os.Exit(-1) os.Exit(-1)
} }
incomingPacket.Body = decryptedBody
s.IncomingPackets <- incomingPacket s.IncomingPackets <- incomingPacket
} }
} }
@ -204,12 +238,22 @@ func (s *Sender) MainLoop() {
go s.ReceivePackets() go s.ReceivePackets()
// instantly sending an encryption key, following the protocol`s rule
err := s.SendEncryptionKey()
if err != nil {
fmt.Printf("Could not send an encryption key: %s\nExiting...", err)
s.Stop()
}
// send an information about the shared file to the receiver // send an information about the shared file to the receiver
s.SendOffer() err = s.SendOffer()
if err != nil {
fmt.Printf("Could not send an info about the file: %s\nExiting...", err)
s.Stop()
}
for { for {
if s.Stopped { if s.Stopped {
// exit the mainloop
break break
} }
@ -237,13 +281,13 @@ func (s *Sender) MainLoop() {
fmt.Println("The transfer has been accepted !") fmt.Println("The transfer has been accepted !")
s.TransferAllowed = true s.TransferAllowed = true
case protocol.HeaderReady:
s.ReceiverIsReady = true
case protocol.HeaderReject: case protocol.HeaderReject:
fmt.Println("The transfer has been rejected") fmt.Println("The transfer has been rejected")
s.Stop() s.Stop()
case protocol.HeaderReady:
s.ReceiverIsReady = true
case protocol.HeaderDisconnecting: case protocol.HeaderDisconnecting:
// receiver is dropping the file transfer ? // receiver is dropping the file transfer ?
fmt.Println("Receiver has disconnected") fmt.Println("Receiver has disconnected")

Loading…
Cancel
Save