diff --git a/README.md b/README.md index d2dcb19..26ac50c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # ssh2telnet Proxy ssh connection into telnet. -## Usage +## Options ``` $ ssh2telnet -h @@ -9,12 +9,16 @@ Usage: ssh2telnet [OPTIONS] Application Options: - -a, --addr= Address to listen on (default: :2222) - -k, --key= Path to the host key + -a, --addr= Address to listen (default: localhost:2222) + -k, --key= Path to the host key + -l, --login Enable auto login + --login-prompt= Login prompt (default: "login: ") + --password-prompt= Password prompt (default: "Password: ") Help Options: -h, --help Show this help message ``` +## Basic Usage Start a ssh server. @@ -23,18 +27,44 @@ $ ssh2telnet -a :2222 Starting ssh server on :2222 ``` -Connect the ssh server from the other terminal. -The given username will be interpeted into the hostname you want to access. +Connect the server from another terminal. +The specified username will be interpeted into the hostname. +Now the proxied telnet session is attached to the target host. ``` $ ssh localhost -p 2222 -l 192.168.1.1 -User Access Verification +RP/0/RSP0/CPU0:R1#show clock +Thu Nov 11 00:00:00.000 JST +00:00:00:000 JST Thu Nov 11 2021 + +RP/0/RSP0/CPU0:R1#exit +Connection to localhost closed. +``` + +## Auto Login + +ssh2telnet also comes with the auto login feature. +Start a ssh server with the `--login` option and specify `--login-prompt` and/or `--password-prompt` if necessary. + +``` +$ ssh2telnet -a :2222 -l --login-prompt 'Username: ' +Starting ssh server on :2222 +``` + +Connect the server from another terminal. +The specified username will be interpeted into 'username@hostname'. +Login password for the target host is also prompted afterward. + +``` +$ ssh localhost -p 2222 -l vagrant@192.168.1.1 +vagrant@192.168.1.1@localhost's password: -Username: vagrant -Password: +RP/0/RSP0/CPU0:R1#show clock +Thu Nov 11 00:00:00.000 JST +00:00:00:000 JST Thu Nov 11 2021 RP/0/RSP0/CPU0:R1#exit Connection to localhost closed. diff --git a/main.go b/main.go index f2e32bf..a4e11da 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "log" "net" "os" + "strings" "github.com/gliderlabs/ssh" "github.com/ziutek/telnet" @@ -14,8 +15,11 @@ import ( ) type options struct { - Addr string `short:"a" long:"addr" description:"Address to listen on" default:":2222"` - HostKey string `short:"k" long:"key" description:"Path to the host key"` + Addr string `short:"a" long:"addr" description:"Address to listen" default:"localhost:2222"` + HostKey string `short:"k" long:"key" description:"Path to the host key"` + AutoLogin bool `short:"l" long:"login" description:"Enable auto login"` + LoginPrompt string `long:"login-prompt" description:"Login prompt (default: \"login: \")" default:"login: " default-mask:"-"` + PasswordPrompt string `long:"password-prompt" description:"Password prompt (default: \"Password: \")" default:"Password: " default-mask:"-"` } func start(opts options) error { @@ -26,10 +30,29 @@ func start(opts options) error { server.SetOption(hostKeyFile) } + var username, password, host string + if opts.AutoLogin { + passwordAuth := ssh.PasswordAuth(func(ctx ssh.Context, s string) bool { + t := strings.SplitN(ctx.User(), "@", 2) + if len(t) != 2 { + return false + } + + username, host = t[0], t[1] + password = s + return true + }) + server.SetOption(passwordAuth) + } + server.Handle(func(s ssh.Session) { _, _, isPty := s.Pty() if isPty { - addr := net.JoinHostPort(s.User(), "23") + if host == "" { + host = s.User() + } + + addr := net.JoinHostPort(host, "23") fmt.Printf("Connecting to %s\n", addr) conn, err := telnet.Dial("tcp", addr) @@ -37,8 +60,14 @@ func start(opts options) error { fmt.Fprintf(os.Stderr, "Unable to connect to %s.\n", addr) s.Exit(1) } else { - sigChan := make(chan struct{}, 1) + if opts.AutoLogin { + _, err = conn.ReadUntil(opts.LoginPrompt) + conn.Write([]byte(fmt.Sprintf("%s\n", username))) + _, err = conn.ReadUntil(opts.PasswordPrompt) + conn.Write([]byte(fmt.Sprintf("%s\n", password))) + } + sigChan := make(chan struct{}, 1) go func() { _, _ = io.Copy(s, conn) sigChan <- struct{}{}