1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  import select 
 20  import socket 
 21  import struct 
 22   
 23  from paramiko.common import * 
 24  from paramiko import util 
 25  from paramiko.channel import Channel 
 26  from paramiko.message import Message 
 27   
 28   
 29  CMD_INIT, CMD_VERSION, CMD_OPEN, CMD_CLOSE, CMD_READ, CMD_WRITE, CMD_LSTAT, CMD_FSTAT, \ 
 30             CMD_SETSTAT, CMD_FSETSTAT, CMD_OPENDIR, CMD_READDIR, CMD_REMOVE, CMD_MKDIR, \ 
 31             CMD_RMDIR, CMD_REALPATH, CMD_STAT, CMD_RENAME, CMD_READLINK, CMD_SYMLINK \ 
 32             = range(1, 21) 
 33  CMD_STATUS, CMD_HANDLE, CMD_DATA, CMD_NAME, CMD_ATTRS = range(101, 106) 
 34  CMD_EXTENDED, CMD_EXTENDED_REPLY = range(200, 202) 
 35   
 36  SFTP_OK = 0 
 37  SFTP_EOF, SFTP_NO_SUCH_FILE, SFTP_PERMISSION_DENIED, SFTP_FAILURE, SFTP_BAD_MESSAGE, \ 
 38           SFTP_NO_CONNECTION, SFTP_CONNECTION_LOST, SFTP_OP_UNSUPPORTED = range(1, 9) 
 39   
 40  SFTP_DESC = [ 'Success', 
 41                'End of file', 
 42                'No such file', 
 43                'Permission denied', 
 44                'Failure', 
 45                'Bad message', 
 46                'No connection', 
 47                'Connection lost', 
 48                'Operation unsupported' ] 
 49   
 50  SFTP_FLAG_READ = 0x1 
 51  SFTP_FLAG_WRITE = 0x2 
 52  SFTP_FLAG_APPEND = 0x4 
 53  SFTP_FLAG_CREATE = 0x8 
 54  SFTP_FLAG_TRUNC = 0x10 
 55  SFTP_FLAG_EXCL = 0x20 
 56   
 57  _VERSION = 3 
 58   
 59   
 60   
 61  CMD_NAMES = { 
 62      CMD_INIT: 'init', 
 63      CMD_VERSION: 'version', 
 64      CMD_OPEN: 'open', 
 65      CMD_CLOSE: 'close', 
 66      CMD_READ: 'read', 
 67      CMD_WRITE: 'write', 
 68      CMD_LSTAT: 'lstat', 
 69      CMD_FSTAT: 'fstat', 
 70      CMD_SETSTAT: 'setstat', 
 71      CMD_FSETSTAT: 'fsetstat', 
 72      CMD_OPENDIR: 'opendir', 
 73      CMD_READDIR: 'readdir', 
 74      CMD_REMOVE: 'remove', 
 75      CMD_MKDIR: 'mkdir', 
 76      CMD_RMDIR: 'rmdir', 
 77      CMD_REALPATH: 'realpath', 
 78      CMD_STAT: 'stat', 
 79      CMD_RENAME: 'rename', 
 80      CMD_READLINK: 'readlink', 
 81      CMD_SYMLINK: 'symlink', 
 82      CMD_STATUS: 'status', 
 83      CMD_HANDLE: 'handle', 
 84      CMD_DATA: 'data', 
 85      CMD_NAME: 'name', 
 86      CMD_ATTRS: 'attrs', 
 87      CMD_EXTENDED: 'extended', 
 88      CMD_EXTENDED_REPLY: 'extended_reply' 
 89      } 
 90   
 91   
 94   
 95   
101   
102   
103       
104   
105   
107          self._send_packet(CMD_INIT, struct.pack('>I', _VERSION)) 
108          t, data = self._read_packet() 
109          if t != CMD_VERSION: 
110              raise SFTPError('Incompatible sftp protocol') 
111          version = struct.unpack('>I', data[:4])[0] 
112           
113           
114          return version 
 115   
117           
118           
119          t, data = self._read_packet() 
120          if t != CMD_INIT: 
121              raise SFTPError('Incompatible sftp protocol') 
122          version = struct.unpack('>I', data[:4])[0] 
123           
124          extension_pairs = [ 'check-file', 'md5,sha1' ] 
125          msg = Message() 
126          msg.add_int(_VERSION) 
127          msg.add(*extension_pairs) 
128          self._send_packet(CMD_VERSION, str(msg)) 
129          return version 
 130           
131 -    def _log(self, level, msg, *args): 
 133   
135          while len(out) > 0: 
136              n = self.sock.send(out) 
137              if n <= 0: 
138                  raise EOFError() 
139              if n == len(out): 
140                  return 
141              out = out[n:] 
142          return 
 143   
145          out = '' 
146          while n > 0: 
147              if isinstance(self.sock, socket.socket): 
148                   
149                   
150                   
151                   
152                   
153                  while True: 
154                      read, write, err = select.select([ self.sock ], [], [], 0.1) 
155                      if len(read) > 0: 
156                          x = self.sock.recv(n) 
157                          break 
158              else: 
159                  x = self.sock.recv(n) 
160                   
161              if len(x) == 0: 
162                  raise EOFError() 
163              out += x 
164              n -= len(x) 
165          return out 
 166   
168           
169          out = struct.pack('>I', len(packet) + 1) + chr(t) + packet 
170          if self.ultra_debug: 
171              self._log(DEBUG, util.format_binary(out, 'OUT: ')) 
172          self._write_all(out) 
 173   
175          x = self._read_all(4) 
176           
177           
178          if x[0] != '\x00': 
179              raise SFTPError('Garbage packet received') 
180          size = struct.unpack('>I', x)[0] 
181          data = self._read_all(size) 
182          if self.ultra_debug: 
183              self._log(DEBUG, util.format_binary(data, 'IN: ')); 
184          if size > 0: 
185              t = ord(data[0]) 
186               
187              return t, data[1:] 
188          return 0, '' 
  189