This commit is contained in:
		
							
								
								
									
										111
									
								
								config.go
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								config.go
									
									
									
									
									
								
							@@ -26,7 +26,7 @@ func NewConfig(actionType string, actionData string) *Config {
 | 
				
			|||||||
	return &Config{ActionType: actionType, ActionData: actionData}
 | 
						return &Config{ActionType: actionType, ActionData: actionData}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (config *Config) Validate()  {
 | 
					func (config *Config) Validate() {
 | 
				
			||||||
	if config.ActionType == "url" {
 | 
						if config.ActionType == "url" {
 | 
				
			||||||
		// Parse URL in config
 | 
							// Parse URL in config
 | 
				
			||||||
		urlParser, err := url.Parse(config.ActionData)
 | 
							urlParser, err := url.Parse(config.ActionData)
 | 
				
			||||||
@@ -52,15 +52,21 @@ func (config *Config) CreateFile(dir string) {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Create config file at given directory
 | 
						// Create config file at given directory
 | 
				
			||||||
	configFile, err := os.Create(dir + "/config.json")
 | 
						configFile, err := os.Create(dir + "/config.json")
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating config file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating config file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Close config file at the end of this function
 | 
						// Close config file at the end of this function
 | 
				
			||||||
	defer configFile.Close()
 | 
						defer configFile.Close()
 | 
				
			||||||
	// Marshal given Config struct into a []byte
 | 
						// Marshal given Config struct into a []byte
 | 
				
			||||||
	jsonData, err := json.Marshal(config)
 | 
						jsonData, err := json.Marshal(config)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error encoding JSON") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error encoding JSON")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Write []byte to previously created config file
 | 
						// Write []byte to previously created config file
 | 
				
			||||||
	bytesWritten, err := configFile.Write(jsonData)
 | 
						bytesWritten, err := configFile.Write(jsonData)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error writing JSON to file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error writing JSON to file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Log bytes written
 | 
						// Log bytes written
 | 
				
			||||||
	log.Info().Str("file", "config.json").Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
 | 
						log.Info().Str("file", "config.json").Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -73,23 +79,31 @@ func (config *Config) CollectFiles(dir string) {
 | 
				
			|||||||
	if config.ActionType == "file" {
 | 
						if config.ActionType == "file" {
 | 
				
			||||||
		// Open file path in config.ActionData
 | 
							// Open file path in config.ActionData
 | 
				
			||||||
		src, err := os.Open(config.ActionData)
 | 
							src, err := os.Open(config.ActionData)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error opening file from config") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error opening file from config")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Close source file at the end of this function
 | 
							// Close source file at the end of this function
 | 
				
			||||||
		defer src.Close()
 | 
							defer src.Close()
 | 
				
			||||||
		// Create new file with the same name at given directory
 | 
							// Create new file with the same name at given directory
 | 
				
			||||||
		dst, err := os.Create(dir + "/" + filepath.Base(config.ActionData))
 | 
							dst, err := os.Create(dir + "/" + filepath.Base(config.ActionData))
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Close new file at the end of this function
 | 
							// Close new file at the end of this function
 | 
				
			||||||
		defer dst.Close()
 | 
							defer dst.Close()
 | 
				
			||||||
		// Copy data from source file to destination file
 | 
							// Copy data from source file to destination file
 | 
				
			||||||
		_, err = io.Copy(dst, src)
 | 
							_, err = io.Copy(dst, src)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error copying data to file") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error copying data to file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Replace file path in config.ActionData with file name
 | 
							// Replace file path in config.ActionData with file name
 | 
				
			||||||
		config.ActionData = filepath.Base(config.ActionData)
 | 
							config.ActionData = filepath.Base(config.ActionData)
 | 
				
			||||||
	} else if config.ActionType == "dir" {
 | 
						} else if config.ActionType == "dir" {
 | 
				
			||||||
		// Create tar archive
 | 
							// Create tar archive
 | 
				
			||||||
		tarFile, err := os.Create(dir + "/" + filepath.Base(config.ActionData) + ".tar")
 | 
							tarFile, err := os.Create(dir + "/" + filepath.Base(config.ActionData) + ".tar")
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Close tar file at the end of this function
 | 
							// Close tar file at the end of this function
 | 
				
			||||||
		defer tarFile.Close()
 | 
							defer tarFile.Close()
 | 
				
			||||||
		// Create writer for tar archive
 | 
							// Create writer for tar archive
 | 
				
			||||||
@@ -99,27 +113,41 @@ func (config *Config) CollectFiles(dir string) {
 | 
				
			|||||||
		// Walk given directory
 | 
							// Walk given directory
 | 
				
			||||||
		err = filepath.Walk(config.ActionData, func(path string, info os.FileInfo, err error) error {
 | 
							err = filepath.Walk(config.ActionData, func(path string, info os.FileInfo, err error) error {
 | 
				
			||||||
			// Return if error walking
 | 
								// Return if error walking
 | 
				
			||||||
			if err != nil { return err }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Skip if file is not normal mode
 | 
								// Skip if file is not normal mode
 | 
				
			||||||
			if !info.Mode().IsRegular() { return nil }
 | 
								if !info.Mode().IsRegular() {
 | 
				
			||||||
 | 
									return nil
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Create tar header for file
 | 
								// Create tar header for file
 | 
				
			||||||
			header, err := tar.FileInfoHeader(info, info.Name())
 | 
								header, err := tar.FileInfoHeader(info, info.Name())
 | 
				
			||||||
			if err != nil { return err }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Change header name to reflect decompressed filepath
 | 
								// Change header name to reflect decompressed filepath
 | 
				
			||||||
			header.Name = strings.TrimPrefix(strings.ReplaceAll(path, config.ActionData, ""), string(filepath.Separator))
 | 
								header.Name = strings.TrimPrefix(strings.ReplaceAll(path, config.ActionData, ""), string(filepath.Separator))
 | 
				
			||||||
			// Write header to archive
 | 
								// Write header to archive
 | 
				
			||||||
			if err := tarArchiver.WriteHeader(header); err != nil { return err }
 | 
								if err := tarArchiver.WriteHeader(header); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Open source file
 | 
								// Open source file
 | 
				
			||||||
			src, err := os.Open(path)
 | 
								src, err := os.Open(path)
 | 
				
			||||||
			if err != nil { return err }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Close source file at the end of this function
 | 
								// Close source file at the end of this function
 | 
				
			||||||
			defer src.Close()
 | 
								defer src.Close()
 | 
				
			||||||
			// Copy source bytes to tar archive
 | 
								// Copy source bytes to tar archive
 | 
				
			||||||
			if _, err := io.Copy(tarArchiver, src); err != nil { return err }
 | 
								if _, err := io.Copy(tarArchiver, src); err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Return at the end of the function
 | 
								// Return at the end of the function
 | 
				
			||||||
			return nil
 | 
								return nil
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error creating tar archive") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error creating tar archive")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Set config data to base path for receiver
 | 
							// Set config data to base path for receiver
 | 
				
			||||||
		config.ActionData = filepath.Base(config.ActionData)
 | 
							config.ActionData = filepath.Base(config.ActionData)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -131,10 +159,14 @@ func (config *Config) ReadFile(filePath string) {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Read file at filePath
 | 
						// Read file at filePath
 | 
				
			||||||
	fileData, err := ioutil.ReadFile(filePath)
 | 
						fileData, err := ioutil.ReadFile(filePath)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error reading config file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error reading config file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Unmarshal data from JSON into config struct
 | 
						// Unmarshal data from JSON into config struct
 | 
				
			||||||
	err = json.Unmarshal(fileData, config)
 | 
						err = json.Unmarshal(fileData, config)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error decoding JSON") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error decoding JSON")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Execute action specified in config
 | 
					// Execute action specified in config
 | 
				
			||||||
@@ -145,18 +177,24 @@ func (config *Config) ExecuteAction(srcDir string, destDir string) {
 | 
				
			|||||||
	if config.ActionType == "file" {
 | 
						if config.ActionType == "file" {
 | 
				
			||||||
		// Open file from config at given directory
 | 
							// Open file from config at given directory
 | 
				
			||||||
		src, err := os.Open(srcDir + "/" + config.ActionData)
 | 
							src, err := os.Open(srcDir + "/" + config.ActionData)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error reading file from config") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error reading file from config")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Close source file at the end of this function
 | 
							// Close source file at the end of this function
 | 
				
			||||||
		defer src.Close()
 | 
							defer src.Close()
 | 
				
			||||||
		// Create file in user's Downloads directory
 | 
							// Create file in user's Downloads directory
 | 
				
			||||||
		dst, err := os.Create(filepath.Clean(destDir) + "/" + config.ActionData)
 | 
							dst, err := os.Create(filepath.Clean(destDir) + "/" + config.ActionData)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Close destination file at the end of this function
 | 
							// Close destination file at the end of this function
 | 
				
			||||||
		defer dst.Close()
 | 
							defer dst.Close()
 | 
				
			||||||
		// Copy data from source file to destination file
 | 
							// Copy data from source file to destination file
 | 
				
			||||||
		_, err = io.Copy(dst, src)
 | 
							_, err = io.Copy(dst, src)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error copying data to file") }
 | 
							if err != nil {
 | 
				
			||||||
	// If action is url
 | 
								log.Fatal().Err(err).Msg("Error copying data to file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// If action is url
 | 
				
			||||||
	} else if config.ActionType == "url" {
 | 
						} else if config.ActionType == "url" {
 | 
				
			||||||
		// Parse received URL
 | 
							// Parse received URL
 | 
				
			||||||
		urlParser, err := url.Parse(config.ActionData)
 | 
							urlParser, err := url.Parse(config.ActionData)
 | 
				
			||||||
@@ -164,34 +202,41 @@ func (config *Config) ExecuteAction(srcDir string, destDir string) {
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			// Alert user of invalid url
 | 
								// Alert user of invalid url
 | 
				
			||||||
			log.Fatal().Err(err).Msg("Invalid URL")
 | 
								log.Fatal().Err(err).Msg("Invalid URL")
 | 
				
			||||||
		// If scheme is not detected
 | 
								// If scheme is not detected
 | 
				
			||||||
		} else if urlParser.Scheme == "" {
 | 
							} else if urlParser.Scheme == "" {
 | 
				
			||||||
			// Alert user of invalid scheme
 | 
								// Alert user of invalid scheme
 | 
				
			||||||
			log.Fatal().Msg("Invalid URL scheme")
 | 
								log.Fatal().Msg("Invalid URL scheme")
 | 
				
			||||||
		// If host is not detected
 | 
								// If host is not detected
 | 
				
			||||||
		} else if urlParser.Host == "" {
 | 
							} else if urlParser.Host == "" {
 | 
				
			||||||
			// Alert user of invalid host
 | 
								// Alert user of invalid host
 | 
				
			||||||
			log.Fatal().Msg("Invalid URL host")
 | 
								log.Fatal().Msg("Invalid URL host")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Attempt to open URL in browser
 | 
							// Attempt to open URL in browser
 | 
				
			||||||
		err = browser.OpenURL(config.ActionData)
 | 
							err = browser.OpenURL(config.ActionData)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error opening browser") }
 | 
							if err != nil {
 | 
				
			||||||
	// If action is dir
 | 
								log.Fatal().Err(err).Msg("Error opening browser")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// If action is dir
 | 
				
			||||||
	} else if config.ActionType == "dir" {
 | 
						} else if config.ActionType == "dir" {
 | 
				
			||||||
		// Set destination directory to ~/Downloads/{dir name}
 | 
							// Set destination directory to ~/Downloads/{dir name}
 | 
				
			||||||
		dstDir := filepath.Clean(destDir) + "/" + config.ActionData
 | 
							dstDir := filepath.Clean(destDir) + "/" + config.ActionData
 | 
				
			||||||
		// Try to create destination directory
 | 
							// Try to create destination directory
 | 
				
			||||||
		err := os.MkdirAll(dstDir, 0755)
 | 
							err := os.MkdirAll(dstDir, 0755)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error creating directory") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error creating directory")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Try to open tar archive file
 | 
							// Try to open tar archive file
 | 
				
			||||||
		tarFile, err := os.Open(srcDir + "/" + config.ActionData + ".tar")
 | 
							tarFile, err := os.Open(srcDir + "/" + config.ActionData + ".tar")
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error opening tar archive") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error opening tar archive")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Close tar archive file at the end of this function
 | 
							// Close tar archive file at the end of this function
 | 
				
			||||||
		defer tarFile.Close()
 | 
							defer tarFile.Close()
 | 
				
			||||||
		// Create tar reader to unarchive tar archive
 | 
							// Create tar reader to unarchive tar archive
 | 
				
			||||||
		tarUnarchiver := tar.NewReader(tarFile)
 | 
							tarUnarchiver := tar.NewReader(tarFile)
 | 
				
			||||||
		// Loop to recursively unarchive tar file
 | 
							// Loop to recursively unarchive tar file
 | 
				
			||||||
		unarchiveLoop: for {
 | 
						unarchiveLoop:
 | 
				
			||||||
 | 
							for {
 | 
				
			||||||
			// Jump to next header in tar archive
 | 
								// Jump to next header in tar archive
 | 
				
			||||||
			header, err := tarUnarchiver.Next()
 | 
								header, err := tarUnarchiver.Next()
 | 
				
			||||||
			switch {
 | 
								switch {
 | 
				
			||||||
@@ -215,13 +260,17 @@ func (config *Config) ExecuteAction(srcDir string, destDir string) {
 | 
				
			|||||||
				_ = os.MkdirAll(filepath.Dir(targetPath), 0755)
 | 
									_ = os.MkdirAll(filepath.Dir(targetPath), 0755)
 | 
				
			||||||
				// Create file with mode contained in header at target path
 | 
									// Create file with mode contained in header at target path
 | 
				
			||||||
				dstFile, err := os.OpenFile(targetPath, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
 | 
									dstFile, err := os.OpenFile(targetPath, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
 | 
				
			||||||
				if err != nil { log.Fatal().Err(err).Msg("Error creating file during unarchiving") }
 | 
									if err != nil {
 | 
				
			||||||
 | 
										log.Fatal().Err(err).Msg("Error creating file during unarchiving")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				// Copy data from tar archive into file
 | 
									// Copy data from tar archive into file
 | 
				
			||||||
				_, err = io.Copy(dstFile, tarUnarchiver)
 | 
									_, err = io.Copy(dstFile, tarUnarchiver)
 | 
				
			||||||
				if err != nil { log.Fatal().Err(err).Msg("Error copying data to file") }
 | 
									if err != nil {
 | 
				
			||||||
 | 
										log.Fatal().Err(err).Msg("Error copying data to file")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	// Catchall
 | 
							// Catchall
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// Log unknown action type
 | 
							// Log unknown action type
 | 
				
			||||||
		log.Fatal().Msg("Unknown action type " + config.ActionType)
 | 
							log.Fatal().Msg("Unknown action type " + config.ActionType)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,9 @@ func DiscoverReceivers() ([]string, []string) {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Create zeroconf resolver
 | 
						// Create zeroconf resolver
 | 
				
			||||||
	resolver, err := zeroconf.NewResolver(nil)
 | 
						resolver, err := zeroconf.NewResolver(nil)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating zeroconf resolver") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating zeroconf resolver")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create channel for zeroconf entries
 | 
						// Create channel for zeroconf entries
 | 
				
			||||||
	entries := make(chan *zeroconf.ServiceEntry)
 | 
						entries := make(chan *zeroconf.ServiceEntry)
 | 
				
			||||||
	// Create slice to store hostnames of discovered receivers
 | 
						// Create slice to store hostnames of discovered receivers
 | 
				
			||||||
@@ -39,7 +41,9 @@ func DiscoverReceivers() ([]string, []string) {
 | 
				
			|||||||
	defer cancel()
 | 
						defer cancel()
 | 
				
			||||||
	// Browse for mDNS entries
 | 
						// Browse for mDNS entries
 | 
				
			||||||
	err = resolver.Browse(ctx, "_opensend._tcp", "local.", entries)
 | 
						err = resolver.Browse(ctx, "_opensend._tcp", "local.", entries)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error browsing zeroconf services") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error browsing zeroconf services")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Send Done signal to context
 | 
						// Send Done signal to context
 | 
				
			||||||
	<-ctx.Done()
 | 
						<-ctx.Done()
 | 
				
			||||||
@@ -53,7 +57,9 @@ func RegisterService() func() {
 | 
				
			|||||||
	hostname, _ := os.Hostname()
 | 
						hostname, _ := os.Hostname()
 | 
				
			||||||
	// Register zeroconf service {hostname}._opensend._tcp.local.
 | 
						// Register zeroconf service {hostname}._opensend._tcp.local.
 | 
				
			||||||
	server, err := zeroconf.Register(hostname, "_opensend._tcp", "local.", 9797, []string{"txtv=0", "lo=1", "la=2"}, nil)
 | 
						server, err := zeroconf.Register(hostname, "_opensend._tcp", "local.", 9797, []string{"txtv=0", "lo=1", "la=2"}, nil)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error registering zeroconf service") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error registering zeroconf service")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Return server.Shutdown() function to allow for shutdown in main()
 | 
						// Return server.Shutdown() function to allow for shutdown in main()
 | 
				
			||||||
	return server.Shutdown
 | 
						return server.Shutdown
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -24,20 +24,28 @@ func CompressAndEncryptFile(filePath string, newFilePath string, sharedKey strin
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Read data from file
 | 
						// Read data from file
 | 
				
			||||||
	file, err := os.Open(filePath)
 | 
						file, err := os.Open(filePath)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error opening file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error opening file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create buffer for compressed data
 | 
						// Create buffer for compressed data
 | 
				
			||||||
	compressedBuffer := new(bytes.Buffer)
 | 
						compressedBuffer := new(bytes.Buffer)
 | 
				
			||||||
	// Create Zstd encoder
 | 
						// Create Zstd encoder
 | 
				
			||||||
	zstdEncoder, err := zstd.NewWriter(compressedBuffer)
 | 
						zstdEncoder, err := zstd.NewWriter(compressedBuffer)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating Zstd encoder") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating Zstd encoder")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Copy file data to Zstd encoder
 | 
						// Copy file data to Zstd encoder
 | 
				
			||||||
	_, err = io.Copy(zstdEncoder, file)
 | 
						_, err = io.Copy(zstdEncoder, file)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error reading file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error reading file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Close Zstd encoder
 | 
						// Close Zstd encoder
 | 
				
			||||||
	zstdEncoder.Close()
 | 
						zstdEncoder.Close()
 | 
				
			||||||
	// Read compressed data into data variable
 | 
						// Read compressed data into data variable
 | 
				
			||||||
	data, err := ioutil.ReadAll(compressedBuffer)
 | 
						data, err := ioutil.ReadAll(compressedBuffer)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error reading compressed buffer") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error reading compressed buffer")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create md5 hash of password in order to make it the required size
 | 
						// Create md5 hash of password in order to make it the required size
 | 
				
			||||||
	md5Hash := md5.New()
 | 
						md5Hash := md5.New()
 | 
				
			||||||
	md5Hash.Write([]byte(sharedKey))
 | 
						md5Hash.Write([]byte(sharedKey))
 | 
				
			||||||
@@ -45,25 +53,35 @@ func CompressAndEncryptFile(filePath string, newFilePath string, sharedKey strin
 | 
				
			|||||||
	hashedKey := hex.EncodeToString(md5Hash.Sum(nil))
 | 
						hashedKey := hex.EncodeToString(md5Hash.Sum(nil))
 | 
				
			||||||
	// Create new AES cipher
 | 
						// Create new AES cipher
 | 
				
			||||||
	block, err := aes.NewCipher([]byte(hashedKey))
 | 
						block, err := aes.NewCipher([]byte(hashedKey))
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating AES cipher") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating AES cipher")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create GCM for AES cipher
 | 
						// Create GCM for AES cipher
 | 
				
			||||||
	gcm, err := cipher.NewGCM(block)
 | 
						gcm, err := cipher.NewGCM(block)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating GCM") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating GCM")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Make byte slice for nonce
 | 
						// Make byte slice for nonce
 | 
				
			||||||
	nonce := make([]byte, gcm.NonceSize())
 | 
						nonce := make([]byte, gcm.NonceSize())
 | 
				
			||||||
	// Read random bytes into nonce slice
 | 
						// Read random bytes into nonce slice
 | 
				
			||||||
	_, err = io.ReadFull(rand.Reader, nonce)
 | 
						_, err = io.ReadFull(rand.Reader, nonce)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating nonce") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating nonce")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Encrypt data
 | 
						// Encrypt data
 | 
				
			||||||
	ciphertext := gcm.Seal(nonce, nonce, data, nil)
 | 
						ciphertext := gcm.Seal(nonce, nonce, data, nil)
 | 
				
			||||||
	// Create new file
 | 
						// Create new file
 | 
				
			||||||
	newFile, err := os.Create(newFilePath)
 | 
						newFile, err := os.Create(newFilePath)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Defer file close
 | 
						// Defer file close
 | 
				
			||||||
	defer newFile.Close()
 | 
						defer newFile.Close()
 | 
				
			||||||
	// Write ciphertext to new file
 | 
						// Write ciphertext to new file
 | 
				
			||||||
	bytesWritten, err := newFile.Write(ciphertext)
 | 
						bytesWritten, err := newFile.Write(ciphertext)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error writing to file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error writing to file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Log bytes written and to which file
 | 
						// Log bytes written and to which file
 | 
				
			||||||
	log.Info().Str("file", filepath.Base(newFilePath)).Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
 | 
						log.Info().Str("file", filepath.Base(newFilePath)).Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -74,7 +92,9 @@ func DecryptAndDecompressFile(filePath string, newFilePath string, sharedKey str
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Read data from file
 | 
						// Read data from file
 | 
				
			||||||
	data, err := ioutil.ReadFile(filePath)
 | 
						data, err := ioutil.ReadFile(filePath)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error reading file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error reading file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create md5 hash of password in order to make it the required size
 | 
						// Create md5 hash of password in order to make it the required size
 | 
				
			||||||
	md5Hash := md5.New()
 | 
						md5Hash := md5.New()
 | 
				
			||||||
	md5Hash.Write([]byte(sharedKey))
 | 
						md5Hash.Write([]byte(sharedKey))
 | 
				
			||||||
@@ -83,25 +103,35 @@ func DecryptAndDecompressFile(filePath string, newFilePath string, sharedKey str
 | 
				
			|||||||
	block, _ := aes.NewCipher([]byte(hashedKey))
 | 
						block, _ := aes.NewCipher([]byte(hashedKey))
 | 
				
			||||||
	// Create GCM for AES cipher
 | 
						// Create GCM for AES cipher
 | 
				
			||||||
	gcm, err := cipher.NewGCM(block)
 | 
						gcm, err := cipher.NewGCM(block)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating GCM") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating GCM")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Get standard GCM nonce size
 | 
						// Get standard GCM nonce size
 | 
				
			||||||
	nonceSize := gcm.NonceSize()
 | 
						nonceSize := gcm.NonceSize()
 | 
				
			||||||
	// Get nonce and ciphertext from data
 | 
						// Get nonce and ciphertext from data
 | 
				
			||||||
	nonce, ciphertext := data[:nonceSize], data[nonceSize:]
 | 
						nonce, ciphertext := data[:nonceSize], data[nonceSize:]
 | 
				
			||||||
	// Decrypt data
 | 
						// Decrypt data
 | 
				
			||||||
	plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
 | 
						plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error decrypting data") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error decrypting data")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create new Zstd decoder
 | 
						// Create new Zstd decoder
 | 
				
			||||||
	zstdDecoder, err := zstd.NewReader(bytes.NewBuffer(plaintext))
 | 
						zstdDecoder, err := zstd.NewReader(bytes.NewBuffer(plaintext))
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating Zstd decoder") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating Zstd decoder")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create new file
 | 
						// Create new file
 | 
				
			||||||
	newFile, err := os.Create(newFilePath)
 | 
						newFile, err := os.Create(newFilePath)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Close new file at the end of this function
 | 
						// Close new file at the end of this function
 | 
				
			||||||
	defer newFile.Close()
 | 
						defer newFile.Close()
 | 
				
			||||||
	// Write decompressed plaintext to new file
 | 
						// Write decompressed plaintext to new file
 | 
				
			||||||
	bytesWritten, err := io.Copy(newFile, zstdDecoder)
 | 
						bytesWritten, err := io.Copy(newFile, zstdDecoder)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error writing to file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error writing to file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	zstdDecoder.Close()
 | 
						zstdDecoder.Close()
 | 
				
			||||||
	// Log bytes written and to which file
 | 
						// Log bytes written and to which file
 | 
				
			||||||
	log.Info().Str("file", filepath.Base(newFilePath)).Msg("Wrote " + strconv.Itoa(int(bytesWritten)) + " bytes")
 | 
						log.Info().Str("file", filepath.Base(newFilePath)).Msg("Wrote " + strconv.Itoa(int(bytesWritten)) + " bytes")
 | 
				
			||||||
@@ -114,19 +144,25 @@ func EncryptFiles(dir string, sharedKey string) {
 | 
				
			|||||||
	// Walk given directory
 | 
						// Walk given directory
 | 
				
			||||||
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
 | 
						err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
 | 
				
			||||||
		// If error reading, return err
 | 
							// If error reading, return err
 | 
				
			||||||
		if err != nil { return err }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// If file is not a directory and is not the key
 | 
							// If file is not a directory and is not the key
 | 
				
			||||||
		if !info.IsDir() && !strings.Contains(path, "key.aes"){
 | 
							if !info.IsDir() && !strings.Contains(path, "key.aes") {
 | 
				
			||||||
			// Compress and Encrypt the file using shared key, appending .zst.enc
 | 
								// Compress and Encrypt the file using shared key, appending .zst.enc
 | 
				
			||||||
			CompressAndEncryptFile(path, path + ".zst.enc", sharedKey)
 | 
								CompressAndEncryptFile(path, path+".zst.enc", sharedKey)
 | 
				
			||||||
			// Remove unencrypted file
 | 
								// Remove unencrypted file
 | 
				
			||||||
			err := os.Remove(path)
 | 
								err := os.Remove(path)
 | 
				
			||||||
			if err != nil { return err }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// Return nil if no error occurs
 | 
							// Return nil if no error occurs
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error encrypting files") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error encrypting files")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Decrypt files in given directory using shared key
 | 
					// Decrypt files in given directory using shared key
 | 
				
			||||||
@@ -136,7 +172,9 @@ func DecryptFiles(dir string, sharedKey string) {
 | 
				
			|||||||
	// Walk given directory
 | 
						// Walk given directory
 | 
				
			||||||
	err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
 | 
						err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
 | 
				
			||||||
		// If error reading, return err
 | 
							// If error reading, return err
 | 
				
			||||||
		if err != nil { return err }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// If file is not a directory and is encrypted
 | 
							// If file is not a directory and is encrypted
 | 
				
			||||||
		if !info.IsDir() && strings.Contains(path, ".enc") {
 | 
							if !info.IsDir() && strings.Contains(path, ".enc") {
 | 
				
			||||||
			// Decrypt and decompress the file using the shared key, removing .zst.enc
 | 
								// Decrypt and decompress the file using the shared key, removing .zst.enc
 | 
				
			||||||
@@ -145,5 +183,7 @@ func DecryptFiles(dir string, sharedKey string) {
 | 
				
			|||||||
		// Return nil if no errors occurred
 | 
							// Return nil if no errors occurred
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error decrypting files") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error decrypting files")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										93
									
								
								files.go
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								files.go
									
									
									
									
									
								
							@@ -23,12 +23,16 @@ func SaveEncryptedKey(encryptedKey []byte, filePath string) {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Create file at given file path
 | 
						// Create file at given file path
 | 
				
			||||||
	keyFile, err := os.Create(filePath)
 | 
						keyFile, err := os.Create(filePath)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Close file at the end of this function
 | 
						// Close file at the end of this function
 | 
				
			||||||
	defer keyFile.Close()
 | 
						defer keyFile.Close()
 | 
				
			||||||
	// Write encrypted key to file
 | 
						// Write encrypted key to file
 | 
				
			||||||
	bytesWritten, err := keyFile.Write(encryptedKey)
 | 
						bytesWritten, err := keyFile.Write(encryptedKey)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error writing key to file") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error writing key to file")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Log bytes written
 | 
						// Log bytes written
 | 
				
			||||||
	log.Info().Str("file", filepath.Base(filePath)).Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
 | 
						log.Info().Str("file", filepath.Base(filePath)).Msg("Wrote " + strconv.Itoa(bytesWritten) + " bytes")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -39,42 +43,59 @@ func SendFiles(dir string) {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Create TCP listener on port 9898
 | 
						// Create TCP listener on port 9898
 | 
				
			||||||
	listener, err := net.Listen("tcp", ":9898")
 | 
						listener, err := net.Listen("tcp", ":9898")
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error starting listener") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error starting listener")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Accept connection on listener
 | 
						// Accept connection on listener
 | 
				
			||||||
	connection, err := listener.Accept()
 | 
						connection, err := listener.Accept()
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error accepting connection") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error accepting connection")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Close connection at the end of this function
 | 
						// Close connection at the end of this function
 | 
				
			||||||
	defer connection.Close()
 | 
						defer connection.Close()
 | 
				
			||||||
	// Create for loop to listen for messages on connection
 | 
						// Create for loop to listen for messages on connection
 | 
				
			||||||
	connectionLoop: for {
 | 
					connectionLoop:
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
		// Use ConsoleWriter logger with TCPFatalHook
 | 
							// Use ConsoleWriter logger with TCPFatalHook
 | 
				
			||||||
		log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(TCPFatalHook{conn: connection})
 | 
							log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(TCPFatalHook{conn: connection})
 | 
				
			||||||
		// Attempt to read new message on connection
 | 
							// Attempt to read new message on connection
 | 
				
			||||||
		data, err := bufio.NewReader(connection).ReadString('\n')
 | 
							data, err := bufio.NewReader(connection).ReadString('\n')
 | 
				
			||||||
		// If no message detected, try again
 | 
							// If no message detected, try again
 | 
				
			||||||
		if err != nil && err.Error() == "EOF" { continue }
 | 
							if err != nil && err.Error() == "EOF" {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// If non-EOF error, fatally log
 | 
							// If non-EOF error, fatally log
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error reading data") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error reading data")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Process received data
 | 
							// Process received data
 | 
				
			||||||
		processedData := strings.Split(strings.TrimSpace(data), ";")
 | 
							processedData := strings.Split(strings.TrimSpace(data), ";")
 | 
				
			||||||
		// If processedData is empty, alert the user of invalid data
 | 
							// If processedData is empty, alert the user of invalid data
 | 
				
			||||||
		if len(processedData) < 1 { log.Fatal().Str("data", data).Msg("Received data invalid") }
 | 
							if len(processedData) < 1 {
 | 
				
			||||||
 | 
								log.Fatal().Str("data", data).Msg("Received data invalid")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		switch processedData[0] {
 | 
							switch processedData[0] {
 | 
				
			||||||
		case "key":
 | 
							case "key":
 | 
				
			||||||
			// Inform user client has requested key
 | 
								// Inform user client has requested key
 | 
				
			||||||
			log.Info().Msg("Key requested")
 | 
								log.Info().Msg("Key requested")
 | 
				
			||||||
			// Read saved key
 | 
								// Read saved key
 | 
				
			||||||
			key, err := ioutil.ReadFile(dir + "/key.aes")
 | 
								key, err := ioutil.ReadFile(dir + "/key.aes")
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error reading key") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error reading key")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Write saved key to ResponseWriter
 | 
								// Write saved key to ResponseWriter
 | 
				
			||||||
			_, err = fmt.Fprintln(connection, "OK;" + hex.EncodeToString(key) + ";")
 | 
								_, err = fmt.Fprintln(connection, "OK;"+hex.EncodeToString(key)+";")
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error writing response") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error writing response")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case "index":
 | 
							case "index":
 | 
				
			||||||
			// Inform user a client has requested the file index
 | 
								// Inform user a client has requested the file index
 | 
				
			||||||
			log.Info().Msg("Index requested")
 | 
								log.Info().Msg("Index requested")
 | 
				
			||||||
			// Get directory listing
 | 
								// Get directory listing
 | 
				
			||||||
			dirListing, err := ioutil.ReadDir(dir)
 | 
								dirListing, err := ioutil.ReadDir(dir)
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error reading directory") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error reading directory")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Create new slice to house filenames for index
 | 
								// Create new slice to house filenames for index
 | 
				
			||||||
			var indexSlice []string
 | 
								var indexSlice []string
 | 
				
			||||||
			// For each file in listing
 | 
								// For each file in listing
 | 
				
			||||||
@@ -88,8 +109,10 @@ func SendFiles(dir string) {
 | 
				
			|||||||
			// Join index slice into string
 | 
								// Join index slice into string
 | 
				
			||||||
			indexStr := strings.Join(indexSlice, "|")
 | 
								indexStr := strings.Join(indexSlice, "|")
 | 
				
			||||||
			// Write index to ResponseWriter
 | 
								// Write index to ResponseWriter
 | 
				
			||||||
			_, err = fmt.Fprintln(connection, "OK;" + indexStr + ";")
 | 
								_, err = fmt.Fprintln(connection, "OK;"+indexStr+";")
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error writing response") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error writing response")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case "file":
 | 
							case "file":
 | 
				
			||||||
			// If processedData only has one entry
 | 
								// If processedData only has one entry
 | 
				
			||||||
			if len(processedData) == 1 {
 | 
								if len(processedData) == 1 {
 | 
				
			||||||
@@ -114,8 +137,10 @@ func SendFiles(dir string) {
 | 
				
			|||||||
				log.Info().Str("file", file).Msg("File requested")
 | 
									log.Info().Str("file", file).Msg("File requested")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// Write file as hex to connection
 | 
								// Write file as hex to connection
 | 
				
			||||||
			_, err = fmt.Fprintln(connection, "OK;" + hex.EncodeToString(fileData) + ";")
 | 
								_, err = fmt.Fprintln(connection, "OK;"+hex.EncodeToString(fileData)+";")
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error writing response") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error writing response")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		case "stop":
 | 
							case "stop":
 | 
				
			||||||
			// Alert user that stop signal has been received
 | 
								// Alert user that stop signal has been received
 | 
				
			||||||
			log.Info().Msg("Received stop signal")
 | 
								log.Info().Msg("Received stop signal")
 | 
				
			||||||
@@ -162,40 +187,56 @@ func RecvFiles(connection net.Conn) {
 | 
				
			|||||||
	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
 | 
						// Request index from sender
 | 
				
			||||||
	_, err := fmt.Fprintln(connection, "index;")
 | 
						_, err := fmt.Fprintln(connection, "index;")
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error sending index request") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error sending index request")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Read received message
 | 
						// Read received message
 | 
				
			||||||
	message, err := bufio.NewReader(connection).ReadString('\n')
 | 
						message, err := bufio.NewReader(connection).ReadString('\n')
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error getting index") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error getting index")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Process received message
 | 
						// Process received message
 | 
				
			||||||
	procMessage := strings.Split(strings.TrimSpace(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" { log.Fatal().Err(err).Msg("Sender reported error") }
 | 
						if procMessage[0] != "OK" {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Sender reported error")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Get index from message
 | 
						// Get index from message
 | 
				
			||||||
	index := strings.Split(strings.TrimSpace(procMessage[1]), "|")
 | 
						index := strings.Split(strings.TrimSpace(procMessage[1]), "|")
 | 
				
			||||||
	for _, file := range index {
 | 
						for _, file := range index {
 | 
				
			||||||
		// Get current file in index
 | 
							// Get current file in index
 | 
				
			||||||
		_, err = fmt.Fprintln(connection, "file;" + file + ";")
 | 
							_, err = fmt.Fprintln(connection, "file;"+file+";")
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error sending file request") }
 | 
							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')
 | 
							message, err := bufio.NewReader(connection).ReadString('\n')
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error getting file") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error getting file")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Process received message
 | 
							// Process received message
 | 
				
			||||||
		procMessage := strings.Split(message, ";")
 | 
							procMessage := strings.Split(message, ";")
 | 
				
			||||||
		// If non-ok code returned
 | 
							// If non-ok code returned
 | 
				
			||||||
		if procMessage[0] != "OK" {
 | 
							if procMessage[0] != "OK" {
 | 
				
			||||||
			// fatally log
 | 
								// fatally log
 | 
				
			||||||
			log.Fatal().Err(err).Msg("Sender reported error")
 | 
								log.Fatal().Err(err).Msg("Sender reported error")
 | 
				
			||||||
		// Otherwise
 | 
								// Otherwise
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// Create new file at index filepath
 | 
								// Create new file at index filepath
 | 
				
			||||||
			newFile, err := os.Create(opensendDir + "/" + file)
 | 
								newFile, err := os.Create(opensendDir + "/" + file)
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error creating file") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error creating file")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Decode file data from hex string
 | 
								// Decode file data from hex string
 | 
				
			||||||
			fileData, err := hex.DecodeString(strings.TrimSpace(procMessage[1]))
 | 
								fileData, err := hex.DecodeString(strings.TrimSpace(procMessage[1]))
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error decoding hex") }
 | 
								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, bytes.NewBuffer(fileData))
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error writing to file") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error writing to file")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Log bytes written
 | 
								// Log bytes written
 | 
				
			||||||
			log.Info().Str("file", filepath.Base(file)).Msg("Wrote " + strconv.Itoa(int(bytesWritten)) + " bytes")
 | 
								log.Info().Str("file", filepath.Base(file)).Msg("Wrote " + strconv.Itoa(int(bytesWritten)) + " bytes")
 | 
				
			||||||
			// Close new file
 | 
								// Close new file
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								keyCrypto.go
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								keyCrypto.go
									
									
									
									
									
								
							@@ -20,7 +20,9 @@ func GenerateRSAKeypair() (*rsa.PrivateKey, *rsa.PublicKey) {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Generate private/public RSA keypair
 | 
						// Generate private/public RSA keypair
 | 
				
			||||||
	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
 | 
						privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error generating RSA keypair") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error generating RSA keypair")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Get public key
 | 
						// Get public key
 | 
				
			||||||
	publicKey := privateKey.PublicKey
 | 
						publicKey := privateKey.PublicKey
 | 
				
			||||||
	// Return keypair
 | 
						// Return keypair
 | 
				
			||||||
@@ -33,23 +35,31 @@ func GetKey(connection net.Conn) []byte {
 | 
				
			|||||||
	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;")
 | 
						_, err := fmt.Fprintln(connection, "key;")
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error sending key request") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error sending key request")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Read received message
 | 
						// Read received message
 | 
				
			||||||
	message, err := bufio.NewReader(connection).ReadString('\n')
 | 
						message, err := bufio.NewReader(connection).ReadString('\n')
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error getting key") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error getting key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Process received message
 | 
						// Process received message
 | 
				
			||||||
	procMessage := strings.Split(strings.TrimSpace(message), ";")
 | 
						procMessage := strings.Split(strings.TrimSpace(message), ";")
 | 
				
			||||||
	// If ok code returned
 | 
						// If ok code returned
 | 
				
			||||||
	if procMessage[0] == "OK" {
 | 
						if procMessage[0] == "OK" {
 | 
				
			||||||
		// Decode received hex string into key
 | 
							// Decode received hex string into key
 | 
				
			||||||
		key, err := hex.DecodeString(procMessage[1])
 | 
							key, err := hex.DecodeString(procMessage[1])
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error reading key") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error reading key")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Return key
 | 
							// Return key
 | 
				
			||||||
		return key
 | 
							return key
 | 
				
			||||||
	// Otherwise
 | 
							// Otherwise
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		// Fatally log
 | 
							// Fatally log
 | 
				
			||||||
		if err != nil { log.Fatal().Msg("Server reported error") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Msg("Server reported error")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Return nil if all else fails
 | 
						// Return nil if all else fails
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
@@ -61,7 +71,9 @@ func EncryptKey(sharedKey string, recvPubKey *rsa.PublicKey) []byte {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Encrypt shared key using RSA
 | 
						// Encrypt shared key using RSA
 | 
				
			||||||
	encryptedSharedKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, recvPubKey, []byte(sharedKey), nil)
 | 
						encryptedSharedKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, recvPubKey, []byte(sharedKey), nil)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error encrypting shared key") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error encrypting shared key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Return encrypted key
 | 
						// Return encrypted key
 | 
				
			||||||
	return encryptedSharedKey
 | 
						return encryptedSharedKey
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -70,7 +82,9 @@ func EncryptKey(sharedKey string, recvPubKey *rsa.PublicKey) []byte {
 | 
				
			|||||||
func DecryptKey(encryptedKey []byte, privateKey *rsa.PrivateKey) string {
 | 
					func DecryptKey(encryptedKey []byte, privateKey *rsa.PrivateKey) string {
 | 
				
			||||||
	// Decrypt shared key using RSA
 | 
						// Decrypt shared key using RSA
 | 
				
			||||||
	decryptedKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedKey, nil)
 | 
						decryptedKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedKey, nil)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error decrypting shared key") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error decrypting shared key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Get string of decrypted key
 | 
						// Get string of decrypted key
 | 
				
			||||||
	sharedKey := string(decryptedKey)
 | 
						sharedKey := string(decryptedKey)
 | 
				
			||||||
	// Return shared key
 | 
						// Return shared key
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,20 +15,26 @@ func ReceiverKeyExchange(key *rsa.PublicKey) string {
 | 
				
			|||||||
	log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
						log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr}).Hook(FatalHook{})
 | 
				
			||||||
	// Create TCP listener on port 9797
 | 
						// Create TCP listener on port 9797
 | 
				
			||||||
	listener, err := net.Listen("tcp", ":9797")
 | 
						listener, err := net.Listen("tcp", ":9797")
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error starting listener") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error starting listener")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create string for sender address
 | 
						// Create string for sender address
 | 
				
			||||||
	var senderAddr string
 | 
						var senderAddr string
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		// Accept connection on listener
 | 
							// Accept connection on listener
 | 
				
			||||||
		connection, err := listener.Accept()
 | 
							connection, err := listener.Accept()
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error accepting connections") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error accepting connections")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Get sender address and store it in senderAddr
 | 
							// Get sender address and store it in senderAddr
 | 
				
			||||||
		senderAddr = connection.RemoteAddr().String()
 | 
							senderAddr = connection.RemoteAddr().String()
 | 
				
			||||||
		// Create gob encoder with connection as io.Writer
 | 
							// Create gob encoder with connection as io.Writer
 | 
				
			||||||
		encoder := gob.NewEncoder(connection)
 | 
							encoder := gob.NewEncoder(connection)
 | 
				
			||||||
		// Encode key into connection
 | 
							// Encode key into connection
 | 
				
			||||||
		err = encoder.Encode(key)
 | 
							err = encoder.Encode(key)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error encoding key") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error encoding key")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return senderAddr
 | 
							return senderAddr
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -38,15 +44,19 @@ func SenderKeyExchange(receiverIP string) *rsa.PublicKey {
 | 
				
			|||||||
	// 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{})
 | 
				
			||||||
	// Connect to TCP socket on receiver IP port 9797
 | 
						// Connect to TCP socket on receiver IP port 9797
 | 
				
			||||||
	connection, err := net.Dial("tcp", receiverIP + ":9797")
 | 
						connection, err := net.Dial("tcp", receiverIP+":9797")
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error connecting to sender") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error connecting to sender")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Create gob decoder
 | 
						// Create gob decoder
 | 
				
			||||||
	decoder := gob.NewDecoder(connection)
 | 
						decoder := gob.NewDecoder(connection)
 | 
				
			||||||
	// Instantiate rsa.PublicKey struct
 | 
						// Instantiate rsa.PublicKey struct
 | 
				
			||||||
	recvPubKey := &rsa.PublicKey{}
 | 
						recvPubKey := &rsa.PublicKey{}
 | 
				
			||||||
	// Decode key
 | 
						// Decode key
 | 
				
			||||||
	err = decoder.Decode(recvPubKey)
 | 
						err = decoder.Decode(recvPubKey)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error decoding key") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error decoding key")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Return received key
 | 
						// Return received key
 | 
				
			||||||
	return recvPubKey
 | 
						return recvPubKey
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fatal hook to run in case of Fatal error
 | 
					// Fatal hook to run in case of Fatal error
 | 
				
			||||||
type FatalHook struct {}
 | 
					type FatalHook struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Run function on trigger
 | 
					// Run function on trigger
 | 
				
			||||||
func (hook FatalHook) Run(_ *zerolog.Event, level zerolog.Level, _ string) {
 | 
					func (hook FatalHook) Run(_ *zerolog.Event, level zerolog.Level, _ string) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										28
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								main.go
									
									
									
									
									
								
							@@ -25,7 +25,9 @@ func main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// Get user's home directory
 | 
						// Get user's home directory
 | 
				
			||||||
	homeDir, err := os.UserHomeDir()
 | 
						homeDir, err := os.UserHomeDir()
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error getting home directory") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error getting home directory")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Define opensend directory as ~/.opensend
 | 
						// Define opensend directory as ~/.opensend
 | 
				
			||||||
	opensendDir = homeDir + "/.opensend"
 | 
						opensendDir = homeDir + "/.opensend"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,11 +52,11 @@ func main() {
 | 
				
			|||||||
	// Create --send-to flag to send to a specific IP
 | 
						// Create --send-to flag to send to a specific IP
 | 
				
			||||||
	sendTo := flag.String("send-to", "", "Use IP address of receiver instead of mDNS")
 | 
						sendTo := flag.String("send-to", "", "Use IP address of receiver instead of mDNS")
 | 
				
			||||||
	// Create --dest-dir flag to save to a specified folder
 | 
						// Create --dest-dir flag to save to a specified folder
 | 
				
			||||||
	destDir := flag.String("dest-dir", homeDir + "/Downloads", "Destination directory for files or dirs sent over opensend")
 | 
						destDir := flag.String("dest-dir", homeDir+"/Downloads", "Destination directory for files or dirs sent over opensend")
 | 
				
			||||||
	// Create --skip-mdns to skip service registration
 | 
						// Create --skip-mdns to skip service registration
 | 
				
			||||||
	skipMdns := flag.Bool("skip-mdns", false, "Skip zeroconf service registration (use if mdns fails)")
 | 
						skipMdns := flag.Bool("skip-mdns", false, "Skip zeroconf service registration (use if mdns fails)")
 | 
				
			||||||
	// Create -t flag for type
 | 
						// Create -t flag for type
 | 
				
			||||||
	actionType := flag.String("t", "","Type of data being sent")
 | 
						actionType := flag.String("t", "", "Type of data being sent")
 | 
				
			||||||
	// Create -d flag for data
 | 
						// Create -d flag for data
 | 
				
			||||||
	actionData := flag.String("d", "", "Data to send")
 | 
						actionData := flag.String("d", "", "Data to send")
 | 
				
			||||||
	// Create -s flag for sending
 | 
						// Create -s flag for sending
 | 
				
			||||||
@@ -75,7 +77,9 @@ func main() {
 | 
				
			|||||||
		sharedKeyBytes := make([]byte, 32)
 | 
							sharedKeyBytes := make([]byte, 32)
 | 
				
			||||||
		// Read random bytes into buffer
 | 
							// Read random bytes into buffer
 | 
				
			||||||
		_, err := io.ReadFull(rand.Reader, sharedKeyBytes)
 | 
							_, err := io.ReadFull(rand.Reader, sharedKeyBytes)
 | 
				
			||||||
		if err != nil { log.Fatal().Err(err).Msg("Error generating random bytes") }
 | 
							if err != nil {
 | 
				
			||||||
 | 
								log.Fatal().Err(err).Msg("Error generating random bytes")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		// Encode random bytes to hexadecimal
 | 
							// Encode random bytes to hexadecimal
 | 
				
			||||||
		sharedKey := hex.EncodeToString(sharedKeyBytes)
 | 
							sharedKey := hex.EncodeToString(sharedKeyBytes)
 | 
				
			||||||
		// Notify user a key has been created
 | 
							// Notify user a key has been created
 | 
				
			||||||
@@ -88,7 +92,7 @@ func main() {
 | 
				
			|||||||
			log.Info().Msg("IP provided. Skipping discovery.")
 | 
								log.Info().Msg("IP provided. Skipping discovery.")
 | 
				
			||||||
			// Set chosen IP to provided
 | 
								// Set chosen IP to provided
 | 
				
			||||||
			choiceIP = *sendTo
 | 
								choiceIP = *sendTo
 | 
				
			||||||
		// Otherwise
 | 
								// Otherwise
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			// Notify user device discovery is beginning
 | 
								// Notify user device discovery is beginning
 | 
				
			||||||
			log.Info().Msg("Discovering opensend receivers")
 | 
								log.Info().Msg("Discovering opensend receivers")
 | 
				
			||||||
@@ -106,7 +110,9 @@ func main() {
 | 
				
			|||||||
			choiceStr, _ := reader.ReadString('\n')
 | 
								choiceStr, _ := reader.ReadString('\n')
 | 
				
			||||||
			// Convert input to int after trimming spaces
 | 
								// Convert input to int after trimming spaces
 | 
				
			||||||
			choiceInt, err := strconv.Atoi(strings.TrimSpace(choiceStr))
 | 
								choiceInt, err := strconv.Atoi(strings.TrimSpace(choiceStr))
 | 
				
			||||||
			if err != nil { log.Fatal().Err(err).Msg("Error converting choice to int") }
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Fatal().Err(err).Msg("Error converting choice to int")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			// Set choiceIndex to choiceInt-1 to allow for indexing
 | 
								// Set choiceIndex to choiceInt-1 to allow for indexing
 | 
				
			||||||
			choiceIndex := choiceInt - 1
 | 
								choiceIndex := choiceInt - 1
 | 
				
			||||||
			// Get IP of chosen receiver
 | 
								// Get IP of chosen receiver
 | 
				
			||||||
@@ -129,7 +135,7 @@ func main() {
 | 
				
			|||||||
		// Encrypt shared key using RSA public key
 | 
							// Encrypt shared key using RSA public key
 | 
				
			||||||
		key := EncryptKey(sharedKey, rawKey)
 | 
							key := EncryptKey(sharedKey, rawKey)
 | 
				
			||||||
		// Save encrypted key in opensend directory as key.aes
 | 
							// Save encrypted key in opensend directory as key.aes
 | 
				
			||||||
		SaveEncryptedKey(key, opensendDir + "/key.aes")
 | 
							SaveEncryptedKey(key, opensendDir+"/key.aes")
 | 
				
			||||||
		// Notify user file encryption is beginning
 | 
							// Notify user file encryption is beginning
 | 
				
			||||||
		log.Info().Msg("Encrypting files")
 | 
							log.Info().Msg("Encrypting files")
 | 
				
			||||||
		// Encrypt all files in opensend directory using shared key
 | 
							// Encrypt all files in opensend directory using shared key
 | 
				
			||||||
@@ -138,7 +144,7 @@ func main() {
 | 
				
			|||||||
		log.Info().Msg("Server started on port 9898")
 | 
							log.Info().Msg("Server started on port 9898")
 | 
				
			||||||
		// Send all files in opensend directory using an HTTP server on port 9898
 | 
							// Send all files in opensend directory using an HTTP server on port 9898
 | 
				
			||||||
		SendFiles(opensendDir)
 | 
							SendFiles(opensendDir)
 | 
				
			||||||
	// If -r given
 | 
							// If -r given
 | 
				
			||||||
	} else if *recvFlag {
 | 
						} else if *recvFlag {
 | 
				
			||||||
		// If --skip-mdns is not given
 | 
							// If --skip-mdns is not given
 | 
				
			||||||
		if !*skipMdns {
 | 
							if !*skipMdns {
 | 
				
			||||||
@@ -156,7 +162,7 @@ func main() {
 | 
				
			|||||||
		// Exchange keys with sender
 | 
							// Exchange keys with sender
 | 
				
			||||||
		senderIP := ReceiverKeyExchange(publicKey)
 | 
							senderIP := ReceiverKeyExchange(publicKey)
 | 
				
			||||||
		// Sleep 300ms to allow sender time to start HTTP server
 | 
							// Sleep 300ms to allow sender time to start HTTP server
 | 
				
			||||||
		time.Sleep(300*time.Millisecond)
 | 
							time.Sleep(300 * time.Millisecond)
 | 
				
			||||||
		// 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
 | 
				
			||||||
@@ -187,5 +193,7 @@ func main() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	// Remove opensend directory
 | 
						// Remove opensend directory
 | 
				
			||||||
	err = os.RemoveAll(opensendDir)
 | 
						err = os.RemoveAll(opensendDir)
 | 
				
			||||||
	if err != nil { log.Fatal().Err(err).Msg("Error removing opensend directory") }
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Fatal().Err(err).Msg("Error removing opensend directory")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user