关于显式TLS和隐式TLS
为了提高FTP
的安全性,我们使用了FTPS
。FTPS
是建立在SSL
协议上一种增强型FTP
协议。但是SSL
安全拓展至少有两种不同的初始化方法:显式完全和隐式安全
- 显式安全:当启用显式模式时,用户连接和FTP连接方式和默认端口一样,然后需要以命令AUTH SSL/TLS类型的命令进行激活安全连接;
- 隐式安全:当启用隐式模式时,FTP的默认端口将修改为TCP/990,服务器自动建立安全连接,同时客户端也要支持才安全连接模式的建立才行;
python自带的ftplib中有FTP_TLS类
FTP_TLS
类默认是不支持隐式的链接,为了支持隐式的链接就必须改写connect
方法
from ftplib import FTP_TLS
import ssl
import socket
class tyFTP(FTP_TLS):
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
客户端实现
import os
class FTPSClient(object):
def __init__(self, username, password, hostname, port=990):
self.username = username
self.password = password
self.hostname = hostname
self.port = port
def get_conn(self, ftp_class=tyFTP):
conn = ftp_class()
conn.connect(self.hostname, self.port)
conn.login(self.username, self.password)
conn.prot_p()
return conn
def upload(self, content, filename_server):
ftps = self.get_conn()
# filename_server = filename_server.ltrip("/")
dirname = os.path.dirname(filename_server)
try:
ftps.mkd(dirname)
except Exception as e:
if str(e) == "550 Directory already exists":
pass
else:
raise Exception(repr(e))
ftps.cwd(dirname)
bufsize = 1024
fp = open(content,'rb')
fp.seek(0)
try:
ftps.storbinary('STOR '+ os.path.basename(filename_server) ,fp,bufsize)
except Exception as e:
if str(e) == "[Errno 0] Error":
pass
else:
raise Exception("Upload error")
fp.close()
# ftps.set_debuglevel(0)
ftps.close()
网友评论