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