Switch to HTTP for transfer
This commit is contained in:
		@@ -21,16 +21,17 @@ import (
 | 
			
		||||
	"crypto/md5"
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	"github.com/klauspost/compress/zstd"
 | 
			
		||||
	"github.com/rs/zerolog"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	"golang.org/x/crypto/chacha20poly1305"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"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
 | 
			
		||||
@@ -43,7 +44,7 @@ func CompressAndEncryptFile(filePath string, newFilePath string, sharedKey strin
 | 
			
		||||
		log.Fatal().Err(err).Msg("Error opening file")
 | 
			
		||||
	}
 | 
			
		||||
	// Create buffer for compressed data
 | 
			
		||||
	compressedBuffer := new(bytes.Buffer)
 | 
			
		||||
	compressedBuffer := &bytes.Buffer{}
 | 
			
		||||
	// Create Zstd encoder
 | 
			
		||||
	zstdEncoder, err := zstd.NewWriter(compressedBuffer)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										275
									
								
								files.go
									
									
									
									
									
								
							
							
						
						
									
										275
									
								
								files.go
									
									
									
									
									
								
							@@ -17,42 +17,19 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"ekyu.moe/base91"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/rs/zerolog"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"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
 | 
			
		||||
func SaveEncryptedKey(encryptedKey []byte, filePath string) {
 | 
			
		||||
	// Use ConsoleWriter logger
 | 
			
		||||
@@ -82,180 +59,114 @@ func SendFiles(dir string) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal().Err(err).Msg("Error starting listener")
 | 
			
		||||
	}
 | 
			
		||||
	// Accept connection on listener
 | 
			
		||||
	connection, err := listener.Accept()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal().Err(err).Msg("Error accepting connection")
 | 
			
		||||
	}
 | 
			
		||||
	// Close connection at the end of this function
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/key", func(res http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		// Inform user client has requested key
 | 
			
		||||
		log.Info().Msg("Key requested")
 | 
			
		||||
		// Read saved key
 | 
			
		||||
		key, err := ioutil.ReadFile(dir + "/key.aes")
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatal().Err(err).Msg("Error reading data")
 | 
			
		||||
			log.Fatal().Err(err).Msg("Error reading key")
 | 
			
		||||
		}
 | 
			
		||||
		// Process received data
 | 
			
		||||
		processedData := strings.Split(strings.TrimSpace(data), ";")
 | 
			
		||||
		// If processedData is empty, alert the user of invalid data
 | 
			
		||||
		if len(processedData) < 1 {
 | 
			
		||||
			log.Fatal().Str("data", data).Msg("Received data invalid")
 | 
			
		||||
		// Write saved key to ResponseWriter
 | 
			
		||||
		_, err = res.Write(key)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatal().Err(err).Msg("Error writing response")
 | 
			
		||||
		}
 | 
			
		||||
		switch processedData[0] {
 | 
			
		||||
		case "key":
 | 
			
		||||
			// Inform user client has requested key
 | 
			
		||||
			log.Info().Msg("Key requested")
 | 
			
		||||
			// Read saved key
 | 
			
		||||
			key, err := ioutil.ReadFile(dir + "/key.aes")
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatal().Err(err).Msg("Error reading key")
 | 
			
		||||
			}
 | 
			
		||||
			// 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
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/index", func(res http.ResponseWriter, req *http.Request) {
 | 
			
		||||
		// 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 = 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 {
 | 
			
		||||
	// Get server address by getting the IP without the port, and appending :9898
 | 
			
		||||
	serverAddr := strings.Split(senderAddr, ":")[0] + ":9898"
 | 
			
		||||
	// Create error variable
 | 
			
		||||
	var err error
 | 
			
		||||
	// Create connection variable
 | 
			
		||||
	var connection net.Conn
 | 
			
		||||
	// Until break
 | 
			
		||||
	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
 | 
			
		||||
		}
 | 
			
		||||
type Sender struct {
 | 
			
		||||
	RemoteAddr string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Sender) Get(endpoint string) (io.ReadCloser, int, error) {
 | 
			
		||||
	res, err := http.Get(c.RemoteAddr + endpoint)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, 0, err
 | 
			
		||||
	}
 | 
			
		||||
	// Returned created connection
 | 
			
		||||
	return connection
 | 
			
		||||
	return res.Body, res.StatusCode, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
