用Popen控制puttygen

时间:2012-03-16 16:21:39

标签: python popen

我正在编写一个python脚本来为用户生成SSH密钥。在使用ssh-keygen生成它们之后,我想使用puttygen创建一个.ppk文件。不幸的是,puttygen不允许在命令行上提供密码短语 - 因此我试图使用popen将它们传输到stdin中。它总是抱怨'错误的密码短语',但是在命令行输入命令并输入密码短语就可以了。这个问题是我的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 + '\r\n' + phrase + '\r\n' + phrase + '\r\n')

    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 个答案:

答案 0 :(得分:1)

似乎puttygen读取所有三个密码短语作为第一个密码短语。最简单的解决方案是插入

time.sleep(0.1) 

之间

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

答案 1 :(得分:0)

puttygen(在我的情况下为0.69)有新选项:' - old-passphrase file' - 指定包含旧密钥密码的文件,' - new-passphrase file' - 指定包含新密钥密码的文件。它通过' stdin'来回答密码。问题。