Switch to HTTP for transfer

This commit is contained in:
Elara 2021-06-19 00:01:31 -07:00
parent 56f82c02f8
commit 116e2cd9ab
7 changed files with 153 additions and 248 deletions

View File

@ -21,16 +21,17 @@ import (
"crypto/md5" "crypto/md5"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"github.com/klauspost/compress/zstd"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/chacha20poly1305"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"github.com/klauspost/compress/zstd"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/crypto/chacha20poly1305"
) )
// Encrypt given file using the shared key // Encrypt given file using the shared key
@ -43,7 +44,7 @@ func CompressAndEncryptFile(filePath string, newFilePath string, sharedKey strin
log.Fatal().Err(err).Msg("Error opening file") log.Fatal().Err(err).Msg("Error opening file")
} }
// Create buffer for compressed data // Create buffer for compressed data
compressedBuffer := new(bytes.Buffer) compressedBuffer := &bytes.Buffer{}
// Create Zstd encoder // Create Zstd encoder
zstdEncoder, err := zstd.NewWriter(compressedBuffer) zstdEncoder, err := zstd.NewWriter(compressedBuffer)
if err != nil { if err != nil {

275
files.go
View File

@ -17,42 +17,19 @@
package main package main
import ( import (
"bufio"
"bytes"
"ekyu.moe/base91"
"errors"
"fmt"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"io" "io"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http"
"os" "os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
) )
// Encode byte slice to base91 encoded, escaped string for transmission
func EncodeToSafeString(data []byte) string {
// Encode data to base91 string
base91Data := base91.EncodeToString(data)
// Replace all semicolons with "-" as semicolon is used as a separator
escapedBase91Data := strings.ReplaceAll(base91Data, ";", "-")
// Return escaped base91 string
return escapedBase91Data
}
// Decode base91 encoded, escaped string to byte slice
func DecodeSafeString(base91Str string) ([]byte, error) {
// Replace "-" with semicolon to reverse escape
base91Data := strings.ReplaceAll(base91Str, "-", ";")
// Decode unescaped base91 string
data := base91.DecodeString(base91Data)
// Return byte slice
return data, nil
}
// Save encrypted key to file // Save encrypted key to file
func SaveEncryptedKey(encryptedKey []byte, filePath string) { func SaveEncryptedKey(encryptedKey []byte, filePath string) {
// Use ConsoleWriter logger // Use ConsoleWriter logger
@ -82,180 +59,114 @@ func SendFiles(dir string) {
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error starting listener") log.Fatal().Err(err).Msg("Error starting listener")
} }
// Accept connection on listener
connection, err := listener.Accept() http.HandleFunc("/key", func(res http.ResponseWriter, req *http.Request) {
if err != nil { // Inform user client has requested key
log.Fatal().Err(err).Msg("Error accepting connection") log.Info().Msg("Key requested")
} // Read saved key
// Close connection at the end of this function key, err := ioutil.ReadFile(dir + "/key.aes")
defer connection.Close()
// Create for loop to listen for messages on connection
connectionLoop:
for {
// Use ConsoleWriter logger with TCPFatalHook
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(TCPFatalHook{conn: connection})
// Attempt to read new message on connection
data, err := bufio.NewReader(connection).ReadString('\n')
// If no message detected, try again
if err != nil && err.Error() == "EOF" {
continue
}
// If non-EOF error, fatally log
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error reading data") log.Fatal().Err(err).Msg("Error reading key")
} }
// Process received data // Write saved key to ResponseWriter
processedData := strings.Split(strings.TrimSpace(data), ";") _, err = res.Write(key)
// If processedData is empty, alert the user of invalid data if err != nil {
if len(processedData) < 1 { log.Fatal().Err(err).Msg("Error writing response")
log.Fatal().Str("data", data).Msg("Received data invalid")
} }
switch processedData[0] { })
case "key":
// Inform user client has requested key http.HandleFunc("/index", func(res http.ResponseWriter, req *http.Request) {
log.Info().Msg("Key requested") // Inform user a client has requested the file index
// Read saved key log.Info().Msg("Index requested")
key, err := ioutil.ReadFile(dir + "/key.aes") // Get directory listing
if err != nil { dirListing, err := ioutil.ReadDir(dir)
log.Fatal().Err(err).Msg("Error reading key") if err != nil {
} log.Fatal().Err(err).Msg("Error reading directory")
// Write saved key to ResponseWriter
_, err = fmt.Fprintln(connection, "OK;"+EncodeToSafeString(key)+";")
if err != nil {
log.Fatal().Err(err).Msg("Error writing response")
}
case "index":
// Inform user a client has requested the file index
log.Info().Msg("Index requested")
// Get directory listing
dirListing, err := ioutil.ReadDir(dir)
if err != nil {
log.Fatal().Err(err).Msg("Error reading directory")
}
// Create new slice to house filenames for index
var indexSlice []string
// For each file in listing
for _, file := range dirListing {
// If the file is not the key
if !strings.Contains(file.Name(), "key.aes") {
// Append the file path to indexSlice
indexSlice = append(indexSlice, file.Name())
}
}
// Join index slice into string
indexStr := strings.Join(indexSlice, "|")
// Write index to ResponseWriter
_, err = fmt.Fprintln(connection, "OK;"+indexStr+";")
if err != nil {
log.Fatal().Err(err).Msg("Error writing response")
}
case "file":
// If processedData only has one entry
if len(processedData) == 1 {
// Warn user of unexpected end of line
log.Warn().Err(errors.New("unexpected eol")).Msg("Invalid file request")
// Send error to connection
_, _ = fmt.Fprintln(connection, "ERR;")
// Break out of switch
break
}
// Set file to first path components of URL, excluding first /
file := processedData[1]
// Read file at specified location
fileData, err := ioutil.ReadFile(dir + "/" + file)
// If there was an error reading
if err != nil {
// Warn user of error
log.Warn().Err(err).Msg("Error reading file")
// Otherwise
} else {
// Inform user client has requested a file
log.Info().Str("file", file).Msg("File requested")
}
// Write file as base91 to connection
_, err = fmt.Fprintln(connection, "OK;"+EncodeToSafeString(fileData)+";")
if err != nil {
log.Fatal().Err(err).Msg("Error writing response")
}
case "stop":
// Alert user that stop signal has been received
log.Info().Msg("Received stop signal")
// Print ok message to connection
_, _ = fmt.Fprintln(connection, "OK;")
// Break out of connectionLoop
break connectionLoop
} }
} // Create new slice to house filenames for index
var indexSlice []string
// For each file in listing
for _, file := range dirListing {
// If the file is not the key
if !strings.Contains(file.Name(), "key.aes") {
// Append the file path to indexSlice
indexSlice = append(indexSlice, file.Name())
}
}
// Join index slice into string
indexStr := strings.Join(indexSlice, "|")
// Write index to ResponseWriter
_, err = res.Write([]byte(indexStr))
if err != nil {
log.Fatal().Err(err).Msg("Error writing response")
}
})
http.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
log.Info().Str("file", filepath.Base(req.URL.Path)).Msg("File requested")
http.FileServer(http.Dir(dir)).ServeHTTP(res, req)
})
http.HandleFunc("/stop", func(res http.ResponseWriter, req *http.Request) {
log.Info().Msg("Stop signal received")
res.WriteHeader(http.StatusOK)
listener.Close()
})
http.Serve(listener, nil)
} }
func ConnectToSender(senderAddr string) net.Conn { type Sender struct {
// Get server address by getting the IP without the port, and appending :9898 RemoteAddr string
serverAddr := strings.Split(senderAddr, ":")[0] + ":9898" }
// Create error variable
var err error func (c *Sender) Get(endpoint string) (io.ReadCloser, int, error) {
// Create connection variable res, err := http.Get(c.RemoteAddr + endpoint)
var connection net.Conn if err != nil {
// Until break return nil, 0, err
for {
// Try connecting to sender
connection, err = net.Dial("tcp", serverAddr)
// If connection refused
if err != nil && strings.Contains(err.Error(), "connection refused") {
// Continue loop (retry)
continue
// If error other than connection refused
} else if err != nil {
// Fatally log
log.Fatal().Err(err).Msg("Error connecting to sender")
// If no error
} else {
// Break out of loop
break
}
} }
// Returned created connection return res.Body, res.StatusCode, nil
return connection }
func NewSender(senderAddr string) *Sender {
// Get server address by getting the IP without the port, and appending :9898
host, _, _ := net.SplitHostPort(senderAddr)
serverAddr := "http://" + net.JoinHostPort(host, "9898")
return &Sender{RemoteAddr: serverAddr}
} }
// Get files from sender // Get files from sender
func RecvFiles(connection net.Conn) { func RecvFiles(sender *Sender) {
// Use ConsoleWriter logger // Use ConsoleWriter logger
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{}) log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
// Request index from sender indexReader, code, err := sender.Get("/index")
_, err := fmt.Fprintln(connection, "index;")
if err != nil {
log.Fatal().Err(err).Msg("Error sending index request")
}
// Read received message
message, err := bufio.NewReader(connection).ReadString('\n')
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error getting index") log.Fatal().Err(err).Msg("Error getting index")
} }
// Process received message
procMessage := strings.Split(strings.TrimSpace(message), ";")
// If non-ok code returned, fatally log // If non-ok code returned, fatally log
if procMessage[0] != "OK" { if code != http.StatusOK {
log.Fatal().Err(err).Msg("Sender reported error") log.Fatal().Err(err).Msg("Sender reported error")
} }
indexBytes, err := ioutil.ReadAll(indexReader)
if err != nil {
log.Fatal().Err(err).Msg("Error reading index from response")
}
// Get index from message // Get index from message
index := strings.Split(strings.TrimSpace(procMessage[1]), "|") index := strings.Split(strings.TrimSpace(string(indexBytes)), "|")
for _, file := range index { for _, file := range index {
// Get current file in index
_, err = fmt.Fprintln(connection, "file;"+file+";")
if err != nil {
log.Fatal().Err(err).Msg("Error sending file request")
}
// Read received message // Read received message
message, err := bufio.NewReader(connection).ReadString('\n') fileData, code, err := sender.Get("/" + file)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error getting file") log.Fatal().Err(err).Msg("Error getting file")
} }
// Process received message
procMessage := strings.Split(message, ";")
// If non-ok code returned // If non-ok code returned
if procMessage[0] != "OK" { if code != http.StatusOK {
// fatally log // fatally log
log.Fatal().Err(err).Msg("Sender reported error") log.Fatal().
Int("status", code).
Str("statusText", http.StatusText(code)).
Err(err).
Msg("Sender reported error")
// Otherwise // Otherwise
} else { } else {
// Create new file at index filepath // Create new file at index filepath
@ -263,13 +174,8 @@ func RecvFiles(connection net.Conn) {
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error creating file") log.Fatal().Err(err).Msg("Error creating file")
} }
// Decode file data from base91 string
fileData, err := DecodeSafeString(strings.TrimSpace(procMessage[1]))
if err != nil {
log.Fatal().Err(err).Msg("Error decoding hex")
}
// Copy response body to new file // Copy response body to new file
bytesWritten, err := io.Copy(newFile, bytes.NewBuffer(fileData)) bytesWritten, err := io.Copy(newFile, fileData)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error writing to file") log.Fatal().Err(err).Msg("Error writing to file")
} }
@ -282,9 +188,6 @@ func RecvFiles(connection net.Conn) {
} }
// Send stop signal to sender // Send stop signal to sender
func SendSrvStopSignal(connection net.Conn) { func SendSrvStopSignal(sender *Sender) {
// Send stop signal to connection _, _, _ = sender.Get("/stop")
_, _ = fmt.Fprintln(connection, "stop;")
// Close connection
_ = connection.Close()
} }

