diff --git a/.gitignore b/.gitignore index d060faf..2f0a298 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ go.mod go.sum -tui-ssh-app \ No newline at end of file +tui-ssh-app +app.log \ No newline at end of file diff --git a/config/logger.go b/config/logger.go new file mode 100644 index 0000000..dcefb4f --- /dev/null +++ b/config/logger.go @@ -0,0 +1,20 @@ +package config + +import ( + "log" + "os" +) + +// InitializeLogger sets up logging to a file. +func InitializeLogger(logFileName string) { + // Open the log file for writing (create if it doesn't exist, append if it does) + file, err := os.OpenFile(logFileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + log.Fatalf("Failed to open log file: %v", err) + } + + // Set the output of the default logger to the file + log.SetOutput(file) + log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) + log.Println("Logging initialized") +} diff --git a/main.go b/main.go index b1bfde1..2fd2668 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,25 @@ package main import ( + "log" "tui-ssh-app/config" "tui-ssh-app/db" "tui-ssh-app/tui" ) func main() { + // Initialize logging + config.InitializeLogger("app.log") + + // Load environment variables + log.Println("Loading environment variables...") config.LoadEnv() + + // Connect to the database + log.Println("Connecting to the database...") db.ConnectDB() + + // Start the TUI + log.Println("Starting TUI...") tui.StartTUI() } diff --git a/ssh/connect.go b/ssh/connect.go index 119c374..8c0ffb5 100644 --- a/ssh/connect.go +++ b/ssh/connect.go @@ -3,6 +3,7 @@ package ssh import ( "fmt" "io/ioutil" + "log" "golang.org/x/crypto/ssh" ) @@ -15,35 +16,60 @@ type SSHConfig struct { PrivateKey string } +// ConnectSSH handles both key-based and password authentication dynamically. func ConnectSSH(config SSHConfig) error { - var auth ssh.AuthMethod + log.Printf("Attempting SSH connection to %s@%s:%s", config.User, config.Host, config.Port) + // Build SSH authentication methods + var authMethods []ssh.AuthMethod + + // Add key-based authentication if a private key is provided if config.PrivateKey != "" { + log.Println("Attempting key-based authentication...") key, err := ioutil.ReadFile(config.PrivateKey) if err != nil { - return fmt.Errorf("failed to read private key: %v", err) + log.Printf("Error reading private key: %v", err) + return fmt.Errorf("failed to read private key: %w", err) } + signer, err := ssh.ParsePrivateKey(key) if err != nil { - return fmt.Errorf("failed to parse private key: %v", err) + log.Printf("Error parsing private key: %v", err) + return fmt.Errorf("failed to parse private key: %w", err) } - auth = ssh.PublicKeys(signer) - } else { - auth = ssh.Password(config.Password) + + authMethods = append(authMethods, ssh.PublicKeys(signer)) } + // Add password-based authentication if a password is provided + if config.Password != "" { + log.Println("Attempting password-based authentication...") + authMethods = append(authMethods, ssh.Password(config.Password)) + } + + // Ensure at least one authentication method is configured + if len(authMethods) == 0 { + return fmt.Errorf("no authentication method provided (password or private key)") + } + + // Configure SSH client clientConfig := &ssh.ClientConfig{ User: config.User, - Auth: []ssh.AuthMethod{auth}, - HostKeyCallback: ssh.InsecureIgnoreHostKey(), // Use a proper callback for production! + Auth: authMethods, + HostKeyCallback: ssh.InsecureIgnoreHostKey(), // Use a proper host key callback for production! } - client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", config.Host, config.Port), clientConfig) + // Dial the SSH server + address := fmt.Sprintf("%s:%s", config.Host, config.Port) + log.Printf("Connecting to SSH server at %s...", address) + + client, err := ssh.Dial("tcp", address, clientConfig) if err != nil { - return fmt.Errorf("failed to connect to SSH: %v", err) + log.Printf("Failed to connect to SSH server: %v", err) + return fmt.Errorf("failed to connect to SSH server: %w", err) } defer client.Close() - fmt.Println("Connected to SSH successfully!") + log.Printf("Successfully connected to %s@%s:%s", config.User, config.Host, config.Port) return nil }