LL      IIIII NN   NN KK  KK EEEEEEE RRRRRR  RRRRRR   OOOOO  RRRRRR 
LL       III  NNN  NN KK KK  EE      RR   RR RR   RR OO   OO RR   RR
LL       III  NN N NN KKKK   EEEEE   RRRRRR  RRRRRR  OO   OO RRRRRR 
LL       III  NN  NNN KK KK  EE      RR  RR  RR  RR  OO   OO RR  RR 
LLLLLLL IIIII NN   NN KK  KK EEEEEEE RR   RR RR   RR  OOOOO  RR   RR
                                                           ramblings
____________________________________________________________________
Posted on: Wednesday, June 9th, 2010 at 11:41.
Filed under: Coding, ServerAdmin, Software.
RSS 2.0 feed for comments.
You can leave a response, or trackback from your own site.

Being a sysadmin you end up running ssh to multiple servers at the same time, all the time. Being a paranoid sysadmin you also have different (long) passwords for every one of these servers.

Unless you want to spend more time entering passwords than doing actual work, you probably have some kind of master-password system setup.

Most people will use an ssh key uploaded to the servers in order to accomplish this. – (hopefully one that is password protected.)

However there are some situations where this is not preferred, for example, when an account is shared by multiple people, or when you simply cannot leave ssh public keys lingering around. Or when you simply don’t want to have to re-upload the key every time the home directory gets wiped…

It sure would be nice to have a password manager, protected with a master password, remember passwords you enter for ssh, in those cases.

This is possible with kdewallet and a small expect script wrapper around ssh.

I don’t personally use kde, but I do use some of the utilities it ships with from time to time, kdewalet being one of them. Kdewallet uses dbus for ipc. The qdbus utility lets you interact with dbus applications from the command line (and from shell scripts), so that’s what this script makes use of. The KDE Wallet password management system consists of system daemon (kwalletd) and a front-end gui application to view the password database, create folders, etc, called kwalletmanager. You don’t have to have kwalletmanager running for this to work. The script will automatically start kwalletd if it’s not running.

You can use kwalletmanager to create a separate folder to store your ssh passwords “eg, a folder called “ssh”) and specify the folder in which to store the passwords at the top of the script, where some other constants can be adjusted such as the location of the needed binaries…

If a password was not found in kwallet, it will prompt for the password and store it. (If you entered the wrong password you’ll have to remove it using kwalletmanager.)

The script is implemented using ‘expect’ which can be obtained here : http://expect.nist.gov/ – Which uses TCL syntax.

#!/usr/bin/expect -f

# Entry point -----------------------------------------------------------------

# Constants
set kwalletd "/usr/bin/kwalletd"
set qdbus "/usr/bin/qdbus"
set kdialog "/usr/bin/kdialog"
set appid "ssh"
set passwdfolder "ssh"

# Get commandline args.

set user [lindex $argv 0]
set host [lindex $argv 1]
set port [lindex $argv 2]

# Check arg sanity
if { $user == "" || $host == "" } {
  puts "Usage: user host \[port\] \n"
  exit 1
}

# Use a sane default port if not specified by the user.
if { $port == "" } {
  set port "22"
}

# Run kde wallet daemon if it's not already running.
set kwalletrunning [ 
  exec "$qdbus" "org.kde.kwalletd" "/modules/kwalletd" "org.kde.KWallet.isEnabled" 
]
if { $kwalletrunning == "false" } {
  puts "kwalletd is not running, starting it...\n"
  exec "$kwalletd&"
  sleep 2
} else {
  puts "Found kwalletd running.\n"
}

# Get wallet id 
set walletid [
  exec "$qdbus" "org.kde.kwalletd" "/modules/kwalletd" "org.kde.KWallet.open" "kdewallet" "0" "$appid"
]

# Get password from kde wallet.
set passw [
  exec "$qdbus" "org.kde.kwalletd" "/modules/kwalletd" "org.kde.KWallet.readPassword" "$walletid" "$passwdfolder" "$user@$host" "$appid"
]

# If no password was found, ask for one.
if { $passw == "" } {
  set passw [
    exec "$kdialog" "--title" "ssh" "--password" "Please enter the ssh password for $user@$host"
  ]
  if { $passw == "" } {
    puts "You need to enter a password.\n"
    exit 1
  }
  # Now save the newly entered password into kde wallet
  exec "$qdbus" "org.kde.kwalletd" "/modules/kwalletd" "org.kde.KWallet.writePassword" "$walletid" "$passwdfolder" "$user@$host" "$passw" "$appid"
}

# Run ssh.
if [
  catch {
    spawn ssh -p $port $user@$host 
  } reason
] {
  puts " Failed to spawn SSH: $reason\n"
  exit 1
}

# Wait for password prompt and send the password.
# Add key to known hosts if asked.
# Resume after successful login.
expect {
  -re ".*assword:" {
    exp_send "$passw\r"
    exp_continue;
  }
  -re ".* (yes/no?)" {
    send -- "yes\r" {
      exp_continue
    }
    -re ".*Warning: Permanently .*known hosts.\r\r\n" exp_continue
  }
  -re ".*Last login" exp_continue;
}

# Send a blank line
send -- "\r"

# Now finally let the user interact with ssh.
interact
pixelstats trackingpixel
____________________________________________________________________
____________________________________________________________________

Leave a Reply