2012-05-11 6 views
5

Новое в Stackoverflow, так что сначала, привет.ssh с использованием python без ключей RSA

Я работаю над небольшим проектом для своей школы, который, как предполагается, является обычным gui (написанным на python как образовательный вызов для меня, поскольку я никогда не использовал python) для программы Unison с открытым исходным кодом. Мы пытаемся разрешить студентам и сотрудникам синхронизировать папку дома и в школу, запустив эту программу с минимальными затратами (идиот-защита, если хотите). Предполагается, что интерфейс - это только имя пользователя и пароль для школы, и оболочка gui должна просто отправить имя пользователя и пароль в Unison и синхронизировать их.

Проблема заключается в том, что Unison в свою очередь запускает SSh и запрашивает пароль, но метод python subprocess.communicate (input) не позволит ssh взять пароль. Я понял, что ssh будет принимать входные данные только от терминала, и я не могу понять, как его обмануть. Я читал некоторые вещи об использовании псевдотерминала, но я все еще в тупике. RSA-ключи были бы идеальным решением, но генерировать их, а затем размещать их на удаленном сервере все равно заставляют меня заходить с паролем хотя бы один раз, и для этого потребуется решение выше, или терминал, который не является идиотским доказательством.

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) 

Струны выполнение отлично работает в терминале там, если я вставить его. И любые вообще питона советы будут также иметь в виду, если вы так склонны.

Спасибо!

Unison Руководство пользователя: http://www.cis.upenn.edu/~bcpierce/unison/download/releases/stable/unison-manual.html

Edit: Я хотел бы также отметить, что в то время как я в настоящее время развивается под OSX и Linux, я в конце концов, придется сделать это окна совместимы, так как большинство студентов моей школы работать окна, как их первичной (или только) машины.

ответ

3

Посмотрите на pexpect.

import pexpect 

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

Я просто попробовал проверить этот проект с тем, что у вас там (очевидно, с фактическим хостом), и ничего не происходит. Незначительная пауза, а затем обратно в приглашение bash без сообщений. Я попытался добавить всю строку выполнения из моего кода выше, думая, что он просто закрывается, если ему ничего не дается, но он делает то же самое. – Hiroshi

+0

Убедитесь, что аргумент, который вы передаете child.expect(), соответствует запросу пароля, которое дает сервер. Кроме того, вам может потребоваться вызвать child.interact() после child.sendline (mypassword). Прошло некоторое время, так как я использовал pexpect, но это инструмент для работы. –

+0

Работал! Благодаря! :) – Hiroshi

2

Если вы хотите послать пароль ssh вам необходимо открыть псевдотерминала (а pty) и поговорить с ним, используя, что вместо того, чтобы просто используя stdin/stdout. Взгляните на модуль pexpect, который предназначен именно для этого.

Альтернативное решение будет включать в себя некий внеполосный механизм распространения открытых ключей: например, создать простое веб-приложение, в котором люди могут вставлять открытый ключ и управлять файлом authorized_keys от имени Пользователь.