1
votes

I'm new to Expect scripting. I'm trying to create a procedure that will connect to routers/switches over SSH and fall back to telnet if that fails. The code that I have works fine before I put it inside a procedure. I'm sure there's something I'm not understanding about how procedures work. When I call it as a procedure it does connect via SSH which receives "Connection refused" and falls back to telnet like it is supposed to, it just never logs in with the password. When I enable debug mode I see it sends the password but for some reason the router doesn't seem like it receives it. It just sits at the Password: prompt until it times out.

proc connectToTerminal { username hostname password } {
    # Run ssh, don't display key warning
    spawn ssh -o StrictHostKeyChecking=no $username\@$hostname

    # Allow this script to handle ssh connection issues, fall back to telnet
    expect {
        timeout { send_user "\nTimeout Exceeded - Check Host\n"; exit 1 }
        eof { send_user "\nSSH Connection To $hostname Failed\n"; exit 1 }
        # If we have the correct prompt, continue
        "*#" {}
        # If it's asking for the password, it can have it
        "*assword:" { send "$password\n" }
        # Fall back to telnet if connection refused
        "Connection refused" { 
            spawn telnet $hostname
            #expect "username:" 
            #send "$username\n"
            expect "*assword:" 
            send "$password\n"
        }
        # Fall back to telnet if connection is closed by [ip address]
        -re {closed by \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}} { 
            spawn telnet $hostname
            #expect "username:" 
            #send "$username\n"
            expect "*assword:"
            send "$password\n" 
        }
        # Use SSH v1 if the device is only accepting v1 
        "2 vs. 1" { 
            spawn ssh -1 -o StrictHostKeyChecking=no $username\@$hostname
            expect {
                "*assword:" { send "$password\n" }
                timeout { 
                    spawn telnet $hostname
                    #expect "username:" 
                    #send "$username\n"
                    expect "*assword:"
                    send "$password\n"
                }
            }
        }
    }
}

connectToTerminal $username $hostname $password

Below is the debug output when I run the script

spawn ssh -o StrictHostKeyChecking=no [email protected]
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {7726}
Gate keeper glob pattern for 'closed by \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}' is 'closed by *'. Activating booster.

expect: does "" (spawn_id exp6) match glob pattern "*#"? no
"*assword:"? no
"Connection refused"? no
"closed by \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}"? Gate "closed by *"? gate=no
"2 vs. 1"? no
ssh: connect to host 172.16.1.195 port 22: Connection refused

expect: does "ssh: connect to host 172.16.1.195 port 22: Connection refused\r\r\n" (spawn_id exp6) match glob pattern "*#"? no
"*assword:"? no
"Connection refused"? yes
expect: set expect_out(0,string) "Connection refused"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "ssh: connect to host 172.16.1.195 port 22: Connection refused"
spawn telnet 172.16.1.195
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {7730}

expect: does "" (spawn_id exp7) match glob pattern "*assword:"? no
Trying 172.16.1.195...

expect: does "Trying 172.16.1.195...\r\n" (spawn_id exp7) match glob pattern "*assword:"? no
Connected to 172.16.1.195.
expect: does "Trying 172.16.1.195...\r\nConnected to 172.16.1.195." (spawn_id exp7) match glob pattern "*assword:"? no


expect: does "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\n" (spawn_id exp7) match glob pattern "*assword:"? no
Escape character is '^]'.
expect: does "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\nEscape character is '^]'." (spawn_id exp7) match glob pattern "*assword:"? no


expect: does "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\nEscape character is '^]'.\r\n" (spawn_id exp7) match glob pattern "*assword:"? no
C
*********************************************************************
*                                                                   *
*                                                                   *
*                                                                   *
*              THIS COMPUTER IS FOR PRIVATE USE ONLY                *
*              -------------------------------------                *
*                                                                   *
*    UNAUTHORIZED access to and/or use of this computer syst
expect: does "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\nEscape character is '^]'.\r\nC\r\n*********************************************************************\r\n*                                                                   *\r\n*                                                                   *\r\n*                                                                   *\r\n*              THIS COMPUTER IS FOR PRIVATE USE ONLY                *\r\n*              -------------------------------------                *\r\n*                                                                   *\r\n*    UNAUTHORIZED access to and/or use of this computer syst" (spawn_id exp7) match glob pattern "*assword:"? no
em      *
*    is a violation of law and is punishable under provisions of    *
*    19 USC 1029 and 18 USC 1030, and applicable statutes. Use      *
*    of this system constitutes consent to security testing and     *
*    monitoring.                                                    *
*                                                                   *
*                               11-12-13                            *
*********************************************************************


