2012-05-11 63 views
5

Nowość w Stackoverflow, więc po pierwsze, witam.ssh za pomocą pythona bez kluczy RSA

Pracuję nad małym projektem dla mojej szkoły, który ma być niestandardowym gui (napisanym w pytonie jako wyzwanie edukacyjne dla mnie, odkąd nigdy nie używałem Pythona) dla programu Unison open source. Staramy się umożliwić uczniom i pracownikom zsynchronizowanie folderu w domu i szkole, uruchamiając ten program z jak najmniejszym wkładem (jak to tylko możliwe). Interfejs ma być tylko nazwą użytkownika i hasłem szkoły, a opakowanie gui powinno wysłać nazwę użytkownika i hasło do Unisona i zsynchronizować je.

Problem polega na tym, że Unison z kolei uruchamia SSh i pyta o hasło, ale metoda podpowiadania podprocesora python (metoda komunikacyjna) nie pozwoli ssh odebrać hasła. Zdałem sobie sprawę, że ssh przyjmie tylko dane wejściowe z terminala i nie będę w stanie wymyślić, jak go oszukać. Czytałem kilka rzeczy o używaniu pseudo terminalu, ale wciąż jestem zakłopotany. Klucze RSA byłyby idealnym rozwiązaniem, ale generowanie ich, a następnie umieszczanie ich na zdalnym serwerze, wymaga co najmniej jednokrotnego logowania przy użyciu hasła, co wymagałoby rozwiązania powyższego, lub terminala, który nie jest dowodem tożsamości.

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) 

Struny wykonawcze działa dobrze w tam terminalu gdybym go wkleić. A jakieś wskazówki ogóle python będzie również mile widziane, jeśli jesteś tak skłonny.

Dzięki!

Unison Instrukcja obsługi: http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html

Edycja: Należy również pamiętać, że choć jestem obecnie rozwija pod OSX i Linux, będę w końcu musiał dokonać tego okna kompatybilny ponieważ większość uczniów mojej szkoły uruchomić Windows jako ich pierwotna (lub tylko) maszyna.

Odpowiedz

3

Sprawdź w pexpect.

import pexpect 

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

Po prostu starałem się przetestować ten projekt z dokładnie tym, co tam masz (oczywiście z rzeczywistym hostem) i nic się nie dzieje. Niewielka pauza, a następnie powrót do podpowiedzi bash bez wiadomości. Próbowałem dodać całą linię wykonawczą z powyższego kodu myśląc, że może się ona po prostu zamyka, jeśli nic nie zostanie podana, ale robi to samo. – Hiroshi

+0

Upewnij się, że argument przekazywany do elementu child.expect() jest zgodny z pytaniem o hasło podane przez serwer. Ponadto może zajść potrzeba wywołania child.interact() po child.sendline (mojehasło). Minęło trochę czasu odkąd użyłem pexpect, ale to narzędzie do pracy. –

+0

Pracował! Dzięki! :) – Hiroshi

2

Jeśli chcesz wysłać hasło ssh trzeba otworzyć pseudoterminalu (a pty) i rozmawiać z nim przy użyciu że zamiast tylko za pomocą stdin/stdout. Spójrz na moduł pexpect, który jest przeznaczony do tego właśnie.

Alternatywne rozwiązanie wymagałoby pewnego rodzaju pozapasmowego mechanizmu dystrybucji kluczy publicznych: na przykład skonfiguruj prostą aplikację internetową, w której ludzie mogą wkleić klucz publiczny i zarządzać plikiem authorized_keys w imieniu użytkownik.