35 <li>990: proxy usage is enabled but no proxy host given</li> |
35 <li>990: proxy usage is enabled but no proxy host given</li> |
36 <li>991: proxy usage is enabled but no proxy user given</li> |
36 <li>991: proxy usage is enabled but no proxy user given</li> |
37 <li>992: proxy usage is enabled but no proxy password given</li> |
37 <li>992: proxy usage is enabled but no proxy password given</li> |
38 </ul> |
38 </ul> |
39 """ |
39 """ |
|
40 |
40 pass |
41 pass |
41 |
42 |
42 |
43 |
43 class EricFtpProxyType(enum.Enum): |
44 class EricFtpProxyType(enum.Enum): |
44 """ |
45 """ |
45 Class defining the supported FTP proxy types. |
46 Class defining the supported FTP proxy types. |
46 """ |
47 """ |
47 NO_PROXY = 0 # no proxy |
48 |
48 NON_AUTHORIZING = 1 # non authorizing proxy |
49 NO_PROXY = 0 # no proxy |
49 USER_SERVER = 2 # proxy login first, than user@remote.host |
50 NON_AUTHORIZING = 1 # non authorizing proxy |
50 SITE = 3 # proxy login first, than use SITE command |
51 USER_SERVER = 2 # proxy login first, than user@remote.host |
51 OPEN = 4 # proxy login first, than use OPEN command |
52 SITE = 3 # proxy login first, than use SITE command |
52 USER_PROXYUSER_SERVER = 5 # one login for both |
53 OPEN = 4 # proxy login first, than use OPEN command |
|
54 USER_PROXYUSER_SERVER = 5 # one login for both |
53 PROXYUSER_SERVER = 6 |
55 PROXYUSER_SERVER = 6 |
54 # proxy login with remote host given, than normal remote login |
56 # proxy login with remote host given, than normal remote login |
55 AUTH_RESP = 7 # authenticate to proxy with AUTH and RESP commands |
57 AUTH_RESP = 7 # authenticate to proxy with AUTH and RESP commands |
56 BLUECOAT = 8 # bluecoat proxy |
58 BLUECOAT = 8 # bluecoat proxy |
57 |
59 |
58 |
60 |
59 class EricFtp(ftplib.FTP): |
61 class EricFtp(ftplib.FTP): |
60 """ |
62 """ |
61 Class implementing an extension to the Python FTP class to support FTP |
63 Class implementing an extension to the Python FTP class to support FTP |
62 proxies. |
64 proxies. |
63 """ |
65 """ |
64 def __init__(self, host="", user="", password="", acct="", # secok |
66 |
65 proxyType=EricFtpProxyType.NO_PROXY, proxyHost="", |
67 def __init__( |
66 proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="", |
68 self, |
67 proxyAccount="", timeout=_GLOBAL_DEFAULT_TIMEOUT): |
69 host="", |
|
70 user="", |
|
71 password="", |
|
72 acct="", # secok |
|
73 proxyType=EricFtpProxyType.NO_PROXY, |
|
74 proxyHost="", |
|
75 proxyPort=ftplib.FTP_PORT, |
|
76 proxyUser="", |
|
77 proxyPassword="", |
|
78 proxyAccount="", |
|
79 timeout=_GLOBAL_DEFAULT_TIMEOUT, |
|
80 ): |
68 """ |
81 """ |
69 Constructor |
82 Constructor |
70 |
83 |
71 @param host name of the FTP host |
84 @param host name of the FTP host |
72 @type str |
85 @type str |
73 @param user user name for login to FTP host |
86 @param user user name for login to FTP host |
74 @type str |
87 @type str |
75 @param password password for login to FTP host |
88 @param password password for login to FTP host |
90 @type str |
103 @type str |
91 @param timeout timeout in seconds for blocking operations |
104 @param timeout timeout in seconds for blocking operations |
92 @type int |
105 @type int |
93 """ |
106 """ |
94 super().__init__() |
107 super().__init__() |
95 |
108 |
96 self.__timeout = timeout |
109 self.__timeout = timeout |
97 |
110 |
98 self.__proxyType = proxyType |
111 self.__proxyType = proxyType |
99 self.__proxyHost = proxyHost |
112 self.__proxyHost = proxyHost |
100 self.__proxyPort = proxyPort |
113 self.__proxyPort = proxyPort |
101 self.__proxyUser = proxyUser |
114 self.__proxyUser = proxyUser |
102 self.__proxyPassword = proxyPassword |
115 self.__proxyPassword = proxyPassword |
103 self.__proxyAccount = proxyAccount |
116 self.__proxyAccount = proxyAccount |
104 |
117 |
105 self.__host = host |
118 self.__host = host |
106 self.__port = ftplib.FTP_PORT |
119 self.__port = ftplib.FTP_PORT |
107 self.__user = user |
120 self.__user = user |
108 self.__password = password |
121 self.__password = password |
109 self.__acct = acct |
122 self.__acct = acct |
110 |
123 |
111 if host: |
124 if host: |
112 self.connect(host) |
125 self.connect(host) |
113 if user: |
126 if user: |
114 self.login(user, password, acct) |
127 self.login(user, password, acct) |
115 |
128 |
116 def setProxy(self, proxyType=EricFtpProxyType.NO_PROXY, proxyHost="", |
129 def setProxy( |
117 proxyPort=ftplib.FTP_PORT, proxyUser="", proxyPassword="", |
130 self, |
118 proxyAccount=""): |
131 proxyType=EricFtpProxyType.NO_PROXY, |
|
132 proxyHost="", |
|
133 proxyPort=ftplib.FTP_PORT, |
|
134 proxyUser="", |
|
135 proxyPassword="", |
|
136 proxyAccount="", |
|
137 ): |
119 """ |
138 """ |
120 Public method to set the proxy configuration. |
139 Public method to set the proxy configuration. |
121 |
140 |
122 @param proxyType type of the FTP proxy |
141 @param proxyType type of the FTP proxy |
123 @type EricFtpProxyType |
142 @type EricFtpProxyType |
124 @param proxyHost name of the FTP proxy |
143 @param proxyHost name of the FTP proxy |
125 @type str |
144 @type str |
126 @param proxyPort port of the FTP proxy |
145 @param proxyPort port of the FTP proxy |
136 self.__proxyHost = proxyHost |
155 self.__proxyHost = proxyHost |
137 self.__proxyPort = proxyPort |
156 self.__proxyPort = proxyPort |
138 self.__proxyUser = proxyUser |
157 self.__proxyUser = proxyUser |
139 self.__proxyPassword = proxyPassword |
158 self.__proxyPassword = proxyPassword |
140 self.__proxyAccount = proxyAccount |
159 self.__proxyAccount = proxyAccount |
141 |
160 |
142 def setProxyAuthentication(self, proxyUser="", proxyPassword="", |
161 def setProxyAuthentication(self, proxyUser="", proxyPassword="", proxyAccount=""): |
143 proxyAccount=""): |
|
144 """ |
162 """ |
145 Public method to set the proxy authentication info. |
163 Public method to set the proxy authentication info. |
146 |
164 |
147 @param proxyUser user name for login to the proxy |
165 @param proxyUser user name for login to the proxy |
148 @type str |
166 @type str |
149 @param proxyPassword password for login to the proxy |
167 @param proxyPassword password for login to the proxy |
150 @type str |
168 @type str |
151 @param proxyAccount accounting info for the proxy |
169 @param proxyAccount accounting info for the proxy |
152 @type str |
170 @type str |
153 """ |
171 """ |
154 self.__proxyUser = proxyUser |
172 self.__proxyUser = proxyUser |
155 self.__proxyPassword = proxyPassword |
173 self.__proxyPassword = proxyPassword |
156 self.__proxyAccount = proxyAccount |
174 self.__proxyAccount = proxyAccount |
157 |
175 |
158 def connect(self, host="", port=0, timeout=-999): |
176 def connect(self, host="", port=0, timeout=-999): |
159 """ |
177 """ |
160 Public method to connect to the given FTP server. |
178 Public method to connect to the given FTP server. |
161 |
179 |
162 This extended method connects to the proxy instead of the given host, |
180 This extended method connects to the proxy instead of the given host, |
163 if a proxy is to be used. It throws an exception, if the proxy data |
181 if a proxy is to be used. It throws an exception, if the proxy data |
164 is incomplete. |
182 is incomplete. |
165 |
183 |
166 @param host name of the FTP host |
184 @param host name of the FTP host |
167 @type str |
185 @type str |
168 @param port port of the FTP host |
186 @param port port of the FTP host |
169 @type int |
187 @type int |
170 @param timeout timeout in seconds for blocking operations |
188 @param timeout timeout in seconds for blocking operations |
177 self.__host = host |
195 self.__host = host |
178 if port: |
196 if port: |
179 self.__port = port |
197 self.__port = port |
180 if timeout != -999: |
198 if timeout != -999: |
181 self.__timeout = timeout |
199 self.__timeout = timeout |
182 |
200 |
183 if self.__proxyType != EricFtpProxyType.NO_PROXY: |
201 if self.__proxyType != EricFtpProxyType.NO_PROXY: |
184 if not self.__proxyHost: |
202 if not self.__proxyHost: |
185 raise EricFtpProxyError( |
203 raise EricFtpProxyError( |
186 "990 Proxy usage requested, but no proxy host given.") |
204 "990 Proxy usage requested, but no proxy host given." |
187 |
205 ) |
188 return super().connect( |
206 |
189 self.__proxyHost, self.__proxyPort, self.__timeout) |
207 return super().connect(self.__proxyHost, self.__proxyPort, self.__timeout) |
190 else: |
208 else: |
191 return super().connect( |
209 return super().connect(self.__host, self.__port, self.__timeout) |
192 self.__host, self.__port, self.__timeout) |
210 |
193 |
211 def login(self, user="", password="", acct=""): # secok |
194 def login(self, user="", password="", acct=""): # secok |
|
195 """ |
212 """ |
196 Public method to login to the FTP server. |
213 Public method to login to the FTP server. |
197 |
214 |
198 This extended method respects the FTP proxy configuration. There are |
215 This extended method respects the FTP proxy configuration. There are |
199 many different FTP proxy products available. But unfortunately there |
216 many different FTP proxy products available. But unfortunately there |
200 is no standard for how o traverse a FTP proxy. The lis below shows |
217 is no standard for how o traverse a FTP proxy. The lis below shows |
201 the sequence of commands used. |
218 the sequence of commands used. |
202 |
219 |
203 <table> |
220 <table> |
204 <tr><td>user</td><td>Username for remote host</td></tr> |
221 <tr><td>user</td><td>Username for remote host</td></tr> |
205 <tr><td>pass</td><td>Password for remote host</td></tr> |
222 <tr><td>pass</td><td>Password for remote host</td></tr> |
206 <tr><td>pruser</td><td>Username for FTP proxy</td></tr> |
223 <tr><td>pruser</td><td>Username for FTP proxy</td></tr> |
207 <tr><td>prpass</td><td>Password for FTP proxy</td></tr> |
224 <tr><td>prpass</td><td>Password for FTP proxy</td></tr> |
208 <tr><td>remote.host</td><td>Hostname of the remote FTP server</td> |
225 <tr><td>remote.host</td><td>Hostname of the remote FTP server</td> |
209 </tr> |
226 </tr> |
210 </table> |
227 </table> |
211 |
228 |
212 <dl> |
229 <dl> |
213 <dt>EricFtpProxyType.NO_PROXY:</dt> |
230 <dt>EricFtpProxyType.NO_PROXY:</dt> |
214 <dd> |
231 <dd> |
215 USER user<br/> |
232 USER user<br/> |
216 PASS pass |
233 PASS pass |
283 """ |
300 """ |
284 if not user: |
301 if not user: |
285 user = "anonymous" |
302 user = "anonymous" |
286 if not password: |
303 if not password: |
287 # make sure it is a string |
304 # make sure it is a string |
288 password = "" # secok |
305 password = "" # secok |
289 if not acct: |
306 if not acct: |
290 # make sure it is a string |
307 # make sure it is a string |
291 acct = "" |
308 acct = "" |
292 if user == "anonymous" and password in {'', '-'}: |
309 if user == "anonymous" and password in {"", "-"}: |
293 password += "anonymous@" |
310 password += "anonymous@" |
294 |
311 |
295 if self.__proxyType != EricFtpProxyType.NO_PROXY: |
312 if self.__proxyType != EricFtpProxyType.NO_PROXY: |
296 if self.__proxyType != EricFtpProxyType.NON_AUTHORIZING: |
313 if self.__proxyType != EricFtpProxyType.NON_AUTHORIZING: |
297 # check, if a valid proxy configuration is known |
314 # check, if a valid proxy configuration is known |
298 if not self.__proxyUser: |
315 if not self.__proxyUser: |
299 raise EricFtpProxyError( |
316 raise EricFtpProxyError( |
300 "991 Proxy usage requested, but no proxy user given") |
317 "991 Proxy usage requested, but no proxy user given" |
|
318 ) |
301 if not self.__proxyPassword: |
319 if not self.__proxyPassword: |
302 raise EricFtpProxyError( |
320 raise EricFtpProxyError( |
303 "992 Proxy usage requested, but no proxy password" |
321 "992 Proxy usage requested, but no proxy password" " given" |
304 " given") |
322 ) |
305 |
323 |
306 if self.__proxyType in [EricFtpProxyType.NON_AUTHORIZING, |
324 if self.__proxyType in [ |
307 EricFtpProxyType.AUTH_RESP, |
325 EricFtpProxyType.NON_AUTHORIZING, |
308 EricFtpProxyType.BLUECOAT]: |
326 EricFtpProxyType.AUTH_RESP, |
|
327 EricFtpProxyType.BLUECOAT, |
|
328 ]: |
309 user += "@" + self.__host |
329 user += "@" + self.__host |
310 if self.__proxyType == EricFtpProxyType.BLUECOAT: |
330 if self.__proxyType == EricFtpProxyType.BLUECOAT: |
311 user += " " + self.__proxyUser |
331 user += " " + self.__proxyUser |
312 acct = self.__proxyPassword |
332 acct = self.__proxyPassword |
313 elif self.__proxyType == EricFtpProxyType.USER_PROXYUSER_SERVER: |
333 elif self.__proxyType == EricFtpProxyType.USER_PROXYUSER_SERVER: |
314 user = "{0}@{1}@{2}".format( |
334 user = "{0}@{1}@{2}".format(user, self.__proxyUser, self.__host) |
315 user, self.__proxyUser, self.__host) |
|
316 password = "{0}@{1}".format(password, self.__proxyPassword) |
335 password = "{0}@{1}".format(password, self.__proxyPassword) |
317 else: |
336 else: |
318 pruser = self.__proxyUser |
337 pruser = self.__proxyUser |
319 if self.__proxyType == EricFtpProxyType.USER_SERVER: |
338 if self.__proxyType == EricFtpProxyType.USER_SERVER: |
320 user += "@" + self.__host |
339 user += "@" + self.__host |
321 elif self.__proxyType == EricFtpProxyType.PROXYUSER_SERVER: |
340 elif self.__proxyType == EricFtpProxyType.PROXYUSER_SERVER: |
322 pruser += "@" + self.__host |
341 pruser += "@" + self.__host |
323 |
342 |
324 # authenticate to the proxy first |
343 # authenticate to the proxy first |
325 presp = self.sendcmd("USER " + pruser) |
344 presp = self.sendcmd("USER " + pruser) |
326 if presp[0] == "3": |
345 if presp[0] == "3": |
327 presp = self.sendcmd("PASS " + self.__proxyPassword) |
346 presp = self.sendcmd("PASS " + self.__proxyPassword) |
328 if presp[0] == "3" and self.__proxyAccount: |
347 if presp[0] == "3" and self.__proxyAccount: |
329 presp = self.sendcmd("ACCT " + self.__proxyAccount) |
348 presp = self.sendcmd("ACCT " + self.__proxyAccount) |
330 if presp[0] != "2": |
349 if presp[0] != "2": |
331 raise EricFtpProxyError( |
350 raise EricFtpProxyError( |
332 "9{0}0 Error authorizing at proxy\n{1}".format( |
351 "9{0}0 Error authorizing at proxy\n{1}".format(presp[0], presp) |
333 presp[0], presp)) |
352 ) |
334 |
353 |
335 if self.__proxyType == EricFtpProxyType.SITE: |
354 if self.__proxyType == EricFtpProxyType.SITE: |
336 # send SITE command |
355 # send SITE command |
337 presp = self.sendcmd("SITE " + self.__host) |
356 presp = self.sendcmd("SITE " + self.__host) |
338 if presp[0] != "2": |
357 if presp[0] != "2": |
339 raise EricFtpProxyError( |
358 raise EricFtpProxyError( |
340 "9{0}0 Error sending SITE command\n{1}".format( |
359 "9{0}0 Error sending SITE command\n{1}".format( |
341 presp[0], presp)) |
360 presp[0], presp |
|
361 ) |
|
362 ) |
342 elif self.__proxyType == EricFtpProxyType.OPEN: |
363 elif self.__proxyType == EricFtpProxyType.OPEN: |
343 # send OPEN command |
364 # send OPEN command |
344 presp = self.sendcmd("OPEN " + self.__host) |
365 presp = self.sendcmd("OPEN " + self.__host) |
345 if presp[0] != "2": |
366 if presp[0] != "2": |
346 raise EricFtpProxyError( |
367 raise EricFtpProxyError( |
347 "9{0}0 Error sending OPEN command\n{1}".format( |
368 "9{0}0 Error sending OPEN command\n{1}".format( |
348 presp[0], presp)) |
369 presp[0], presp |
349 |
370 ) |
|
371 ) |
|
372 |
350 # authenticate to the remote host or combined to proxy and remote host |
373 # authenticate to the remote host or combined to proxy and remote host |
351 resp = self.sendcmd("USER " + user) |
374 resp = self.sendcmd("USER " + user) |
352 if resp[0] == "3": |
375 if resp[0] == "3": |
353 resp = self.sendcmd("PASS " + password) |
376 resp = self.sendcmd("PASS " + password) |
354 if resp[0] == "3": |
377 if resp[0] == "3": |
355 resp = self.sendcmd("ACCT " + acct) |
378 resp = self.sendcmd("ACCT " + acct) |
356 if resp[0] != "2": |
379 if resp[0] != "2": |
357 raise ftplib.error_reply(resp) # secok |
380 raise ftplib.error_reply(resp) # secok |
358 |
381 |
359 if self.__proxyType == EricFtpProxyType.AUTH_RESP: |
382 if self.__proxyType == EricFtpProxyType.AUTH_RESP: |
360 # authorize to the FTP proxy |
383 # authorize to the FTP proxy |
361 presp = self.sendcmd("AUTH " + self.__proxyUser) |
384 presp = self.sendcmd("AUTH " + self.__proxyUser) |
362 if presp[0] == "3": |
385 if presp[0] == "3": |
363 presp = self.sendcmd("RESP " + self.__proxyPassword) |
386 presp = self.sendcmd("RESP " + self.__proxyPassword) |
364 if presp[0] != "2": |
387 if presp[0] != "2": |
365 raise EricFtpProxyError( |
388 raise EricFtpProxyError( |
366 "9{0}0 Error authorizing at proxy\n{1}".format( |
389 "9{0}0 Error authorizing at proxy\n{1}".format(presp[0], presp) |
367 presp[0], presp)) |
390 ) |
368 |
391 |
369 return resp |
392 return resp |