Package paramiko :: Module util
[frames] | no frames]

Source Code for Module paramiko.util

  1  # Copyright (C) 2003-2007  Robey Pointer <robey@lag.net> 
  2  # 
  3  # This file is part of paramiko. 
  4  # 
  5  # Paramiko is free software; you can redistribute it and/or modify it under the 
  6  # terms of the GNU Lesser General Public License as published by the Free 
  7  # Software Foundation; either version 2.1 of the License, or (at your option) 
  8  # any later version. 
  9  # 
 10  # Paramiko is distrubuted in the hope that it will be useful, but WITHOUT ANY 
 11  # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 
 12  # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 13  # details. 
 14  # 
 15  # You should have received a copy of the GNU Lesser General Public License 
 16  # along with Paramiko; if not, write to the Free Software Foundation, Inc., 
 17  # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. 
 18   
 19  """ 
 20  Useful functions used by the rest of paramiko. 
 21  """ 
 22   
 23  from __future__ import generators 
 24   
 25  from binascii import hexlify, unhexlify 
 26  import sys 
 27  import struct 
 28  import traceback 
 29  import threading 
 30   
 31  from paramiko.common import * 
 32  from paramiko.config import SSHConfig 
 33   
 34   
 35  # Change by RogerB - python < 2.3 doesn't have enumerate so we implement it 
 36  if sys.version_info < (2,3): 
