關(guān)于顯式TLS和隱式TLS
為了提高FTP的安全性,我們使用了FTPS。FTPS是建立在SSL協(xié)議上一種增強型FTP協(xié)議。但是SSL安全拓展至少有兩種不同的初始化方法:顯式完全和隱式安全
- 顯式安全:當(dāng)啟用顯式模式時,用戶連接和FTP連接方式和默認端口一樣,然后需要以命令A(yù)UTH SSL/TLS類型的命令進行激活安全連接;
- 隱式安全:當(dāng)啟用隱式模式時,F(xiàn)TP的默認端口將修改為TCP/990,服務(wù)器自動建立安全連接,同時客戶端也要支持才安全連接模式的建立才行;
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
客戶端實現(xiàn)
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()