2
go.mod
View File

@ -3,12 +3,12 @@ module opensend
go 1.15 go 1.15
require ( require (
ekyu.moe/base91 v0.2.3
github.com/grandcat/zeroconf v1.0.0 github.com/grandcat/zeroconf v1.0.0
github.com/klauspost/compress v1.11.3 github.com/klauspost/compress v1.11.3
github.com/pelletier/go-toml v1.8.1 github.com/pelletier/go-toml v1.8.1
github.com/pkg/browser v0.0.0-20201112035734-206646e67786 github.com/pkg/browser v0.0.0-20201112035734-206646e67786
github.com/rs/zerolog v1.20.0 github.com/rs/zerolog v1.20.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
) )

10
go.sum
View File

@ -3,6 +3,7 @@ ekyu.moe/base91 v0.2.3/go.mod h1:/qmmaFUj5d0p9xcpj8beZDj33yXrc54eGU+hO/V5vuo=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/grandcat/zeroconf v1.0.0 h1:uHhahLBKqwWBV6WZUDAT71044vwOTL+McW0mBJvo6kE= github.com/grandcat/zeroconf v1.0.0 h1:uHhahLBKqwWBV6WZUDAT71044vwOTL+McW0mBJvo6kE=
@ -18,11 +19,18 @@ github.com/pkg/browser v0.0.0-20201112035734-206646e67786/go.mod h1:N6UoU20jOqgg
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs= github.com/rs/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo= github.com/rs/zerolog v1.20.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc=
github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
@ -44,3 +52,5 @@ golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@ -17,16 +17,15 @@
package main package main
import ( import (
"bufio"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/sha256" "crypto/sha256"
"fmt" "io/ioutil"
"net/http"
"os"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"net"
"os"
"strings"
) )
// Generate RSA keypair // Generate RSA keypair
@ -45,25 +44,18 @@ func GenerateRSAKeypair() (*rsa.PrivateKey, *rsa.PublicKey) {
} }
// Get public key from sender // Get public key from sender
func GetKey(connection net.Conn) []byte { func GetKey(sender *Sender) []byte {
// Use ConsoleWriter logger // Use ConsoleWriter logger
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{}) log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
// Send key request to connection // Send key request to connection
_, err := fmt.Fprintln(connection, "key;") keyReader, code, err := sender.Get("/key")
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error sending key request") log.Fatal().Err(err).Msg("Error sending key request")
} }
// Read received message
message, err := bufio.NewReader(connection).ReadString('\n')
if err != nil {
log.Fatal().Err(err).Msg("Error getting key")
}
// Process received message
procMessage := strings.Split(strings.TrimSpace(message), ";")
// If ok code returned // If ok code returned
if procMessage[0] == "OK" { if code == http.StatusOK {
// Decode received safe base91 string into key // Read received bytes into key
key, err := DecodeSafeString(procMessage[1]) key, err := ioutil.ReadAll(keyReader)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error reading key") log.Fatal().Err(err).Msg("Error reading key")
} }

