2022-01-09 13:05:36 +10:30
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2022-01-13 22:20:35 +10:30
|
|
|
"bufio"
|
2022-01-14 23:30:14 +10:30
|
|
|
"bytes"
|
2022-01-13 14:26:16 +10:30
|
|
|
"encoding/gob"
|
2022-01-09 13:05:36 +10:30
|
|
|
"errors"
|
|
|
|
"fmt"
|
2022-01-13 22:20:35 +10:30
|
|
|
"io"
|
2022-01-09 13:05:36 +10:30
|
|
|
"net"
|
2022-01-13 22:20:35 +10:30
|
|
|
"os"
|
2022-01-09 13:05:36 +10:30
|
|
|
|
2022-01-16 12:58:11 +10:30
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
2022-01-15 23:10:46 +10:30
|
|
|
"github.com/dustin/go-humanize"
|
2022-01-09 13:05:36 +10:30
|
|
|
"github.com/tardisx/netgiv/secure"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Client struct {
|
2022-01-13 22:20:35 +10:30
|
|
|
address string
|
|
|
|
port int
|
2022-01-14 23:30:14 +10:30
|
|
|
list bool
|
2022-01-15 18:20:31 +10:30
|
|
|
send bool
|
2022-01-15 14:04:13 +10:30
|
|
|
receive bool
|
2022-01-09 13:05:36 +10:30
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) Connect() error {
|
2022-01-13 22:20:35 +10:30
|
|
|
address := fmt.Sprintf("%s:%d", c.address, c.port)
|
|
|
|
|
2022-01-09 13:05:36 +10:30
|
|
|
serverAddress, _ := net.ResolveTCPAddr("tcp", address)
|
|
|
|
|
|
|
|
conn, err := net.DialTCP("tcp", nil, serverAddress)
|
|
|
|
if err != nil {
|
2022-01-13 14:26:16 +10:30
|
|
|
return errors.New("problem connecting to server, is it running?\n")
|
2022-01-09 13:05:36 +10:30
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
|
2022-01-15 14:04:13 +10:30
|
|
|
log.Printf("Connection on %s\n", address)
|
2022-01-09 13:05:36 +10:30
|
|
|
|
|
|
|
sharedKey := secure.Handshake(conn)
|
2022-01-14 23:30:14 +10:30
|
|
|
secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey, Buffer: &bytes.Buffer{}}
|
2022-01-09 13:05:36 +10:30
|
|
|
|
2022-01-13 14:26:16 +10:30
|
|
|
enc := gob.NewEncoder(&secureConnection)
|
2022-01-14 23:30:14 +10:30
|
|
|
dec := gob.NewDecoder(&secureConnection)
|
2022-01-09 13:05:36 +10:30
|
|
|
|
2022-01-14 23:30:14 +10:30
|
|
|
if c.list {
|
|
|
|
log.Printf("requesting file list")
|
2022-01-16 12:58:11 +10:30
|
|
|
|
|
|
|
err := connectToServer(secure.OperationTypeList, enc, dec)
|
2022-01-14 23:30:14 +10:30
|
|
|
if err != nil {
|
2022-01-16 12:58:11 +10:30
|
|
|
return fmt.Errorf("could not connect and auth: %v", err)
|
2022-01-14 23:30:14 +10:30
|
|
|
}
|
2022-01-16 12:58:11 +10:30
|
|
|
|
2022-01-14 23:30:14 +10:30
|
|
|
// 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)
|
|
|
|
}
|
2022-01-15 23:10:46 +10:30
|
|
|
log.Printf("%d: %s (%s)", listPacket.Id, listPacket.Kind, humanize.Bytes(uint64(listPacket.FileSize)))
|
2022-01-14 23:30:14 +10:30
|
|
|
}
|
|
|
|
conn.Close()
|
|
|
|
log.Printf("done listing")
|
|
|
|
|
2022-01-15 14:04:13 +10:30
|
|
|
} else if c.receive {
|
|
|
|
log.Printf("receiving a file")
|
2022-01-16 12:58:11 +10:30
|
|
|
|
|
|
|
err := connectToServer(secure.OperationTypeReceive, enc, dec)
|
2022-01-15 14:04:13 +10:30
|
|
|
if err != nil {
|
2022-01-16 12:58:11 +10:30
|
|
|
return fmt.Errorf("could not connect and auth: %v", err)
|
2022-01-15 14:04:13 +10:30
|
|
|
}
|
|
|
|
|
|
|
|
req := secure.PacketReceiveDataStartRequest{
|
2022-01-15 16:47:06 +10:30
|
|
|
Id: 0, // 0 means last? Change to do a fetch?
|
2022-01-15 14:04:13 +10:30
|
|
|
}
|
|
|
|
err = enc.Encode(req)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
// expect a response telling us if we can go ahead
|
|
|
|
res := secure.PacketReceiveDataStartResponse{}
|
|
|
|
err = dec.Decode(&res)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if res.Status == secure.ReceiveDataStartResponseOK {
|
|
|
|
for {
|
|
|
|
res := secure.PacketReceiveDataNext{}
|
|
|
|
err = dec.Decode(&res)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
os.Stdout.Write(res.Data[:res.Size])
|
|
|
|
if res.Last {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Printf("finished")
|
2022-01-15 16:47:06 +10:30
|
|
|
} else if res.Status == secure.ReceiveDataStartResponseNotFound {
|
|
|
|
log.Printf("ngf not found")
|
2022-01-15 14:04:13 +10:30
|
|
|
} else {
|
2022-01-15 16:47:06 +10:30
|
|
|
panic("unknown status")
|
2022-01-15 14:04:13 +10:30
|
|
|
}
|
|
|
|
|
|
|
|
conn.Close()
|
2022-01-15 18:20:31 +10:30
|
|
|
} else if c.send {
|
|
|
|
// send mode
|
2022-01-09 13:05:36 +10:30
|
|
|
|
2022-01-16 12:58:11 +10:30
|
|
|
err := connectToServer(secure.OperationTypeSend, enc, dec)
|
2022-01-13 14:26:16 +10:30
|
|
|
if err != nil {
|
2022-01-16 12:58:11 +10:30
|
|
|
return fmt.Errorf("could not connect and auth: %v", err)
|
2022-01-13 14:26:16 +10:30
|
|
|
}
|
2022-01-09 13:05:36 +10:30
|
|
|
|
2022-01-14 13:07:56 +10:30
|
|
|
data := secure.PacketSendDataStart{
|
|
|
|
Filename: "",
|
|
|
|
TotalSize: 0,
|
|
|
|
}
|
|
|
|
err = enc.Encode(data)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2022-01-13 22:20:35 +10:30
|
|
|
nBytes, nChunks := int64(0), int64(0)
|
|
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
buf := make([]byte, 0, 1024)
|
|
|
|
|
|
|
|
for {
|
|
|
|
n, err := reader.Read(buf[:cap(buf)])
|
2022-01-14 10:06:55 +10:30
|
|
|
|
2022-01-13 22:20:35 +10:30
|
|
|
buf = buf[:n]
|
2022-01-14 10:06:55 +10:30
|
|
|
|
2022-01-13 22:20:35 +10:30
|
|
|
if n == 0 {
|
|
|
|
if err == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
nChunks++
|
|
|
|
nBytes += int64(len(buf))
|
2022-01-14 10:06:55 +10:30
|
|
|
|
2022-01-13 22:20:35 +10:30
|
|
|
send := secure.PacketSendDataNext{
|
|
|
|
Size: 5000,
|
|
|
|
Data: buf,
|
|
|
|
}
|
|
|
|
enc.Encode(send)
|
|
|
|
// time.Sleep(time.Second)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.Println("Bytes:", nBytes, "Chunks:", nChunks)
|
|
|
|
|
2022-01-13 14:26:16 +10:30
|
|
|
conn.Close()
|
|
|
|
|
2022-01-15 18:20:31 +10:30
|
|
|
} else {
|
|
|
|
panic("no client mode set")
|
2022-01-09 13:05:36 +10:30
|
|
|
}
|
|
|
|
return nil
|
2022-01-14 23:30:14 +10:30
|
|
|
|
2022-01-09 13:05:36 +10:30
|
|
|
}
|
2022-01-16 12:58:11 +10:30
|
|
|
|
|
|
|
func connectToServer(op secure.OperationTypeEnum, enc *gob.Encoder, dec *gob.Decoder) error {
|
|
|
|
|
|
|
|
// list mode
|
|
|
|
startPacket := secure.PacketStartRequest{
|
|
|
|
OperationType: op,
|
|
|
|
ClientName: "",
|
|
|
|
ProtocolVersion: "1.0",
|
|
|
|
AuthToken: "dummy",
|
|
|
|
}
|
|
|
|
err := enc.Encode(startPacket)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not send start packet: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// check the response is ok
|
|
|
|
response := secure.PacketStartResponse{}
|
|
|
|
err = dec.Decode(&response)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("could not receive start packet response: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if response.Response == secure.PacketStartResponseEnumWrongProtocol {
|
|
|
|
log.Print("wrong protocol version")
|
|
|
|
return errors.New("protocol version mismatch")
|
|
|
|
|
|
|
|
}
|
|
|
|
if response.Response == secure.PacketStartResponseEnumBadAuthToken {
|
|
|
|
log.Print("bad authtoken")
|
|
|
|
return errors.New("bad authtoken")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|