User Access Verification

Password: 
expect: does "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\nEscape character is '^]'.\r\nC\r\n*********************************************************************\r\n*                                                                   *\r\n*                                                                   *\r\n*                                                                   *\r\n*              THIS COMPUTER IS FOR PRIVATE USE ONLY                *\r\n*              -------------------------------------                *\r\n*                                                                   *\r\n*    UNAUTHORIZED access to and/or use of this computer system      *\r\n*    is a violation of law and is punishable under provisions of    *\r\n*    19 USC 1029 and 18 USC 1030, and applicable statutes. Use      *\r\n*    of this system constitutes consent to security testing and     *\r\n*    monitoring.                                                    *\r\n*                                                                   *\r\n*                               11-12-13                            *\r\n*********************************************************************\r\n\r\n\r\nUser Access Verification\r\n\r\nPassword: " (spawn_id exp7) match glob pattern "*assword:"? yes
expect: set expect_out(0,string) "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\nEscape character is '^]'.\r\nC\r\n*********************************************************************\r\n*                                                                   *\r\n*                                                                   *\r\n*                                                                   *\r\n*              THIS COMPUTER IS FOR PRIVATE USE ONLY                *\r\n*              -------------------------------------                *\r\n*                                                                   *\r\n*    UNAUTHORIZED access to and/or use of this computer system      *\r\n*    is a violation of law and is punishable under provisions of    *\r\n*    19 USC 1029 and 18 USC 1030, and applicable statutes. Use      *\r\n*    of this system constitutes consent to security testing and     *\r\n*    monitoring.                                                    *\r\n*                                                                   *\r\n*                               11-12-13                            *\r\n*********************************************************************\r\n\r\n\r\nUser Access Verification\r\n\r\nPassword:"
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "Trying 172.16.1.195...\r\nConnected to 172.16.1.195.\r\nEscape character is '^]'.\r\nC\r\n*********************************************************************\r\n*                                                                   *\r\n*                                                                   *\r\n*                                                                   *\r\n*              THIS COMPUTER IS FOR PRIVATE USE ONLY                *\r\n*              -------------------------------------                *\r\n*                                                                   *\r\n*    UNAUTHORIZED access to and/or use of this computer system      *\r\n*    is a violation of law and is punishable under provisions of    *\r\n*    19 USC 1029 and 18 USC 1030, and applicable statutes. Use      *\r\n*    of this system constitutes consent to security testing and     *\r\n*    monitoring.                                                    *\r\n*                                                                   *\r\n*                               11-12-13                            *\r\n*********************************************************************\r\n\r\n\r\nUser Access Verification\r\n\r\nPassword:"
send: sending "cisco\n" to { exp7 }

expect: does "" (spawn_id exp0) match glob pattern "*#"? no
"*>"? no
expect: timed out
1
I was using Expect a few days ago and remember seeing the manual page saying that when you want to send the equivalent of pressing return, that you should use \r rather than \n. Maybe that fixes things? - icktoofay
Gave that a shot but it did not make a difference. Thanks for the suggestion though. - 0xDECAFBAD

1 Answers

0
votes

After sending the password, just add one more expect statement.

set prompt "#"
send "$password \r"
expect "$prompt"

Unless we explicitly tell Expect to wait for it, it won't expect anything from the session.

Update :

I'm not sure if you have missed the expect statement or misplaced it in the caller procedure. Update your issues if still not solved.

If you have placed the expect statement in another proc, then the spawn_id should be passed on to it, so that Expect can wait for it properly. Else, the default behavior will be restored if spawn_id is empty. i.e. it will expect from the stdin.

It is evident from your debug output

expect: does "" (spawn_id exp0) match glob pattern "*#"? no

where exp0 is nothing but the stdin. Inside that procedure, after spawning the telnet , you can save the spawn_id in to another variable and return it to caller procedure where it can be used.