~certify-web-dev/twisted/certify-trunk

« back to all changes in this revision

Viewing changes to twisted/conch/scripts/ckeygen.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-17 14:52:35 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20070117145235-btmig6qfmqfen0om
Tags: 2.5.0-0ubuntu1
New upstream version, compatible with python2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
#
 
5
# $Id: ckeygen.py,v 1.8 2003/05/10 14:03:40 spiv Exp $
 
6
 
 
7
#""" Implementation module for the `ckeygen` command.
 
8
#"""
 
9
 
 
10
from twisted.conch.ssh import keys, common
 
11
from twisted.python import log, usage
 
12
 
 
13
import sys, os, getpass, md5, socket
 
14
if getpass.getpass == getpass.unix_getpass:
 
15
    try:
 
16
        import termios # hack around broken termios
 
17
        termios.tcgetattr, termios.tcsetattr
 
18
    except (ImportError, AttributeError):
 
19
        sys.modules['termios'] = None
 
20
        reload(getpass)
 
21
 
 
22
class GeneralOptions(usage.Options):
 
23
    synopsis = """Usage:    ckeygen [options] 
 
24
 """
 
25
 
 
26
    optParameters = [['bits', 'b', 1024, 'Number of bits in the key to create.'],
 
27
                     ['filename', 'f', None, 'Filename of the key file.'],
 
28
                     ['type', 't', None, 'Specify type of key to create.'],
 
29
                     ['comment', 'C', None, 'Provide new comment.'],
 
30
                     ['newpass', 'N', None, 'Provide new passphrase.'],
 
31
                     ['pass', 'P', None, 'Provide old passphrase']]
 
32
    
 
33
    optFlags = [['fingerprint', 'l', 'Show fingerprint of key file.'],
 
34
                ['changepass', 'p', 'Change passphrase of private key file.'],
 
35
                ['quiet', 'q', 'Quiet.'],
 
36
                ['showpub', 'y', 'Read private key file and print public key.']]
 
37
 
 
38
    #zsh_altArgDescr = {"bits":"Number of bits in the key (default: 1024)"}
 
39
    #zsh_multiUse = ["foo", "bar"]
 
40
    #zsh_mutuallyExclusive = [("foo", "bar"), ("bar", "baz")]
 
41
    zsh_actions = {"type":"(rsa dsa)"}
 
42
    #zsh_actionDescr = {"logfile":"log file name", "random":"random seed"}
 
43
 
 
44
def run():
 
45
    options = GeneralOptions()
 
46
    try:
 
47
        options.parseOptions(sys.argv[1:])
 
48
    except usage.UsageError, u:
 
49
        print 'ERROR: %s' % u
 
50
        options.opt_help()
 
51
        sys.exit(1)
 
52
    log.discardLogs()
 
53
    log.deferr = handleError # HACK
 
54
    if options['type']:
 
55
        if options['type'] == 'rsa':
 
56
            generateRSAkey(options)
 
57
        elif options['type'] == 'dsa':
 
58
            generateDSAkey(options)
 
59
        else:
 
60
            sys.exit('Key type was %s, must be one of: rsa, dsa' % options['type'])
 
61
    elif options['fingerprint']:
 
62
        printFingerprint(options)
 
63
    elif options['changepass']:
 
64
        changePassPhrase(options)
 
65
    elif options['showpub']:
 
66
        displayPublicKey(options)
 
67
    else:
 
68
        options.opt_help()
 
69
        sys.exit(1)
 
70
 
 
71
def handleError():
 
72
    from twisted.python import failure
 
73
    global exitStatus
 
74
    exitStatus = 2
 
75
    log.err(failure.Failure())
 
76
    reactor.stop()
 
77
    raise
 
78
 
 
79
def generateRSAkey(options):
 
80
    from Crypto.PublicKey import RSA
 
81
    print 'Generating public/private rsa key pair.'
 
82
    key = RSA.generate(int(options['bits']), common.entropy.get_bytes)
 
83
    _saveKey(key, options)
 
84
 
 
85
def generateDSAkey(options):
 
86
    from Crypto.PublicKey import DSA
 
87
    print 'Generating public/private dsa key pair.'
 
88
    key = DSA.generate(int(options['bits']), common.entropy.get_bytes)
 
89
    _saveKey(key, options)
 
90
 
 
91
def printFingerprint(options):
 
92
    if not options['filename']:
 
93
        filename = os.path.expanduser('~/.ssh/id_rsa')
 
94
        options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename)
 
