2012-05-11 19 views
5

Neu bei Stackoverflow, also erstmal, hallo.ssh mit Python ohne RSA-Schlüssel

Ich arbeite an einem kleinen Projekt für meine Schule, das eine benutzerdefinierte GUI (geschrieben in Python als eine pädagogische Herausforderung für mich, da ich nie Python verwendet habe) für die Open-Source-Unison-Programm. Wir versuchen, Studenten und Mitarbeitern zu ermöglichen, einen Ordner zu Hause und in der Schule zu synchronisieren, indem Sie dieses Programm mit so wenig Aufwand wie möglich starten (Idiotensicher, wenn Sie so wollen). Die Schnittstelle sollte nur der Name und das Passwort der Schule sein und der GUI-Wrapper sollte einfach den Benutzernamen und das Passwort an Unison senden und sie synchronisieren.

Das Problem ist Unison wiederum startet SSh und fordert zur Eingabe des Passworts aber Python Subprozess.Communicate (Eingabe) -Methode wird nicht zulassen, dass SSH das Passwort übernehmen. Ich erkannte, dass ssh nur Eingaben vom Terminal akzeptieren wird und ich nicht herausfinden kann, wie man es austricksen kann. Ich habe einiges über die Verwendung eines Pseudo-Terminals gelesen, aber ich bin immer noch ratlos. RSA-Schlüssel wären die ideale Lösung, aber wenn ich sie erzeuge und sie dann auf dem Remote-Server ablege, muss ich mich mindestens einmal mit einem Passwort anmelden, was eine Lösung für das Obige oder das Terminal erfordert, das nicht idiotensicher ist.

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) 

Die Ausführungs Strings arbeitet dort Terminal in Ordnung, wenn ich es in einfügen. Und alle allgemeinen Python-Tipps auch wenn Sie so geneigt sind geschätzt würde.

Danke!

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

Edit: Ich sollte auch beachten, dass, während ich zur Zeit unter OSX und Linux zu entwickeln, werde ich schließlich kompatibel dieses Fenster machen, da die meisten meiner Schule Studenten laufen Fenster als ihre primäre (oder einzige) Maschine.

Antwort

3

Blick in pexpect.

import pexpect 

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

Ich habe gerade versucht dies mit genau ouside mein Projekt zu testen, was haben Sie da (natürlich mit einem tatsächlichen Host obwohl) und nichts passiert. Leichte Pause und dann zurück zu einer Bash-Eingabeaufforderung ohne Nachrichten. Ich habe versucht, die gesamte Ausführungszeile von meinem obigen Code zu denken, vielleicht schließt es nur, wenn nichts gegeben ist, aber es tut das gleiche. – Hiroshi

+0

Stellen Sie sicher, dass das Argument, das Sie an child.expect() übergeben, mit der Kennwortabfrage übereinstimmt, die der Server Ihnen gibt. Möglicherweise müssen Sie auch child.interact() nach child.sendline (mypassword) aufrufen. Es ist eine Weile her, seit ich Pexpect benutzt habe, aber es ist das Werkzeug für den Job. –

+0

Arbeitete! Vielen Dank! :) – Hiroshi

2

Wenn Sie ein Passwort ssh senden wollen, müssen Sie Pseudoterminal öffnen (ein pty) und mit ihm reden, dass statt nur stdin/stdout verwenden. Werfen Sie einen Blick auf das Modul pexpect, das genau dafür entwickelt wurde. Eine alternative Lösung würde eine Art Out-of-Band-Mechanismus für die Verteilung öffentlicher Schlüssel beinhalten: Sie können beispielsweise eine einfache Webanwendung einrichten, in der Personen einen öffentlichen Schlüssel einfügen und die authorized_keys-Datei im Auftrag verwalten können der Benutzer.