diff --git a/client.go b/client.go index f9ab65a..82db5fa 100644 --- a/client.go +++ b/client.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "bytes" "encoding/gob" "errors" "fmt" @@ -16,6 +17,7 @@ import ( type Client struct { address string port int + list bool } func (c *Client) Connect() error { @@ -32,12 +34,41 @@ func (c *Client) Connect() error { fmt.Printf("Connection on %s\n", address) sharedKey := secure.Handshake(conn) - secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey} + secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey, Buffer: &bytes.Buffer{}} - // reader := bufio.NewReader(os.Stdin) enc := gob.NewEncoder(&secureConnection) + dec := gob.NewDecoder(&secureConnection) - for { + if c.list { + log.Printf("requesting file list") + // list mode + msg := secure.PacketStart{ + OperationType: secure.OperationTypeList, + ClientName: "Justin Hawkins", + ProtocolVersion: "v1.0", + AuthToken: "abc123", + } + err := enc.Encode(msg) + if err != nil { + panic(err) + } + // now we expect to get stuff back until we don't + for { + listPacket := secure.PacketListData{} + err := dec.Decode(&listPacket) + if err == io.EOF { + break + } + if err != nil { + panic(err) + } + log.Printf("%d: %s (%d bytes)", listPacket.Id, listPacket.Kind, listPacket.FileSize) + } + conn.Close() + log.Printf("done listing") + + } else { + // must be send mode msg := secure.PacketStart{ OperationType: secure.OperationTypeSend, @@ -96,8 +127,7 @@ func (c *Client) Connect() error { conn.Close() - break } - return nil + } diff --git a/main.go b/main.go index b037dbf..bc5b171 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,8 @@ func main() { port := flag.Int("p", 9000, "Port to run server/client on.") addr := flag.String("a", "61.245.149.58", "address to connect to.") isServer := flag.Bool("s", false, "Set if running the server.") + isList := flag.Bool("l", false, "Set if requesting a list") + flag.Parse() if *isServer { @@ -19,7 +21,7 @@ func main() { s.Run() } else { fmt.Printf("Client running on %d\n", *port) - c := Client{port: *port, address: *addr} + c := Client{port: *port, address: *addr, list: *isList} err := c.Connect() if err != nil { fmt.Print(err) diff --git a/secure/secure.go b/secure/secure.go index 2209432..6986765 100644 --- a/secure/secure.go +++ b/secure/secure.go @@ -72,13 +72,19 @@ func (s *SecureConnection) Read(p []byte) (int, error) { if err == io.EOF { eof = true } + // if n == 0 && bytes.Buffer.{ + // return 0, io.EOF + // } // log.Printf("read: got %d bytes on the wire, error is %v", n, err) // log.Printf("looks like %v", message[:n]) - if eof { - log.Printf("eof is true - this is our final read!") - } + // if eof { + // log.Printf("eof is true - this is our final read!") + // } + // log.Printf("writing n=%d", n) + // log.Printf("writing buffersize=%v", s.Buffer) + // log.Printf("writing n=%d buffersize=%d this: %v", n, s.Buffer.Len(), s.Buffer.Bytes()[:n]) s.Buffer.Write(message[:n]) // log.Printf("read: appended them to the buffer which is now %d bytes", len(s.Buffer.Bytes())) @@ -154,7 +160,6 @@ func (s *SecureConnection) Write(p []byte) (int, error) { func Handshake(conn *net.TCPConn) *[32]byte { var peerKey, sharedKey [32]byte - log.Print("starting handshake") publicKey, privateKey, _ := box.GenerateKey(rand.Reader) conn.Write(publicKey[:]) @@ -165,8 +170,6 @@ func Handshake(conn *net.TCPConn) *[32]byte { box.Precompute(&sharedKey, &peerKey, privateKey) - log.Printf("ending handshake, sk: %v", sharedKey) - return &sharedKey } @@ -174,6 +177,7 @@ type OperationTypeEnum byte const ( OperationTypeSend OperationTypeEnum = iota + OperationTypeList ) // PacketStart is sent from the client to the server at the beginning @@ -190,6 +194,13 @@ type PacketSendDataStart struct { TotalSize uint32 } +type PacketListData struct { + Id uint32 + Filename string + FileSize uint32 + Kind string +} + type PacketSendDataNext struct { Size uint16 Data []byte diff --git a/server.go b/server.go index cc8f340..a7445e8 100644 --- a/server.go +++ b/server.go @@ -8,6 +8,7 @@ import ( "log" "net" "os" + "sync/atomic" "time" "github.com/h2non/filetype" @@ -21,12 +22,16 @@ type Server struct { // An NGF is a Netgiv File type NGF struct { + Id uint32 StorePath string Filename string // could be empty string if we were not supplied with one Kind string // Size uint64 // file size } +var ngfs []NGF +var globalId uint32 + func (s *Server) Run() { address := fmt.Sprintf(":%d", s.port) networkAddress, _ := net.ResolveTCPAddr("tcp", address) @@ -37,6 +42,8 @@ func (s *Server) Run() { os.Exit(2) } + ngfs = make([]NGF, 0) + for { conn, err := listener.AcceptTCP() @@ -60,34 +67,37 @@ func handleConnection(conn *net.TCPConn) { gob.Register(secure.PacketSendDataStart{}) dec := gob.NewDecoder(&secureConnection) + enc := gob.NewEncoder(&secureConnection) // Get the start packet start := secure.PacketStart{} err := dec.Decode(&start) if err == io.EOF { - log.Printf("connection has been closed after start packet") + log.Printf("connection has been closed prematurely") return } if err != nil { - log.Printf("some error with start packet: %w", err) + log.Printf("error while expecting PacketStart: %v", err) return } - log.Printf("Decoded packet:\n%#v", start) conn.SetDeadline(time.Now().Add(time.Second * 5)) if start.OperationType == secure.OperationTypeSend { - log.Printf("client wants to send us something, expecting a send start") + log.Printf("file incoming") + sendStart := secure.PacketSendDataStart{} err = dec.Decode(&sendStart) if err != nil { - log.Printf("error at send data start: %w", err) + log.Printf("error - expecting PacketSendDataStart: %v", err) return } - log.Printf("send start looks like: %v", sendStart) file, err := os.CreateTemp("", "netgiv_") + if err != nil { + log.Fatalf("can't open tempfile: %v", err) + } defer file.Close() ngf := NGF{ @@ -95,24 +105,23 @@ func handleConnection(conn *net.TCPConn) { Filename: sendStart.Filename, Kind: "", Size: 0, + Id: atomic.AddUint32(&globalId, 1), } if err != nil { log.Printf("got error with temp file: %w", err) return } - log.Printf("writing data to file: %s", file.Name()) sendData := secure.PacketSendDataNext{} determinedKind := false for { conn.SetDeadline(time.Now().Add(time.Second * 5)) err = dec.Decode(&sendData) if err == io.EOF { - log.Printf("WE ARE DONE writing to: %s", file.Name()) break } if err != nil { - log.Printf("error decoding data next: %s", err) + log.Printf("error while expecting PacketSendDataNext: %s", err) return } @@ -132,10 +141,27 @@ func handleConnection(conn *net.TCPConn) { return } ngf.Size = uint64(info.Size()) - log.Printf("received a %#v", ngf) file.Close() + ngfs = append(ngfs, ngf) + log.Printf("done receiving file") + return + } else if start.OperationType == secure.OperationTypeList { + log.Printf("client requesting file list") + + for _, ngf := range ngfs { + p := secure.PacketListData{} + p.FileSize = uint32(ngf.Size) + p.Kind = ngf.Kind + p.Id = ngf.Id + p.Filename = ngf.Filename + enc.Encode(p) + } + log.Printf("done sending list, closing connection") + + return + } else { log.Printf("bad operation") return