1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """
20 Useful functions used by the rest of paramiko.
21 """
22
23 from __future__ import generators
24
25 import array
26 from binascii import hexlify, unhexlify
27 import sys
28 import struct
29 import traceback
30 import threading
31
32 from paramiko.common import *
33 from paramiko.config import SSHConfig
34
35
36
37 if sys.version_info < (2,3):
40 self.sequence = sequence
42 count = 0
43 for item in self.sequence:
44 yield (count, item)
45 count += 1
46
47
49 "turns a normalized byte string into a long-int (adapted from Crypto.Util.number)"
50 out = 0L
51 negative = 0
52 if not always_positive and (len(s) > 0) and (ord(s[0]) >= 0x80):
53 negative = 1
54 if len(s) % 4:
55 filler = '\x00'
56 if negative:
57 filler = '\xff'
58 s = filler * (4 - len(s) % 4) + s
59 for i in range(0, len(s), 4):
60 out = (out << 32) + struct.unpack('>I', s[i:i+4])[0]
61 if negative:
62 out -= (1L << (8 * len(s)))
63 return out
64
66 "turns a long-int into a normalized byte string (adapted from Crypto.Util.number)"
67
68 s = ''
69 n = long(n)
70 while (n != 0) and (n != -1):
71 s = struct.pack('>I', n & 0xffffffffL) + s
72 n = n >> 32
73
74 for i in enumerate(s):
75 if (n == 0) and (i[1] != '\000'):
76 break
77 if (n == -1) and (i[1] != '\xff'):
78 break
79 else:
80
81 i = (0,)
82 if n == 0:
83 s = '\000'
84 else:
85 s = '\xff'
86 s = s[i[0]:]
87 if add_sign_padding:
88 if (n == 0) and (ord(s[0]) >= 0x80):
89 s = '\x00' + s
90 if (n == -1) and (ord(s[0]) < 0x80):
91 s = '\xff' + s
92 return s
93
103
113
118
120 return hexlify(s).upper()
121
124
126 out = ''
127 for c in s:
128 if (ord(c) >= 32) and (ord(c) <= 127):
129 out += c
130 else:
131 out += '%%%02X' % ord(c)
132 return out
133
134
135
137 norm = deflate_long(n, 0)
138 hbyte = ord(norm[0])
139 if hbyte == 0:
140 return 1
141 bitlen = len(norm) * 8
142 while not (hbyte & 0x80):
143 hbyte <<= 1
144 bitlen -= 1
145 return bitlen
146
148 return ''.join(traceback.format_exception(*sys.exc_info())).split('\n')
149
151 """
152 Given a password, passphrase, or other human-source key, scramble it
153 through a secure hash into some keyworthy bytes. This specific algorithm
154 is used for encrypting/decrypting private key files.
155
156 @param hashclass: class from L{Crypto.Hash} that can be used as a secure
157 hashing function (like C{MD5} or C{SHA}).
158 @type hashclass: L{Crypto.Hash}
159 @param salt: data to salt the hash with.
160 @type salt: string
161 @param key: human-entered password or passphrase.
162 @type key: string
163 @param nbytes: number of bytes to generate.
164 @type nbytes: int
165 @return: key data
166 @rtype: string
167 """
168 keydata = ''
169 digest = ''
170 if len(salt) > 8:
171 salt = salt[:8]
172 while nbytes > 0:
173 hash_obj = hashclass.new()
174 if len(digest) > 0:
175 hash_obj.update(digest)
176 hash_obj.update(key)
177 hash_obj.update(salt)
178 digest = hash_obj.digest()
179 size = min(nbytes, len(digest))
180 keydata += digest[:size]
181 nbytes -= size
182 return keydata
183
185 """
186 Read a file of known SSH host keys, in the format used by openssh, and
187 return a compound dict of C{hostname -> keytype ->} L{PKey <paramiko.pkey.PKey>}.
188 The hostname may be an IP address or DNS name. The keytype will be either
189 C{"ssh-rsa"} or C{"ssh-dss"}.
190
191 This type of file unfortunately doesn't exist on Windows, but on posix,
192 it will usually be stored in C{os.path.expanduser("~/.ssh/known_hosts")}.
193
194 Since 1.5.3, this is just a wrapper around L{HostKeys}.
195
196 @param filename: name of the file to read host keys from
197 @type filename: str
198 @return: dict of host keys, indexed by hostname and then keytype
199 @rtype: dict(hostname, dict(keytype, L{PKey <paramiko.pkey.PKey>}))
200 """
201 from paramiko.hostkeys import HostKeys
202 return HostKeys(filename)
203
211
213 """
214 Provided only as a backward-compatible wrapper around L{SSHConfig}.
215 """
216 return config.lookup(hostname)
217
219
220 u1, u2, u3 = 1, 0, m
221 v1, v2, v3 = 0, 1, x
222
223 while v3 > 0:
224 q = u3 // v3
225 u1, v1 = v1, u1 - v1 * q
226 u2, v2 = v2, u2 - v2 * q
227 u3, v3 = v3, u3 - v3 * q
228 if u2 < 0:
229 u2 += m
230 return u2
231
232 _g_thread_ids = {}
233 _g_thread_counter = 0
234 _g_thread_lock = threading.Lock()
248
250 "send paramiko logs to a logfile, if they're not already going somewhere"
251 l = logging.getLogger("paramiko")
252 if len(l.handlers) > 0:
253 return
254 l.setLevel(level)
255 f = open(filename, 'w')
256 lh = logging.StreamHandler(f)
257 lh.setFormatter(logging.Formatter('%(levelname)-.3s [%(asctime)s.%(msecs)03d] thr=%(_threadid)-3d %(name)s: %(message)s',
258 '%Y%m%d-%H:%M:%S'))
259 l.addHandler(lh)
260
261
266 _pfilter = PFilter()
267
272
273
275 """Stateful counter for CTR mode crypto"""
276 - def __init__(self, nbits, initial_value=1L, overflow=0L):
277 self.blocksize = nbits / 8
278 self.overflow = overflow
279
280
281 if initial_value == 0:
282 self.value = array.array('c', '\xFF' * self.blocksize)
283 else:
284 x = deflate_long(initial_value - 1, add_sign_padding=False)
285 self.value = array.array('c', '\x00' * (self.blocksize - len(x)) + x)
286
288 """Increament the counter and return the new value"""
289 i = self.blocksize - 1
290 while i > -1:
291 c = self.value[i] = chr((ord(self.value[i]) + 1) % 256)
292 if c != '\x00':
293 return self.value.tostring()
294 i -= 1
295
296 x = deflate_long(self.overflow, add_sign_padding=False)
297 self.value = array.array('c', '\x00' * (self.blocksize - len(x)) + x)
298 return self.value.tostring()
299
300 - def new(cls, nbits, initial_value=1L, overflow=0L):
301 return cls(nbits, initial_value=initial_value, overflow=overflow)
302 new = classmethod(new)
303