48
main.go
View File

@ -20,10 +20,7 @@ import (
"bufio" "bufio"
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
flag "github.com/spf13/pflag"
"fmt" "fmt"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"io" "io"
"os" "os"
"os/signal" "os/signal"
@ -31,6 +28,10 @@ import (
"strings" "strings"
"syscall" "syscall"
"time" "time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
flag "github.com/spf13/pflag"
) )
var workDir *string var workDir *string
@ -106,19 +107,16 @@ func main() {
// Create channel for signals // Create channel for signals
sig := make(chan os.Signal, 1) sig := make(chan os.Signal, 1)
// Send message on channel upon reception of SIGINT or SIGTERM // Send message on channel upon reception of SIGINT or SIGTERM
signal.Notify(sig, os.Interrupt, syscall.SIGTERM) signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
// Intercept signal // Intercept signal
go func() { go func() {
select { signal := <-sig
// Wait for sig to be written // Warn user that a signal has been received and that opensend is shutting down
case <-sig: log.Warn().Str("signal", signal.String()).Msg("Signal received. Shutting down.")
// Warn user that a signal has been received and that opensend is shutting down // Remove opensend directory to avoid future conflicts
log.Warn().Msg("Signal received. Shutting down.") _ = os.RemoveAll(*workDir)
// Remove opensend directory to avoid future conflicts // Exit with code 0
_ = os.RemoveAll(*workDir) os.Exit(0)
// Exit with code 0
os.Exit(0)
}
}() }()
// Create opensend dir ignoring errors // Create opensend dir ignoring errors
@ -228,7 +226,7 @@ func main() {
// Notify user files are being received // Notify user files are being received
log.Info().Msg("Receiving files from server (This may take a while)") log.Info().Msg("Receiving files from server (This may take a while)")
// Connect to sender's TCP socket // Connect to sender's TCP socket
connection := ConnectToSender(senderIP) connection := NewSender(senderIP)
// Get files from sender and place them into the opensend directory // Get files from sender and place them into the opensend directory
RecvFiles(connection) RecvFiles(connection)
// Get encrypted shared key from sender // Get encrypted shared key from sender
@ -244,10 +242,10 @@ func main() {
// Instantiate Config // Instantiate Config
parameters := &Parameters{} parameters := &Parameters{}
// Read config file in opensend directory // Read config file in opensend directory
parameters.ReadFile(*workDir + "/parameters.json") parameters.ReadFile(*workDir + "/parameters.msgpack")
// Notify user that action is being executed // Notify user that action is being executed
log.Info().Msg("Executing JSON action") log.Info().Msg("Executing action")
// Execute JSON action using files within opensend directory // Execute MessagePack action using files within opensend directory
parameters.ExecuteAction(*workDir, *destDir) parameters.ExecuteAction(*workDir, *destDir)
// Remove opensend directory // Remove opensend directory
err := os.RemoveAll(*workDir) err := os.RemoveAll(*workDir)
@ -276,13 +274,13 @@ func main() {
// Notify user files are being received // Notify user files are being received
log.Info().Msg("Receiving files from server (This may take a while)") log.Info().Msg("Receiving files from server (This may take a while)")
// Connect to sender's TCP socket // Connect to sender's TCP socket
connection := ConnectToSender(senderIP) sender := NewSender(senderIP)
// Get files from sender and place them into the opensend directory // Get files from sender and place them into the opensend directory
RecvFiles(connection) RecvFiles(sender)
// Get encrypted shared key from sender // Get encrypted shared key from sender
encryptedKey := GetKey(connection) encryptedKey := GetKey(sender)
// Send stop signal to sender's HTTP server // Send stop signal to sender's HTTP server
SendSrvStopSignal(connection) SendSrvStopSignal(sender)
// Decrypt shared key // Decrypt shared key
sharedKey := DecryptKey(encryptedKey, privateKey) sharedKey := DecryptKey(encryptedKey, privateKey)
// Notify user file decryption is beginning // Notify user file decryption is beginning
@ -292,10 +290,10 @@ func main() {
// Instantiate Config // Instantiate Config
parameters := &Parameters{} parameters := &Parameters{}
// Read config file in opensend directory // Read config file in opensend directory
parameters.ReadFile(*workDir + "/parameters.json") parameters.ReadFile(*workDir + "/parameters.msgpack")
// Notify user that action is being executed // Notify user that action is being executed
log.Info().Msg("Executing JSON action") log.Info().Msg("Executing Action")
// Execute JSON action using files within opensend directory // Execute MessagePack action using files within opensend directory
parameters.ExecuteAction(*workDir, *destDir) parameters.ExecuteAction(*workDir, *destDir)
} else { } else {
flag.Usage() flag.Usage()

View File

@ -18,10 +18,6 @@ package main
import ( import (
"archive/tar" "archive/tar"
"encoding/json"
"github.com/pkg/browser"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"io" "io"
"io/ioutil" "io/ioutil"
"net/url" "net/url"
@ -29,6 +25,11 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"github.com/pkg/browser"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/vmihailenco/msgpack/v5"
) )
// Create config type to store action type and data // Create config type to store action type and data
@ -67,24 +68,24 @@ func (parameters *Parameters) CreateFile(dir string) {
// Use ConsoleWriter logger // Use ConsoleWriter logger
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{}) log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
// Create parameters file at given directory // Create parameters file at given directory
configFile, err := os.Create(dir + "/parameters.json") configFile, err := os.Create(dir + "/parameters.msgpack")
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error creating parameters file") log.Fatal().Err(err).Msg("Error creating parameters file")
} }
// Close parameters file at the end of this function // Close parameters file at the end of this function
defer configFile.Close() defer configFile.Close()
// Marshal given Parameters struct into a []byte // Marshal given Parameters struct into a []byte
jsonData, err := json.Marshal(parameters) MessagePackData, err := msgpack.Marshal(parameters)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error encoding JSON") log.Fatal().Err(err).Msg("Error encoding MessagePack")
} }
// Write []byte to previously created parameters file // Write []byte to previously created parameters file
bytesWritten, err := configFile.Write(jsonData) bytesWritten, err := configFile.Write(MessagePackData)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error writing JSON to file") log.Fatal().Err(err).Msg("Error writing MessagePack to file")
} }
// Log bytes written // Log bytes written
log.Info().Str("file", "parameters.json").Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes") log.Info().Str("file", "parameters.msgpack").Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
} }
// Collect all required files into given directory // Collect all required files into given directory
@ -178,10 +179,10 @@ func (parameters *Parameters) ReadFile(filePath string) {
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error reading parameters file") log.Fatal().Err(err).Msg("Error reading parameters file")
} }
// Unmarshal data from JSON into parameters struct // Unmarshal data from MessagePack into parameters struct
err = json.Unmarshal(fileData, parameters) err = msgpack.Unmarshal(fileData, parameters)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Error decoding JSON") log.Fatal().Err(err).Msg("Error decoding MessagePack")
} }
} }
@ -262,7 +263,7 @@ func (parameters *Parameters) ExecuteAction(srcDir string, destDir string) {
break unarchiveLoop break unarchiveLoop
} else if err != nil { } else if err != nil {
log.Fatal().Err(err).Msg("Error unarchiving tar archive") log.Fatal().Err(err).Msg("Error unarchiving tar archive")
// If nil header // If nil header
} else if header == nil { } else if header == nil {
// Skip // Skip
continue continue