2012-05-11 24 views
5

Nuovo per Stackoverflow, quindi prima di tutto, ciao.ssh utilizzando python senza chiavi RSA

Sto lavorando a un piccolo progetto per la mia scuola che dovrebbe essere un gui personalizzato (scritto in python come una sfida educativa per me dal momento che non ho mai usato Python) per il programma Unison open source. Stiamo cercando di consentire agli studenti e al personale di sincronizzare una cartella a casa e nella scuola avviando questo programma con il minimo di input possibile (prova dell'idiota, se lo si desidera). L'interfaccia dovrebbe essere solo il nome utente e la password della scuola e il wrapper gui dovrebbe solo inviare username e password a Unison e sincronizzarli.

Il problema è Unison a sua volta avvia SSh e richiede la password ma il metodo subprocess.communicate (input) python non consente a ssh di acquisire la password. Ho capito che ssh accetterà solo input dal terminale e non riesco a capire come ingannarlo. Ho letto alcune cose sull'utilizzo di uno pseudo terminale, ma sono ancora perplesso. Le chiavi RSA sarebbero la soluzione ideale, ma la loro generazione e il loro inserimento sul server remoto implicano ancora la necessità di effettuare il login con una password almeno una volta e ciò richiederebbe una soluzione a quanto sopra, o il terminale che non è una prova idiota.

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) 

Le stringhe di esecuzione funziona bene in là terminale se mi si incolla. E qualche consiglio pitone generale sarebbe anche apprezzato se siete così inclinato.

Grazie!

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

Edit: Vorrei anche notare che, mentre sto attualmente in via di sviluppo sotto OSX e Linux, io alla fine dovranno rendere compatibile questa finestra poiché la maggior parte degli studenti della mia scuola eseguire Windows come loro macchina primaria (o solo).

risposta

3

Cerca su pexpect.

import pexpect 

child = pexpect.spawn('ssh [email protected]') 
child.expect('Password:') 
child.sendline(mypassword) 
child.interact() 
+0

Ho appena provato a testare questo mio progetto con esattamente quello che hai lì (ovviamente con un host effettivo) e non succede nulla. Leggera pausa e poi torna a un prompt di bash senza messaggi. Ho provato ad aggiungere l'intera linea di esecuzione dal mio codice precedente pensando che potrebbe semplicemente chiudersi se non gli viene dato nulla, ma fa la stessa cosa. – Hiroshi

+0

Assicurarsi che l'argomento passato a child.expect() corrisponda alla richiesta di password che il server fornisce. Inoltre, potrebbe essere necessario chiamare child.interact() dopo child.sendline (mypassword). È passato un po 'di tempo da quando ho usato pexpect, ma è lo strumento per il lavoro. –

+0

Ha funzionato! Grazie! :) – Hiroshi

2

Se si desidera inviare una password per ssh è necessario aprire pseudoterminal (un pty) e comunicare con esso usando che invece di utilizzare stdin/stdout. Dai un'occhiata al modulo pexpect, progettato per fare esattamente questo.

Una soluzione alternativa implicherebbe una sorta di meccanismo fuori banda per la distribuzione di chiavi pubbliche: ad esempio, impostare una semplice applicazione Web in cui le persone possono incollare una chiave pubblica e far gestire il file authorized_keys per conto di l'utente.