func RecvFiles(connection net.Conn) {
 | 
			
		||||
func RecvFiles(sender *Sender) {
 | 
			
		||||
	// Use ConsoleWriter logger
 | 
			
		||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
			
		||||
	// Request index from sender
 | 
			
		||||
	_, 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')
 | 
			
		||||
	indexReader, code, err := sender.Get("/index")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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 procMessage[0] != "OK" {
 | 
			
		||||
	if code != http.StatusOK {
 | 
			
		||||
		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
 | 
			
		||||
	index := strings.Split(strings.TrimSpace(procMessage[1]), "|")
 | 
			
		||||
	index := strings.Split(strings.TrimSpace(string(indexBytes)), "|")
 | 
			
		||||
	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
 | 
			
		||||
		message, err := bufio.NewReader(connection).ReadString('\n')
 | 
			
		||||
		fileData, code, err := sender.Get("/" + file)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatal().Err(err).Msg("Error getting file")
 | 
			
		||||
		}
 | 
			
		||||
		// Process received message
 | 
			
		||||
		procMessage := strings.Split(message, ";")
 | 
			
		||||
		// If non-ok code returned
 | 
			
		||||
		if procMessage[0] != "OK" {
 | 
			
		||||
		if code != http.StatusOK {
 | 
			
		||||
			// 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
 | 
			
		||||
		} else {
 | 
			
		||||
			// Create new file at index filepath
 | 
			
		||||
@@ -263,13 +174,8 @@ func RecvFiles(connection net.Conn) {
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				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
 | 
			
		||||
			bytesWritten, err := io.Copy(newFile, bytes.NewBuffer(fileData))
 | 
			
		||||
			bytesWritten, err := io.Copy(newFile, fileData)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatal().Err(err).Msg("Error writing to file")
 | 
			
		||||
			}
 | 
			
		||||
@@ -282,9 +188,6 @@ func RecvFiles(connection net.Conn) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Send stop signal to sender
 | 
			
		||||
func SendSrvStopSignal(connection net.Conn) {
 | 
			
		||||
	// Send stop signal to connection
 | 
			
		||||
	_, _ = fmt.Fprintln(connection, "stop;")
 | 
			
		||||
	// Close connection
 | 
			
		||||
	_ = connection.Close()
 | 
			
		||||
func SendSrvStopSignal(sender *Sender) {
 | 
			
		||||
	_, _, _ = sender.Get("/stop")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -3,12 +3,12 @@ module opensend
 | 
			
		||||
go 1.15
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	ekyu.moe/base91 v0.2.3
 | 
			
		||||
	github.com/grandcat/zeroconf v1.0.0
 | 
			
		||||
	github.com/klauspost/compress v1.11.3
 | 
			
		||||
	github.com/pelletier/go-toml v1.8.1
 | 
			
		||||
	github.com/pkg/browser v0.0.0-20201112035734-206646e67786
 | 
			
		||||
	github.com/rs/zerolog v1.20.0
 | 
			
		||||
	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
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
								
							@@ -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/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
 | 
			
		||||
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
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.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 | 
			
		||||
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/zerolog v1.20.0 h1:38k9hgtUBdxFwE34yS8rTHmHBa4eN16E4DJlv177LNs=
 | 
			
		||||
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/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/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
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/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=
 | 
			
		||||
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=
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								keyCrypto.go
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								keyCrypto.go
									
									
									
									
									
								
							@@ -17,16 +17,15 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"crypto/rsa"
 | 
			
		||||
	"crypto/sha256"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/rs/zerolog"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Generate RSA keypair
 | 
			
		||||
@@ -45,25 +44,18 @@ func GenerateRSAKeypair() (*rsa.PrivateKey, *rsa.PublicKey) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get public key from sender
 | 
			
		||||
func GetKey(connection net.Conn) []byte {
 | 
			
		||||
func GetKey(sender *Sender) []byte {
 | 
			
		||||
	// Use ConsoleWriter logger
 | 
			
		||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
			
		||||
	// Send key request to connection
 | 
			
		||||
	_, err := fmt.Fprintln(connection, "key;")
 | 
			
		||||
	keyReader, code, err := sender.Get("/key")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		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 procMessage[0] == "OK" {
 | 
			
		||||
		// Decode received safe base91 string into key
 | 
			
		||||
		key, err := DecodeSafeString(procMessage[1])
 | 
			
		||||
	if code == http.StatusOK {
 | 
			
		||||
		// Read received bytes into key
 | 
			
		||||
		key, err := ioutil.ReadAll(keyReader)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatal().Err(err).Msg("Error reading key")
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								main.go
									
									
									
									
									
								
							@@ -20,10 +20,7 @@ import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"crypto/rand"
 | 
			
		||||
	"encoding/hex"
 | 
			
		||||
	flag "github.com/spf13/pflag"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/rs/zerolog"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
@@ -31,6 +28,10 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/rs/zerolog"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	flag "github.com/spf13/pflag"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var workDir *string
 | 
			
		||||
@@ -106,19 +107,16 @@ func main() {
 | 
			
		||||
	// Create channel for signals
 | 
			
		||||
	sig := make(chan os.Signal, 1)
 | 
			
		||||
	// 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
 | 
			
		||||
	go func() {
 | 
			
		||||
		select {
 | 
			
		||||
		// Wait for sig to be written
 | 
			
		||||
		case <-sig:
 | 
			
		||||
			// Warn user that a signal has been received and that opensend is shutting down
 | 
			
		||||
			log.Warn().Msg("Signal received. Shutting down.")
 | 
			
		||||
			// Remove opensend directory to avoid future conflicts
 | 
			
		||||
			_ = os.RemoveAll(*workDir)
 | 
			
		||||
			// Exit with code 0
 | 
			
		||||
			os.Exit(0)
 | 
			
		||||
		}
 | 
			
		||||
		signal := <-sig
 | 
			
		||||
		// Warn user that a signal has been received and that opensend is shutting down
 | 
			
		||||
		log.Warn().Str("signal", signal.String()).Msg("Signal received. Shutting down.")
 | 
			
		||||
		// Remove opensend directory to avoid future conflicts
 | 
			
		||||
		_ = os.RemoveAll(*workDir)
 | 
			
		||||
		// Exit with code 0
 | 
			
		||||
		os.Exit(0)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
	// Create opensend dir ignoring errors
 | 
			
		||||
@@ -228,7 +226,7 @@ func main() {
 | 
			
		||||
			// Notify user files are being received
 | 
			
		||||
			log.Info().Msg("Receiving files from server (This may take a while)")
 | 
			
		||||
			// Connect to sender's TCP socket
 | 
			
		||||
			connection := ConnectToSender(senderIP)
 | 
			
		||||
			connection := NewSender(senderIP)
 | 
			
		||||
			// Get files from sender and place them into the opensend directory
 | 
			
		||||
			RecvFiles(connection)
 | 
			
		||||
			// Get encrypted shared key from sender
 | 
			
		||||
@@ -244,10 +242,10 @@ func main() {
 | 
			
		||||
			// Instantiate Config
 | 
			
		||||
			parameters := &Parameters{}
 | 
			
		||||
			// Read config file in opensend directory
 | 
			
		||||
			parameters.ReadFile(*workDir + "/parameters.json")
 | 
			
		||||
			parameters.ReadFile(*workDir + "/parameters.msgpack")
 | 
			
		||||
			// Notify user that action is being executed
 | 
			
		||||
			log.Info().Msg("Executing JSON action")
 | 
			
		||||
			// Execute JSON action using files within opensend directory
 | 
			
		||||
			log.Info().Msg("Executing action")
 | 
			
		||||
			// Execute MessagePack action using files within opensend directory
 | 
			
		||||
			parameters.ExecuteAction(*workDir, *destDir)
 | 
			
		||||
			// Remove opensend directory
 | 
			
		||||
			err := os.RemoveAll(*workDir)
 | 
			
		||||
@@ -276,13 +274,13 @@ func main() {
 | 
			
		||||
		// Notify user files are being received
 | 
			
		||||
		log.Info().Msg("Receiving files from server (This may take a while)")
 | 
			
		||||
		// Connect to sender's TCP socket
 | 
			
		||||
		connection := ConnectToSender(senderIP)
 | 
			
		||||
		sender := NewSender(senderIP)
 | 
			
		||||
		// Get files from sender and place them into the opensend directory
 | 
			
		||||
		RecvFiles(connection)
 | 
			
		||||
		RecvFiles(sender)
 | 
			
		||||
		// Get encrypted shared key from sender
 | 
			
		||||
		encryptedKey := GetKey(connection)
 | 
			
		||||
		encryptedKey := GetKey(sender)
 | 
			
		||||
		// Send stop signal to sender's HTTP server
 | 
			
		||||
		SendSrvStopSignal(connection)
 | 
			
		||||
		SendSrvStopSignal(sender)
 | 
			
		||||
		// Decrypt shared key
 | 
			
		||||
		sharedKey := DecryptKey(encryptedKey, privateKey)
 | 
			
		||||
		// Notify user file decryption is beginning
 | 
			
		||||
@@ -292,10 +290,10 @@ func main() {
 | 
			
		||||
		// Instantiate Config
 | 
			
		||||
		parameters := &Parameters{}
 | 
			
		||||
		// Read config file in opensend directory
 | 
			
		||||
		parameters.ReadFile(*workDir + "/parameters.json")
 | 
			
		||||
		parameters.ReadFile(*workDir + "/parameters.msgpack")
 | 
			
		||||
		// Notify user that action is being executed
 | 
			
		||||
		log.Info().Msg("Executing JSON action")
 | 
			
		||||
		// Execute JSON action using files within opensend directory
 | 
			
		||||
		log.Info().Msg("Executing Action")
 | 
			
		||||
		// Execute MessagePack action using files within opensend directory
 | 
			
		||||
		parameters.ExecuteAction(*workDir, *destDir)
 | 
			
		||||
	} else {
 | 
			
		||||
		flag.Usage()
 | 
			
		||||
 
 | 
			
		||||
@@ -18,10 +18,6 @@ package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"archive/tar"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"github.com/pkg/browser"
 | 
			
		||||
	"github.com/rs/zerolog"
 | 
			
		||||
	"github.com/rs/zerolog/log"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"net/url"
 | 
			
		||||
@@ -29,6 +25,11 @@ import (
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"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
 | 
			
		||||
@@ -67,24 +68,24 @@ func (parameters *Parameters) CreateFile(dir string) {
 | 
			
		||||
	// Use ConsoleWriter logger
 | 
			
		||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
			
		||||
	// Create parameters file at given directory
 | 
			
		||||
	configFile, err := os.Create(dir + "/parameters.json")
 | 
			
		||||
	configFile, err := os.Create(dir + "/parameters.msgpack")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal().Err(err).Msg("Error creating parameters file")
 | 
			
		||||
	}
 | 
			
		||||
	// Close parameters file at the end of this function
 | 
			
		||||
	defer configFile.Close()
 | 
			
		||||
	// Marshal given Parameters struct into a []byte
 | 
			
		||||
	jsonData, err := json.Marshal(parameters)
 | 
			
		||||
	MessagePackData, err := msgpack.Marshal(parameters)
 | 
			
		||||
	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
 | 
			
		||||
	bytesWritten, err := configFile.Write(jsonData)
 | 
			
		||||
	bytesWritten, err := configFile.Write(MessagePackData)
 | 
			
		||||
	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.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
 | 
			
		||||
@@ -178,10 +179,10 @@ func (parameters *Parameters) ReadFile(filePath string) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal().Err(err).Msg("Error reading parameters file")
 | 
			
		||||
	}
 | 
			
		||||
	// Unmarshal data from JSON into parameters struct
 | 
			
		||||
	err = json.Unmarshal(fileData, parameters)
 | 
			
		||||
	// Unmarshal data from MessagePack into parameters struct
 | 
			
		||||
	err = msgpack.Unmarshal(fileData, parameters)
 | 
			
		||||
	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
 | 
			
		||||
			} else if err != nil {
 | 
			
		||||
				log.Fatal().Err(err).Msg("Error unarchiving tar archive")
 | 
			
		||||
			// If nil header
 | 
			
		||||
				// If nil header
 | 
			
		||||
			} else if header == nil {
 | 
			
		||||
				// Skip
 | 
			
		||||
				continue
 | 
			
		||||
		Reference in New Issue
	
	Block a user