@@ -13,6 +13,7 @@ import (
1313
1414 "golang.org/x/crypto/ssh"
1515 "golang.org/x/crypto/ssh/agent"
16+ "golang.org/x/crypto/ssh/terminal"
1617)
1718
1819// Client is a wrapper over the SSH connection/sessions.
@@ -29,6 +30,10 @@ type SSHClient struct {
2930 running bool
3031 env string //export FOO="bar"; export BAR="baz";
3132 color string
33+
34+ ask bool // For interactive "ask:root@..."
35+ password string // For config "password: ..."
36+
3237}
3338
3439type ErrConnect struct {
@@ -54,6 +59,15 @@ func (c *SSHClient) parseHost(host string) error {
5459 if at := strings .LastIndex (c .host , "@" ); at != - 1 {
5560 c .user = c .host [:at ]
5661 c .host = c .host [at + 1 :]
62+
63+ // Check if the username starts with "ask:"
64+ c .ask = false
65+ if strings .HasPrefix (c .user , "ask:" ) {
66+ // Remove "ask:" from the username
67+ c .user = strings .TrimPrefix (c .user , "ask:" )
68+ // Set the flag so ConnectWith knows to prompt
69+ c .ask = true
70+ }
5771 }
5872
5973 // Add default user, if not set
@@ -135,11 +149,30 @@ func (c *SSHClient) ConnectWith(host string, dialer SSHDialFunc) error {
135149 return err
136150 }
137151
152+ // 1. Start with Public Keys (SSH Agent + ~/.ssh/id_rsa)
153+ auths := []ssh.AuthMethod {
154+ authMethod ,
155+ }
156+
157+ // 2. If a password was provided in Supfile, add it to the list
158+ if c .password != "" {
159+ auths = append (auths , ssh .Password (c .password ))
160+ }
161+
162+ // 3. If the user requested an interactive prompt (ask:user@host), ask now
163+ if c .ask {
164+ fmt .Printf ("Enter Password for %s@%s: " , c .user , c .host )
165+ pass , err := terminal .ReadPassword (int (os .Stdin .Fd ()))
166+ if err != nil {
167+ return err
168+ }
169+ fmt .Println ("" ) // Print newline after input
170+ auths = append (auths , ssh .Password (string (pass )))
171+ }
172+
138173 config := & ssh.ClientConfig {
139- User : c .user ,
140- Auth : []ssh.AuthMethod {
141- authMethod ,
142- },
174+ User : c .user ,
175+ Auth : auths , // Use the combined list of auth methods
143176 HostKeyCallback : ssh .InsecureIgnoreHostKey (),
144177 }
145178
@@ -155,10 +188,10 @@ func (c *SSHClient) ConnectWith(host string, dialer SSHDialFunc) error {
155188// Run runs the task.Run command remotely on c.host.
156189func (c * SSHClient ) Run (task * Task ) error {
157190 if c .running {
158- return fmt .Errorf ("Session already running" )
191+ return fmt .Errorf ("session already running" )
159192 }
160193 if c .sessOpened {
161- return fmt .Errorf ("Session already connected" )
194+ return fmt .Errorf ("session already connected" )
162195 }
163196
164197 sess , err := c .conn .NewSession ()
0 commit comments