Add listing

This commit is contained in:
Justin Hawkins 2022-01-14 23:30:14 +10:30
parent 5adfd08595
commit 1e4ee09d5c
4 changed files with 91 additions and 22 deletions

View File

@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes"
"encoding/gob" "encoding/gob"
"errors" "errors"
"fmt" "fmt"
@ -16,6 +17,7 @@ import (
type Client struct { type Client struct {
address string address string
port int port int
list bool
} }
func (c *Client) Connect() error { func (c *Client) Connect() error {
@ -32,12 +34,41 @@ func (c *Client) Connect() error {
fmt.Printf("Connection on %s\n", address) fmt.Printf("Connection on %s\n", address)
sharedKey := secure.Handshake(conn) 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) 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{ msg := secure.PacketStart{
OperationType: secure.OperationTypeSend, OperationType: secure.OperationTypeSend,
@ -96,8 +127,7 @@ func (c *Client) Connect() error {
conn.Close() conn.Close()
break
} }
return nil return nil
} }

View File

@ -11,6 +11,8 @@ func main() {
port := flag.Int("p", 9000, "Port to run server/client on.") port := flag.Int("p", 9000, "Port to run server/client on.")
addr := flag.String("a", "61.245.149.58", "address to connect to.") addr := flag.String("a", "61.245.149.58", "address to connect to.")
isServer := flag.Bool("s", false, "Set if running the server.") isServer := flag.Bool("s", false, "Set if running the server.")
isList := flag.Bool("l", false, "Set if requesting a list")
flag.Parse() flag.Parse()
if *isServer { if *isServer {
@ -19,7 +21,7 @@ func main() {
s.Run() s.Run()
} else { } else {
fmt.Printf("Client running on %d\n", *port) 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() err := c.Connect()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)

View File

@ -72,13 +72,19 @@ func (s *SecureConnection) Read(p []byte) (int, error) {
if err == io.EOF { if err == io.EOF {
eof = true 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("read: got %d bytes on the wire, error is %v", n, err)
// log.Printf("looks like %v", message[:n]) // log.Printf("looks like %v", message[:n])
if eof { // if eof {
log.Printf("eof is true - this is our final read!") // 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]) s.Buffer.Write(message[:n])
// log.Printf("read: appended them to the buffer which is now %d bytes", len(s.Buffer.Bytes())) // 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 { func Handshake(conn *net.TCPConn) *[32]byte {
var peerKey, sharedKey [32]byte var peerKey, sharedKey [32]byte
log.Print("starting handshake")
publicKey, privateKey, _ := box.GenerateKey(rand.Reader) publicKey, privateKey, _ := box.GenerateKey(rand.Reader)
conn.Write(publicKey[:]) conn.Write(publicKey[:])
@ -165,8 +170,6 @@ func Handshake(conn *net.TCPConn) *[32]byte {
box.Precompute(&sharedKey, &peerKey, privateKey) box.Precompute(&sharedKey, &peerKey, privateKey)
log.Printf("ending handshake, sk: %v", sharedKey)
return &sharedKey return &sharedKey
} }
@ -174,6 +177,7 @@ type OperationTypeEnum byte
const ( const (
OperationTypeSend OperationTypeEnum = iota OperationTypeSend OperationTypeEnum = iota
OperationTypeList
) )
// PacketStart is sent from the client to the server at the beginning // PacketStart is sent from the client to the server at the beginning
@ -190,6 +194,13 @@ type PacketSendDataStart struct {
TotalSize uint32 TotalSize uint32
} }
type PacketListData struct {
Id uint32
Filename string
FileSize uint32
Kind string
}
type PacketSendDataNext struct { type PacketSendDataNext struct {
Size uint16 Size uint16
Data []byte Data []byte

View File

@ -8,6 +8,7 @@ import (
"log" "log"
"net" "net"
"os" "os"
"sync/atomic"
"time" "time"
"github.com/h2non/filetype" "github.com/h2non/filetype"
@ -21,12 +22,16 @@ type Server struct {
// An NGF is a Netgiv File // An NGF is a Netgiv File
type NGF struct { type NGF struct {
Id uint32
StorePath string StorePath string
Filename string // could be empty string if we were not supplied with one Filename string // could be empty string if we were not supplied with one
Kind string // Kind string //
Size uint64 // file size Size uint64 // file size
} }
var ngfs []NGF
var globalId uint32
func (s *Server) Run() { func (s *Server) Run() {
address := fmt.Sprintf(":%d", s.port) address := fmt.Sprintf(":%d", s.port)
networkAddress, _ := net.ResolveTCPAddr("tcp", address) networkAddress, _ := net.ResolveTCPAddr("tcp", address)
@ -37,6 +42,8 @@ func (s *Server) Run() {
os.Exit(2) os.Exit(2)
} }
ngfs = make([]NGF, 0)
for { for {
conn, err := listener.AcceptTCP() conn, err := listener.AcceptTCP()
@ -60,34 +67,37 @@ func handleConnection(conn *net.TCPConn) {
gob.Register(secure.PacketSendDataStart{}) gob.Register(secure.PacketSendDataStart{})
dec := gob.NewDecoder(&secureConnection) dec := gob.NewDecoder(&secureConnection)
enc := gob.NewEncoder(&secureConnection)
// Get the start packet // Get the start packet
start := secure.PacketStart{} start := secure.PacketStart{}
err := dec.Decode(&start) err := dec.Decode(&start)
if err == io.EOF { if err == io.EOF {
log.Printf("connection has been closed after start packet") log.Printf("connection has been closed prematurely")
return return
} }
if err != nil { if err != nil {
log.Printf("some error with start packet: %w", err) log.Printf("error while expecting PacketStart: %v", err)
return return
} }
log.Printf("Decoded packet:\n%#v", start)
conn.SetDeadline(time.Now().Add(time.Second * 5)) conn.SetDeadline(time.Now().Add(time.Second * 5))
if start.OperationType == secure.OperationTypeSend { if start.OperationType == secure.OperationTypeSend {
log.Printf("client wants to send us something, expecting a send start") log.Printf("file incoming")
sendStart := secure.PacketSendDataStart{} sendStart := secure.PacketSendDataStart{}
err = dec.Decode(&sendStart) err = dec.Decode(&sendStart)
if err != nil { if err != nil {
log.Printf("error at send data start: %w", err) log.Printf("error - expecting PacketSendDataStart: %v", err)
return return
} }
log.Printf("send start looks like: %v", sendStart)
file, err := os.CreateTemp("", "netgiv_") file, err := os.CreateTemp("", "netgiv_")
if err != nil {
log.Fatalf("can't open tempfile: %v", err)
}
defer file.Close() defer file.Close()
ngf := NGF{ ngf := NGF{
@ -95,24 +105,23 @@ func handleConnection(conn *net.TCPConn) {
Filename: sendStart.Filename, Filename: sendStart.Filename,
Kind: "", Kind: "",
Size: 0, Size: 0,
Id: atomic.AddUint32(&globalId, 1),
} }
if err != nil { if err != nil {
log.Printf("got error with temp file: %w", err) log.Printf("got error with temp file: %w", err)
return return
} }
log.Printf("writing data to file: %s", file.Name())
sendData := secure.PacketSendDataNext{} sendData := secure.PacketSendDataNext{}
determinedKind := false determinedKind := false
for { for {
conn.SetDeadline(time.Now().Add(time.Second * 5)) conn.SetDeadline(time.Now().Add(time.Second * 5))
err = dec.Decode(&sendData) err = dec.Decode(&sendData)
if err == io.EOF { if err == io.EOF {
log.Printf("WE ARE DONE writing to: %s", file.Name())
break break
} }
if err != nil { if err != nil {
log.Printf("error decoding data next: %s", err) log.Printf("error while expecting PacketSendDataNext: %s", err)
return return
} }
@ -132,10 +141,27 @@ func handleConnection(conn *net.TCPConn) {
return return
} }
ngf.Size = uint64(info.Size()) ngf.Size = uint64(info.Size())
log.Printf("received a %#v", ngf)
file.Close() file.Close()
ngfs = append(ngfs, ngf)
log.Printf("done receiving file")
return 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 { } else {
log.Printf("bad operation") log.Printf("bad operation")
return return