Search code examples
bashsshone-time-password

Calling ssh with otp from a script


My company uses a OTP over ssh (One Time Password) to access our production machines. The interaction might look something like this:

$ ssh prod
otp-md5 942 st9621 extResponse: 

At this point I run a Java program to generate the OTP response using the info I get from SSH. Note: that the hash from the ssh output ("942 st9621" in this example) has to be passed to the command bellow as input. This hash changes everytime you ssh.

$ java -jar jop.jar 942 st9621 <password>
LAD DARN BHOY TEST ACHE JUTE

Now I cut and paste the OTP generated ("LAD DARN BHOY TEST ACHE JUTE") into the other console window.

So, just to make everything clear: I piece of data generated from the ssh command needs to be used when running jop combined with my password, and then the result passed back to the, still running, ssh command.

I would love to automate this process. Basically, have a bash script which takes a hostname, asks for a password, and then calls ssh, passes the otp-md5 code to jop, and then the OTP back to ssh. A nice to have is to not have to type my password as a command line argument since this would then be stored in the command history, and is a big security problem.

Is this possible?

Thank you


Solution

  • This is based on the excellent answer posted by glenn jackman:

    #!/usr/bin/env expect
    
    # Get host from command line
    set host     [lindex $argv 0]
    
    # Read password from the user
    send_user "Password: "
    # Turn off echo to hide password
    stty -echo
    expect -re "(.+)\n"
    set password $expect_out(1,string)
    # Turn echo back on
    stty echo
    
    # SSH into server
    spawn ssh "$host"
    expect -re {otp-md5 ([^ ]+) ([^ ]+) extResponse: *$} {
        set otp [exec java -jar jop.jar $expect_out(1,string) $expect_out(2,string) "$password"]
        send_user "\n$otp"
        send -- "$otp\r"
    }
    interact