| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2007 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 | |
| 11 from twisted.python import log, usage, randbytes | |
| 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']), randbytes.secureRandom) | |
| 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']), randbytes.secureRandom) | |
| 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 = opt
ions['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 = opt
ions['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 | |
| OLD | NEW |