Thursday, April 14, 2022

[SOLVED] Expect if condition with ssh password

Issue

I am currently trying to create a script with error handling.

Basically the script tests the ssh connection with this command : ssh -o BatchMode=yes $machine uname -a

There is 3 potential situation that i want to handle :

  1. SSH works just fine without password
  2. SSH is blocked because the machine isn't in the known_hosts file in .ssh
  3. SSH is blocked because the machine isn't in the known_hosts file in .ssh AND it requires a password to continue (which means the id_rsa.pub isn't in the authorized_keys file in .ssh

I have on main script that is calling an expect script here is what the main script looks like :

ssh -o BatchMode=yes ${machine} uname -a &> temp-file.txt 2>&1
# Here we test the ssh connection just once and we store the output of the command in a temp file

if [ $? -eq 255 ]
# If the ssh didn't work

then

   if grep -q "Host key verification failed." temp-file.txt
   # If the error message is "Host key verification failed."

   then
      expect script-expect-knownhosts.exp ${machine} 2>&1 >/dev/null

And here is the script-expect-knownhosts.exp file in which i tried to make a condition :

#!/usr/bin/expect -f

set machine [lindex $argv 0]
# Here we state that the first argument used with the command will be the $machine variable

set prompt "#|%|>|\$ $"

set timeout 60

spawn ssh $machine
# We do a ssh on the machine

set prompt "#|%|>|\$ $"

expect { 

    "Are you sure you want to continue connecting (yes/no)? "  {send "yes\r";exp_continue} 
     # If he asks for a yes/no answer, then answer yes to add the machine to the known_hosts file

    -exact "Password: " {send -- "^C";exp_continue}
     # If he asks for a password, then send a CTRL + C

    -re $prompt {send "exit\r";exp_continue}
     # If the prompt shows up (if after the yes/no question, we don't need to put a password in) then type exit

}

So here is what happens when i execute the expect script with a machine in case number 2 (works just fine):

spawn ssh machine
Are you sure you want to continue connecting (yes/no)? yes
machine:~ # exit
deconnection
Connection to machine closed.

And here is what happens when i execute the expect script with a machine in case number 3 :

spawn ssh machine
Are you sure you want to continue connecting (yes/no)? yes
Password: 

And it stays stuck on Password until i manually do a CTRL + C


Solution

In cases 2 and 3 you don't need exp_continue because you are stopping the connection process.

For case 2, I don't think you really want to send a control-C. When you do this interactively, typing control-C has the effect of sending a signal to kill the process you are interacting with. What you really want is to stop the ssh process, so instead of send -- "^C";exp_continue you should just do close.



Answered By - Colin Macleod
Answer Checked By - Gilberto Lyons (WPSolving Admin)