37 - class enumerate:
38 - def __init__ (self, sequence):
39 self.sequence = sequence
40 - def __iter__ (self):
41 count = 0 42 for item in self.sequence: 43 yield (count, item) 44 count += 1
45 46
47 -def inflate_long(s, always_positive=False):
48 "turns a normalized byte string into a long-int (adapted from Crypto.Util.number)" 49 out = 0L 50 negative = 0 51 if not always_positive and (len(s) > 0) and (ord(s[0]) >= 0x80): 52 negative = 1 53 if len(s) % 4: 54 filler = '\x00' 55 if negative: 56 filler = '\xff' 57 s = filler * (4 - len(s) % 4) + s 58 for i in range(0, len(s), 4): 59 out = (out << 32) + struct.unpack('>I', s[i:i+4])[0] 60 if negative: 61 out -= (1L << (8 * len(s))) 62 return out
63
64 -def deflate_long(n, add_sign_padding=True):
65 "turns a long-int into a normalized byte string (adapted from Crypto.Util.number)" 66 # after much testing, this algorithm was deemed to be the fastest 67 s = '' 68 n = long(n) 69 while (n != 0) and (n != -1): 70 s = struct.pack('>I', n & 0xffffffffL) + s 71 n = n >> 32 72 # strip off leading zeros, FFs 73 for i in enumerate(s): 74 if (n == 0) and (i[1] != '\000'): 75 break 76 if (n == -1) and (i[1] != '\xff'): 77 break 78 else: 79 # degenerate case, n was either 0 or -1 80 i = (0,) 81 if n == 0: 82 s = '\000' 83 else: 84 s = '\xff' 85 s = s[i[0]:] 86 if add_sign_padding: 87 if (n == 0) and (ord(s[0]) >= 0x80): 88 s = '\x00' + s 89 if (n == -1) and (ord(s[0]) < 0x80): 90 s = '\xff' + s 91 return s
92
93 -def format_binary_weird(data):
94 out = '' 95 for i in enumerate(data): 96 out += '%02X' % ord(i[1]) 97 if i[0] % 2: 98 out += ' ' 99 if i[0] % 16 == 15: 100 out += '\n' 101 return out
102
103 -def format_binary(data, prefix=''):
104 x = 0 105 out = [] 106 while len(data) > x + 16: 107 out.append(format_binary_line(data[x:x+16])) 108 x += 16 109 if x < len(data): 110 out.append(format_binary_line(data[x:])) 111 return [prefix + x for x in out]
112
113 -def format_binary_line(data):
114 left = ' '.join(['%02X' % ord(c) for c in data]) 115 right = ''.join([('.%c..' % c)[(ord(c)+63)//95] for c in data]) 116 return '%-50s %s' % (left, right)
117
118 -def hexify(s):
119 return hexlify(s).upper()
120
121 -def unhexify(s):
122 return unhexlify(s)
123
124 -def safe_string(s):
125 out = '' 126 for c in s: 127 if (ord(c) >= 32) and (ord(c) <= 127): 128 out += c 129 else: 130 out += '%%%02X' % ord(c) 131 return out
132 133 # ''.join([['%%%02X' % ord(c), c][(ord(c) >= 32) and (ord(c) <= 127)] for c in s]) 134
135 -def bit_length(n):
136 norm = deflate_long(n, 0) 137 hbyte = ord(norm[0]) 138 bitlen = len(norm) * 8 139 while not (hbyte & 0x80): 140 hbyte <<= 1 141 bitlen -= 1 142 return bitlen
143
144 -def tb_strings():
145 return ''.join(traceback.format_exception(*sys.exc_info())).split('\n')
146
147 -def generate_key_bytes(hashclass, salt, key, nbytes):
148 """ 149 Given a password, passphrase, or other human-source key, scramble it 150 through a secure hash into some keyworthy bytes. This specific algorithm 151 is used for encrypting/decrypting private key files. 152 153 @param hashclass: class from L{Crypto.Hash} that can be used as a secure 154 hashing function (like C{MD5} or C{SHA}). 155 @type hashclass: L{Crypto.Hash} 156 @param salt: data to salt the hash with. 157 @type salt: string 158 @param key: human-entered password or passphrase. 159 @type key: string 160 @param nbytes: number of bytes to generate. 161 @type nbytes: int 162 @return: key data 163 @rtype: string 164 """ 165 keydata = '' 166 digest = '' 167 if len(salt) > 8: 168 salt = salt[:8] 169 while nbytes > 0: 170 hash_obj = hashclass.new() 171 if len(digest) > 0: 172 hash_obj.update(digest) 173 hash_obj.update(key) 174 hash_obj.update(salt) 175 digest = hash_obj.digest() 176 size = min(nbytes, len(digest)) 177 keydata += digest[:size] 178 nbytes -= size 179 return keydata
180
181 -def load_host_keys(filename):
182 """ 183 Read a file of known SSH host keys, in the format used by openssh, and 184 return a compound dict of C{hostname -> keytype ->} L{PKey <paramiko.pkey.PKey>}. 185 The hostname may be an IP address or DNS name. The keytype will be either 186 C{"ssh-rsa"} or C{"ssh-dss"}. 187 188 This type of file unfortunately doesn't exist on Windows, but on posix, 189 it will usually be stored in C{os.path.expanduser("~/.ssh/known_hosts")}. 190 191 Since 1.5.3, this is just a wrapper around L{HostKeys}. 192 193 @param filename: name of the file to read host keys from 194 @type filename: str 195 @return: dict of host keys, indexed by hostname and then keytype 196 @rtype: dict(hostname, dict(keytype, L{PKey <paramiko.pkey.PKey>})) 197 """ 198 from paramiko.hostkeys import HostKeys 199 return HostKeys(filename)
200
201 -def parse_ssh_config(file_obj):
202 """ 203 Provided only as a backward-compatible wrapper around L{SSHConfig}. 204 """ 205 config = SSHConfig() 206 config.parse(file_obj) 207 return config
208
209 -def lookup_ssh_host_config(hostname, config):
210 """ 211 Provided only as a backward-compatible wrapper around L{SSHConfig}. 212 """ 213 return config.lookup(hostname)
214
215 -def mod_inverse(x, m):
216 # it's crazy how small python can make this function. 217 u1, u2, u3 = 1, 0, m 218 v1, v2, v3 = 0, 1, x 219 220 while v3 > 0: 221 q = u3 // v3 222 u1, v1 = v1, u1 - v1 * q 223 u2, v2 = v2, u2 - v2 * q 224 u3, v3 = v3, u3 - v3 * q 225 if u2 < 0: 226 u2 += m 227 return u2
228 229 _g_thread_ids = {} 230 _g_thread_counter = 0 231 _g_thread_lock = threading.Lock()
232 -def get_thread_id():
233 global _g_thread_ids, _g_thread_counter, _g_thread_lock 234 tid = id(threading.currentThread()) 235 try: 236 return _g_thread_ids[tid] 237 except KeyError: 238 _g_thread_lock.acquire() 239 try: 240 _g_thread_counter += 1 241 ret = _g_thread_ids[tid] = _g_thread_counter 242 finally: 243 _g_thread_lock.release() 244 return ret
245
246 -def log_to_file(filename, level=DEBUG):
247 "send paramiko logs to a logfile, if they're not already going somewhere" 248 l = logging.getLogger("paramiko") 249 if len(l.handlers) > 0: 250 return 251 l.setLevel(level) 252 f = open(filename, 'w') 253 lh = logging.StreamHandler(f) 254 lh.setFormatter(logging.Formatter('%(levelname)-.3s [%(asctime)s.%(msecs)03d] thr=%(_threadid)-3d %(name)s: %(message)s', 255 '%Y%m%d-%H:%M:%S')) 256 l.addHandler(lh)
257 258 # make only one filter object, so it doesn't get applied more than once
259 -class PFilter (object):
260 - def filter(self, record):
261 record._threadid = get_thread_id() 262 return True
263 _pfilter = PFilter() 264
265 -def get_logger(name):
266 l = logging.getLogger(name) 267 l.addFilter(_pfilter) 268 return l
269