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 
  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