~landscape/zope3/newer-from-ztk

« back to all changes in this revision

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

  • Committer: Thomas Hervé
  • Date: 2009-07-08 13:52:04 UTC
  • Revision ID: thomas@canonical.com-20090708135204-df5eesrthifpylf8
Remove twisted copy

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