diff --git a/cmd/mdrop-client/auth.go b/cmd/mdrop-client/auth.go index d6041da..4d40ca9 100644 --- a/cmd/mdrop-client/auth.go +++ b/cmd/mdrop-client/auth.go @@ -20,10 +20,12 @@ func AuthCommand(args []string) { flag := flag.NewFlagSet("mdrop auth", flag.ExitOnError) var ( - defaultInstance = flag.String("set-default", "", "Set default tunnel instance.") - list = flag.Bool("list", false, "Get list of tunnel instance") - help = flag.Bool("help", false, "Print this message") - deleteInstance = flag.String("delete", "", "Delete tunnel instance") + defaultInstance = flag.String("set-default", "", "Set default tunnel instance.") + list = flag.Bool("list", false, "Get list of tunnel instance") + help = flag.Bool("help", false, "Print this message") + deleteInstance = flag.String("delete", "", "Delete tunnel instance") + raw = flag.Bool("raw", false, "Print raw output of .mdrop file") + replace = flag.Bool("replace", false, "Replace .mdrop file with new config") ) flag.Parse(args) @@ -77,7 +79,16 @@ func AuthCommand(args []string) { } // Write config file - err = config.WriteConfig() + if *raw { + confString, err := config.WriteRawConfig(*replace) + if err != nil { + internal.PrintErrorWithExit("authWriteRawConfig", err, 1) + } + fmt.Println("\nCopy this secret below and paste it to ~/.mdrop") + fmt.Println(confString) + os.Exit(0) + } + err = config.WriteConfig(*replace) if err != nil { internal.PrintErrorWithExit("authWriteConfig", err, 1) } @@ -140,14 +151,14 @@ func deleteTunnelInstance(instanceName string) { func authPrompt() (config internal.ConfigFile, err error) { reader := bufio.NewReader(os.Stdin) - stdin := int(syscall.Stdin) + stdin := int(syscall.Stdin) oldState, err := term.GetState(stdin) if err != nil { return internal.ConfigFile{}, err } defer term.Restore(stdin, oldState) - sigch := make(chan os.Signal, 1) + sigch := make(chan os.Signal, 1) signal.Notify(sigch, os.Interrupt) go func() { for _ = range sigch { @@ -191,19 +202,19 @@ func authPrompt() (config internal.ConfigFile, err error) { } proxy = strings.Replace(proxy, "\n", "", -1) - fmt.Print("Private Key String [Set blank if none]: ") + fmt.Print("Private Key String [Set blank if none]: ") privateKeyByte, err := term.ReadPassword(stdin) if err != nil { return internal.ConfigFile{}, err } - privateKeyString := strings.Replace(string(privateKeyByte), "\n", "", -1) + privateKeyString := strings.Replace(string(privateKeyByte), "\n", "", -1) config = internal.ConfigFile{ Name: instanceName, Host: hostname, Port: portInt, Proxy: proxy, - Key: privateKeyString, + Key: privateKeyString, } return config, nil } diff --git a/cmd/mdrop-client/get_command.go b/cmd/mdrop-client/get_command.go index 136800a..3d86977 100644 --- a/cmd/mdrop-client/get_command.go +++ b/cmd/mdrop-client/get_command.go @@ -16,9 +16,9 @@ func GetCommand(args []string) { flag := flag.NewFlagSet("mdrop get", flag.ExitOnError) var ( - help = flag.Bool("help", false, "Print this message") + help = flag.Bool("help", false, "Print this message") fileNameOpt = flag.String("output", "", "Set file or directory output") - localPort = flag.Int("local-port", 6000, "Specified sender port remoted on local") + localPort = flag.Int("local-port", 6000, "Specified sender port remoted on local") ) flag.Parse(args) diff --git a/cmd/mdrop-client/get_download.go b/cmd/mdrop-client/get_download.go index 51e1e8a..c9134cb 100644 --- a/cmd/mdrop-client/get_download.go +++ b/cmd/mdrop-client/get_download.go @@ -79,7 +79,7 @@ func GetPrompt(localPort int, uuid string, fileNameOpt string, isSingleFile bool fileName = fileNameOpt } } - if fileStatus, _ := os.Stat(filePath+"/"+fileName); fileStatus != nil { + if fileStatus, _ := os.Stat(filePath + "/" + fileName); fileStatus != nil { fmt.Print("There's duplicate file. Action? [(R)eplace/R(e)name/(C)ancel] [Default: R] -> ") prompt, err := reader.ReadString('\n') if err != nil { @@ -90,7 +90,7 @@ func GetPrompt(localPort int, uuid string, fileNameOpt string, isSingleFile bool internal.PrintErrorWithExit("sendPromptCancel", errors.New("Canceled by action"), 0) } if strings.ToLower(prompt) == "e" { - fmt.Print("Change filename ["+fileName+"]: ") + fmt.Print("Change filename [" + fileName + "]: ") prompt, err = reader.ReadString('\n') if err != nil { internal.PrintErrorWithExit("sendPromptError", err, 1) @@ -133,7 +133,7 @@ func GetDownload(localPort int, uuid string, fileName string, fileNameOpt string filePath = fileNameOpt fmt.Println("Changing working directory to", filePath) } - filePath += "/"+fileName + filePath += "/" + fileName // Create file file, err := os.Create(filePath) diff --git a/cmd/mdrop-client/send_command.go b/cmd/mdrop-client/send_command.go index bccdad3..68d33ca 100644 --- a/cmd/mdrop-client/send_command.go +++ b/cmd/mdrop-client/send_command.go @@ -91,16 +91,16 @@ func SendCommand(args []string) { // Print token token, err := TokenTransferJSON{ - Host: config.Host, + Host: config.Host, RemotePort: remotePort, - Files: fileUUID, + Files: fileUUID, }.GenerateToken() if err != nil { errChan <- err } fmt.Print("\nPlease copy this token to the receiver.") - fmt.Print("\nToken: "+token+"\n\n") + fmt.Print("\nToken: " + token + "\n\n") fmt.Println("Spawning webserver...") err = SendWebserver(*localPort, file, fileUUID) diff --git a/cmd/mdrop-client/send_webserver.go b/cmd/mdrop-client/send_webserver.go index 0b3d9d5..7fb4357 100644 --- a/cmd/mdrop-client/send_webserver.go +++ b/cmd/mdrop-client/send_webserver.go @@ -26,7 +26,7 @@ var senderErrorChan chan error = make(chan error) func SendWebserver(localPort int, file []string, uuid []string) (err error) { totalFile = len(file) - server.Addr = ":"+strconv.Itoa(localPort) + server.Addr = ":" + strconv.Itoa(localPort) for i, _ := range file { // Check mimetype @@ -35,13 +35,13 @@ func SendWebserver(localPort int, file []string, uuid []string) (err error) { senderErrorChan <- internal.CustomizeError("receiveMimeType", err) } - http.Handle("/"+uuid[i], http.HandlerFunc(func (w http.ResponseWriter, request *http.Request) { + http.Handle("/"+uuid[i], http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) { receiveSendWebserver(w, request, file[i], mimeType.String()) })) - http.Handle("/checksum-"+uuid[i], http.HandlerFunc(func (w http.ResponseWriter, request *http.Request) { + http.Handle("/checksum-"+uuid[i], http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) { checksumSendWebserver(w, request, file[i]) })) - http.Handle("/verify-"+uuid[i], http.HandlerFunc(func (w http.ResponseWriter, request *http.Request) { + http.Handle("/verify-"+uuid[i], http.HandlerFunc(func(w http.ResponseWriter, request *http.Request) { promptSendWebserver(w, request, file[i], mimeType.String()) })) } @@ -58,14 +58,14 @@ func SendWebserver(localPort int, file []string, uuid []string) (err error) { err = <-senderErrorChan - shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second) - defer shutdownRelease() + shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second) + defer shutdownRelease() fmt.Println("Gracefully shutdown server...") err = server.Shutdown(shutdownCtx) - if err != nil { + if err != nil { return err - } + } return nil } @@ -131,7 +131,6 @@ func receiveSendWebserver(w http.ResponseWriter, request *http.Request, filePath senderErrorChan <- internal.CustomizeError("receiveOpenFileStat", err) } - w.Header().Set("Transfer-Encoding", "identity") w.Header().Set( "Content-Length", diff --git a/cmd/mdrop-client/shell.go b/cmd/mdrop-client/shell.go index 0c347c9..99f0d59 100644 --- a/cmd/mdrop-client/shell.go +++ b/cmd/mdrop-client/shell.go @@ -72,11 +72,11 @@ func StartShellTunnel(s internal.SSHParameter, isTunnel bool) (output string, er errChan <- errors.New("Port full on server") } - // Case: Invalid key - if strings.Contains(m, "Invalid key") { + // Case: Invalid key + if strings.Contains(m, "Invalid key") { outputChan <- "Invalid key" errChan <- errors.New("Invalid key on execution") - } + } } }() @@ -112,4 +112,3 @@ func StartShellTunnel(s internal.SSHParameter, isTunnel bool) (output string, er return output, err } - diff --git a/cmd/mdrop-client/token_transfer.go b/cmd/mdrop-client/token_transfer.go index d9c537f..dfb163a 100644 --- a/cmd/mdrop-client/token_transfer.go +++ b/cmd/mdrop-client/token_transfer.go @@ -6,9 +6,9 @@ import ( ) type TokenTransferJSON struct { - Host string `json:"host"` - RemotePort int `json:"remotePort"` - Files []string `json:"files"` + Host string `json:"host"` + RemotePort int `json:"remotePort"` + Files []string `json:"files"` } func (t TokenTransferJSON) GenerateToken() (token string, err error) { diff --git a/cmd/mdrop-tunnel-tools/main.go b/cmd/mdrop-tunnel-tools/main.go index 3be21d3..dc8e5b4 100644 --- a/cmd/mdrop-tunnel-tools/main.go +++ b/cmd/mdrop-tunnel-tools/main.go @@ -13,29 +13,29 @@ import ( const KEY_FILE_LOCATION string = "/etc/mdrop-tunnel-key" func main() { - // Parse args + // Parse args flag.Parse() args := flag.Args() - // Check key file - if _, err := os.Stat(KEY_FILE_LOCATION); os.IsNotExist(err) { + // Check key file + if _, err := os.Stat(KEY_FILE_LOCATION); os.IsNotExist(err) { fmt.Println("Key/token file not found at /etc/mdrop-tunnel-key") os.Exit(10) - } - byteKeyFile, err := os.ReadFile(KEY_FILE_LOCATION) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - keyFile := strings.TrimSpace(string(byteKeyFile)) + } + byteKeyFile, err := os.ReadFile(KEY_FILE_LOCATION) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + keyFile := strings.TrimSpace(string(byteKeyFile)) - // Check is command contains key or not - if keyFile != "" { - if !implContains(args, keyFile) { - fmt.Println("Invalid key") - os.Exit(10) - } - } + // Check is command contains key or not + if keyFile != "" { + if !implContains(args, keyFile) { + fmt.Println("Invalid key") + os.Exit(10) + } + } if len(args) < 1 { fmt.Println("Usage: mdrop-tunnel [key]") @@ -68,19 +68,19 @@ func GetPortCommand() { timeout := time.Second conn, err := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", strconv.Itoa(i)), timeout) if err != nil { - fmt.Println("Error ["+strconv.Itoa(i)+"]: "+err.Error()) + fmt.Println("Error [" + strconv.Itoa(i) + "]: " + err.Error()) } if conn == nil { portFound = i break } - fmt.Println("Get-Port-Closed ["+strconv.Itoa(i)+"]: Continue.") + fmt.Println("Get-Port-Closed [" + strconv.Itoa(i) + "]: Continue.") } if portFound != 0 { - fmt.Println("Get-Port-Found "+strconv.Itoa(portFound)) + fmt.Println("Get-Port-Found " + strconv.Itoa(portFound)) } else { - fmt.Println("Get-Port-Closed ["+strconv.Itoa(portFound)+"]: Not found.") + fmt.Println("Get-Port-Closed [" + strconv.Itoa(portFound) + "]: Not found.") os.Exit(2) } } @@ -90,7 +90,7 @@ func PingCommand() { } func implContains(sl []string, name string) (found bool) { - found = false + found = false for _, value := range sl { if value == name { found = true diff --git a/internal/rw_config_file.go b/internal/rw_config_file.go index b56e6d6..9828c34 100644 --- a/internal/rw_config_file.go +++ b/internal/rw_config_file.go @@ -13,8 +13,8 @@ var ( ) type ConfigSourceAuth struct { - Default int `json:"default"` - ListConfiguration []ConfigFile `json:"listConfig"` + Default int `json:"default"` + ListConfiguration []ConfigFile `json:"listConfig"` } type ConfigFile struct { @@ -22,7 +22,7 @@ type ConfigFile struct { Host string `json:"host"` Port int `json:"port"` Proxy string `json:"proxy"` - Key string `json:"key"` + Key string `json:"key"` } func init() { @@ -36,29 +36,55 @@ func init() { ConfigFileLocation += "/.mdrop" } -func (c ConfigFile) WriteConfig() (err error) { +func (c ConfigFile) WriteRawConfig(isReplace bool) (conf string, err error) { var config ConfigSourceAuth - fmt.Println("Writing config file...") - if CheckConfigFileExist() { - err = config.ParseConfig(&config) - if err != nil { - err = os.Remove(GetConfigPath()) + if !isReplace { + if CheckConfigFileExist() { + err = config.ParseConfig(&config) if err != nil { - return err + err = os.Remove(GetConfigPath()) + if err != nil { + return "", err + } } } } // Check if there's multiple configuration if config.GetTunnelBasedInstanceName(c.Name) != -1 { - return errors.New("Multiple instance name") + return "", errors.New("Multiple instance name") } // Append config file config.ListConfiguration = append(config.ListConfiguration, c) strJsonByte, err := json.Marshal(config) + if err != nil { + return "", err + } + conf = base64.StdEncoding.EncodeToString(strJsonByte) + return conf, nil +} + +func (c ConfigFile) WriteConfig(isReplace bool) (err error) { + fmt.Println("Writing config file...") + strConfig, err := c.WriteRawConfig(isReplace) + if err != nil { + return err + } + + err = os.WriteFile(ConfigFileLocation, []byte(strConfig), 0644) + if err != nil { + return err + } + + fmt.Println("Config file is saved on", ConfigFileLocation) + return nil +} + +func (c ConfigSourceAuth) WriteConfig() (err error) { + strJsonByte, err := json.Marshal(c) if err != nil { return err } diff --git a/internal/shell.go b/internal/shell.go index 90f83de..7fcfd35 100644 --- a/internal/shell.go +++ b/internal/shell.go @@ -7,11 +7,11 @@ import ( ) type SSHParameter struct { - IsRemote bool - LocalPort int - RemotePort int - ConfigFile ConfigFile - Command []string + IsRemote bool + LocalPort int + RemotePort int + ConfigFile ConfigFile + Command []string } func (s SSHParameter) GenerateConnectSSHArgs() string { @@ -26,11 +26,11 @@ func (s SSHParameter) GenerateConnectSSHArgs() string { } args = append(args, s.Command...) s.GenerateProxyArgs(&args) - if s.ConfigFile.Key != "" { - args = append(args, s.ConfigFile.Key) - } + if s.ConfigFile.Key != "" { + args = append(args, s.ConfigFile.Key) + } - return "ssh "+strings.Join(args, " ") + return "ssh " + strings.Join(args, " ") } func (s SSHParameter) GenerateRemoteSSHArgs() string { @@ -57,11 +57,11 @@ func (s SSHParameter) GenerateRemoteSSHArgs() string { ) } s.GenerateProxyArgs(&args) - if s.ConfigFile.Key != "" { - args = append(args, s.ConfigFile.Key) - } + if s.ConfigFile.Key != "" { + args = append(args, s.ConfigFile.Key) + } - return "ssh "+strings.Join(args, " ") + return "ssh " + strings.Join(args, " ") } func (s SSHParameter) GenerateProxyArgs(args *[]string) {