让python的FTP_TLS支持implicit ssl/tls FTP

python自带的ftplib中有FTP_TLS类,支持连接带ssl的FTP。但implicitssl/tls FTP要求客户端在建立socket链接之后立刻用 ssl/tls 加密,否则不会发送欢迎信息。由于FTP_TLS并没有重载基类FTP的connect方法,因此并不能和implicit  ssl/tls FTP正确连接。我们需要修改FTP_TLS来解决次问题。采用继承的方法,代码如下:


class tyFTP(FTP_TLS):
	def __init__(self, host='', user='', passwd='', acct='', keyfile=None,
		certfile=None, timeout=60):
		FTP_TLS.__init__(self, host, user, passwd, acct, keyfile, certfile, timeout)
	def connect(self, host='', port=0, timeout=-999):
		'''Connect to host.  Arguments are:
		- host: hostname to connect to (string, default previous host)
		- port: port to connect to (integer, default previous port)
		'''
		if host != '':
			self.host = host
		if port > 0:
			self.port = port
		if timeout != -999:
			self.timeout = timeout
		try:
			self.sock = socket.create_connection((self.host, self.port), self.timeout)
			self.af = self.sock.family
			#add this line!!!
			self.sock = ssl.wrap_socket(self.sock, self.keyfile, self.certfile,ssl_version=ssl.PROTOCOL_TLSv1)
			#add end
			self.file = self.sock.makefile('rb')
			self.welcome = self.getresp()
		except Exception as e:
			print e
		return self.welcome

这样就能成功connect到implicit  ssl/tls ftp的端口了(一般是990)。login也不会有问题。在login之后需要调用prot_p()方法,标明之后的数据通信都进行 ssl/tls 加密,才能正确的执行ftp指令。

关于implicit  ssl/tls ftp,大概介绍如下:

以FTP/SSL为例:

隐式TLS-服务器在990端口监听,客户端建立TCP连接,然后建立SSL连接,然后进行USER PASS的ftp 认证。其间是没有 AUTH TLS这种特殊command的。

显式TLS-服务器仍然在21端口监听,客户端正常发起tcp连接、服务器返回hello、客户端发起AUTH TLS-至此建立了TLS认证,以后才是加密状态。如果服务器设置了必须使用TLS,则当server hello后,客户端试图不建立SSL连接而直接进行USER PASS的ftp认证,服务器会踢掉客户端。

简而言之:

隐式TLS-干脆利落,服务器listen一个单独端口,上来就直接SSL加密,然后才建立应用层会话。

显式TLS-保持最大的兼容性,还是混在原来的端口,只是应用层会话一旦建立,就用特殊的命令来建立SSL会话。

所谓隐式TLS/显式TLS,区别主要在是否独立开监听端口上。

隐式TLS的实现,都是要求服务器单独listen一个特殊端口,客户端连接后直接建立SSL会话,然后再进行应用协议的command,整个过程都是加密的;而显式TLS的实现,是在原应用协议的基础上改进,增加了TLS认证的command,并且server不占用单独的端口。

你可能感兴趣的:(python,ftp)