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