управление шпатлевкой с помощью Попена


Я пишу скрипт на python для генерации SSH-ключей для пользователей. После их генерации с помощью ssh-keygen, я хотел бы использовать puttygen для создания .файл ppk. К сожалению, puttygen не позволяет парольной фразе предоставляться в командной строке - поэтому я пытаюсь передать их в свой stdin с помощью popen. Он всегда жалуется на "неправильную парольную фразу", но ввод команд в командной строке и ввод парольной фразы там работает нормально - проблема в моей технике popen. puttygen трижды запрашивает пароль-один раз для чтения ключа, сгенерированного openssh, и два раза для ключа для нового файла. Puttygen сообщает об ошибке после первого запроса, поэтому проблема заключается в моей попытке отправить парольную фразу в подпроцесс.

Платформа-Ubuntu 11.10, python 2.7, последние пакеты openssh и putty-tools. Вот вырезанный сценарий, чтобы проиллюстрировать проблему, с которой я столкнулся:
#!/usr/bin/python
import sys, os, subprocess

KEYGEN = "/usr/bin/ssh-keygen -t rsa -b 4096 -f id_rsa -N passphrase"
PUTTYGEN = "/usr/bin/puttygen id_rsa -P -O private -o test.ppk"
phrase = "passphrase"

try:
    os.unlink('id_rsa')
except:
    pass

try:
    os.unlink('id_rsa.pub')
except:
    pass

try:
    os.unlink('test.ppk')
except:
    pass

## generate the public and private keys
subprocess.call(KEYGEN.split(' '))

## convert key to PuTTY format
p = subprocess.Popen(PUTTYGEN.split(' '), 
                     stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)

## Two techniques I've tried - also tried variations on CR/LF.  No luck.
if False:
    o, e = p.communicate(phrase + 'n' + phrase + 'n' + phrase + 'n')
    #o, e = p.communicate(phrase + 'r' + phrase + 'r' + phrase + 'r')
    #o, e = p.communicate(phrase + 'rn' + phrase + 'rn' + phrase + 'rn')

    print o
    print e

else:
    p.stdin.write(phrase + 'n')
    p.stdin.write(phrase + 'n')
    p.stdin.write(phrase + 'n')

    print p.stdout.read()
    print p.stderr.read()
    p.stdin.close()

    p.wait()
2 3

2 ответа:

Похоже, что puttygen читает все три парольные фразы как первую. Самое простое решение-вставить

time.sleep(0.1) 

Между

p.stdin.write(phrase + '\n')

Puttygen (0.69 в моем случае) имеет новые опции: '--old-passphrase file' - указать файл, содержащий старую ключевую фразу, '--new-passphrase file' - указать файл, содержащий новую ключевую фразу. Он отвечает на парольную фразу Через вопрос "stdin".