Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ssh using python without RSA keys

New to Stackoverflow, so first off, hello.

I'm working on a little project for my school which is supposed to be a custom gui (written in python as an educational challenge for me since I've never used python) for the open source Unison program. We're trying to allow students and staff to sync a folder at home and the school by launching this program with as little input as possible (idiot-proofing if you will). The interface is supposed to be just they're school username and password and the gui wrapper should just send the username and password to Unison and sync them.

The problem is Unison in turn launches SSh and prompts for the password but python subprocess.communicate(input) method won't let ssh take the password. I realized ssh will only accept input from the terminal and I can't figure out how to trick it. I've read some stuff about using a pseudo terminal but I'm still stumped. RSA keys would be the ideal solution, but generating them and then placing them on the remote server still involves me needing to login with a password at least once and that would require a solution to the above, or the terminal which is not idiot proof.

def startSync(self):
    '''
    '''
    userName = self.userNameIn.get()
    userPass = self.userPassIn.get()
    localDir = "/Users/localuser/syncFolder/"
    remoteDir = " ssh://schoolServer/remotesyncFolder" #for testing purposes, I set this to my own home machine which logs into my own account if I don't provide [email protected]
    unisonExecRemotePath = " -servercmd /Users/RemoteMe/unison" #unison is the unix executable responsible for launching unison on the remote system
    silenceCmdPrompts = " -silent" #keeps unison from displaying directory differences and asking if its okay to sync
    executionString = "./unison" + localDir + remoteDir + unisonExecRemotePath + silenceCmdPrompts

   mainProcess = subprocess.Popen(executionString,shell = True, stdin = subprocess.PIPE)
   mainProcess.communicate(userPass)

The execution strings works fine in there terminal if I paste it in. And any general python tips would also be appreciated if you're so inclined.

Thanks!

Unison User Manual: http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html

Edit: I should also note that while I'm currently developing under OSX and Linux, I will eventually have to make this windows compatible since most of my school's students run windows as their primary (or only) machine.

like image 997
Jtgrenz Avatar asked May 11 '12 16:05

Jtgrenz


2 Answers

Look into pexpect.

import pexpect

child = pexpect.spawn('ssh [email protected]')
child.expect('Password:')
child.sendline(mypassword)
child.interact()
like image 86
Neil Forrester Avatar answered Sep 26 '22 06:09

Neil Forrester


If you want to send a password to ssh you need to open pseudoterminal (a pty) and talk to it using that instead of just using stdin/stdout. Take a look at the pexpect module, which is designed to do exactly that.

An alternative solution would involve some sort of out-of-band mechanism for distributing public keys: for example, set up a simple web application where people can paste in a public key and have it manage the authorized_keys file on behalf of the user.

like image 32
larsks Avatar answered Sep 23 '22 06:09

larsks