95
    if os.path.exists(options['filename']+'.pub'):
 
96
        options['filename'] += '.pub'
 
97
    try:
 
98
        string = keys.getPublicKeyString(options['filename'])
 
99
        obj = keys.getPublicKeyObject(string)
 
100
        print '%s %s %s' % (
 
101
            obj.size()+1,
 
102
            ':'.join(['%02x' % ord(x) for x in md5.new(string).digest()]),
 
103
            os.path.basename(options['filename']))
 
104
    except:
 
105
        sys.exit('bad key')
 
106
 
 
107
def changePassPhrase(options):
 
108
    if not options['filename']:
 
109
        filename = os.path.expanduser('~/.ssh/id_rsa')
 
110
        options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename)
 
111
    try:
 
112
        key = keys.getPrivateKeyObject(options['filename'])
 
113
    except keys.BadKeyError, e:
 
114
        if e.args[0] != 'encrypted key with no passphrase':
 
115
            raise
 
116
        else:
 
117
            if not options['pass']:
 
118
                options['pass'] = getpass.getpass('Enter old passphrase: ')
 
119
            key = keys.getPrivateKeyObject(options['filename'], passphrase = options['pass'])
 
120
    if not options['newpass']:
 
121
        while 1:
 
122
            p1 = getpass.getpass('Enter new passphrase (empty for no passphrase): ')
 
123
            p2 = getpass.getpass('Enter same passphrase again: ')
 
124
            if p1 == p2:
 
125
                break
 
126
            print 'Passphrases do not match.  Try again.'
 
127
        options['newpass'] = p1
 
128
    open(options['filename'], 'w').write(
 
129
    keys.makePrivateKeyString(key, passphrase=options['newpass']))
 
130
    print 'Your identification has been saved with the new passphrase.' 
 
131
 
 
132
def displayPublicKey(options):
 
133
    if not options['filename']:
 
134
        filename = os.path.expanduser('~/.ssh/id_rsa')
 
135
        options['filename'] = raw_input('Enter file in which the key is (%s): ' % filename)
 
136
    try:
 
137
        key = keys.getPrivateKeyObject(options['filename'])
 
138
    except keys.BadKeyError, e:
 
139
        if e.args[0] != 'encrypted key with no passphrase':
 
140
            raise
 
141
        else:
 
142
            if not options['pass']:
 
143
                options['pass'] = getpass.getpass('Enter passphrase: ')
 
144
            key = keys.getPrivateKeyObject(options['filename'], passphrase = options['pass'])
 
145
    print keys.makePublicKeyString(key)
 
146
        
 
147
def _saveKey(key, options):
 
148
    if not options['filename']:
 
149
        kind = keys.objectType(key)
 
150
        kind = {'ssh-rsa':'rsa','ssh-dss':'dsa'}[kind]
 
151
        filename = os.path.expanduser('~/.ssh/id_%s'%kind)
 
152
        options['filename'] = raw_input('Enter file in which to save the key (%s): '%filename).strip() or filename
 
153
    if os.path.exists(options['filename']):
 
154
        print '%s already exists.' % options['filename']
 
155
        yn = raw_input('Overwrite (y/n)? ')
 
156
        if yn[0].lower() != 'y':
 
157
            sys.exit()
 
158
    if not options['pass']:
 
159
        while 1:
 
160
            p1 = getpass.getpass('Enter passphrase (empty for no passphrase): ')
 
161
            p2 = getpass.getpass('Enter same passphrase again: ')
 
162
            if p1 == p2:
 
163
                break
 
164
            print 'Passphrases do not match.  Try again.'
 
165
        options['pass'] = p1
 
166
    comment = '%s@%s' % (getpass.getuser(), socket.gethostname())
 
167
    open(options['filename'], 'w').write(
 
168
            keys.makePrivateKeyString(key, passphrase=options['pass']))
 
169
    os.chmod(options['filename'], 33152)
 
170
    open(options['filename']+'.pub', 'w').write(
 
171
            keys.makePublicKeyString(key, comment = comment))
 
172
    pubKey = keys.getPublicKeyString(data=keys.makePublicKeyString(key, comment=comment))
 
173
    print 'Your identification has been saved in %s' % options['filename']
 
174
    print 'Your public key has been saved in %s.pub' % options['filename']
 
175
    print 'The key fingerprint is:'
 
176
    print ':'.join(['%02x' % ord(x) for x in md5.new(pubKey).digest()])
 
177
 
 
178
if __name__ == '__main__':
 
179
    run()
 
180