python 登录sftp 2FA 双因素认证登录(password+key)

import os
import threading

import paramiko
import threadpool
import time


def creat_path(Dir):
# localPath = filePath.rpartition("/")[0]
if not os.path.exists(Dir):
os.makedirs(Dir)


def save_log(content):
creat_path('log')
log = open('log/log' + time.strftime("_%Y-%m-%d", time.localtime()) + '.txt', "a")
log.write(time.strftime("%Y-%m-%d %H:%M:%S ", time.localtime()) + content + "\n")





def getparam():
map = {}
with open("sftplogin.properties", "r") as f:
count = len(f.readlines())

with open("sftplogin.properties", "r") as f:
for line in range(count):
data = f.readline()
# 去除首位空格和换行符
data = data.strip().replace('\n', '')
if data[:4] == "user":
tag = data.split("=")[0][4:]
param = data.split("=")[0]
value = data.split("=")[1]
sftpdict = {param: value}
map[str(tag)] = sftpdict

if data[:8] == "password":
param = data.split("=")[0]
value = data.split(param + '=')[1]
map[str(tag)][param] = value

if data[:4] == "port":
param = data.split("=")[0]
value = data.split("=")[1]
map[str(tag)][param] = value

if data[:4] == "host":
param = data.split("=")[0]
value = data.split("=")[1]
map[str(tag)][param] = value

if data[:3] == "key":
param = data.split("=")[0]
value = data.split("=")[1]
map[str(tag)][param] = value

if data[:9] == "keypasswd":
param = data.split("=")[0]
value = data.split("=")[1]
map[str(tag)][param] = value

if data[:7] == "filedir":
param = data.split("=")[0]
value = data.split("=")[1]
map[str(tag)][param] = value

if data[:9] == "uploaddir":
param = data.split("=")[0]
value = data.split("=")[1]
map[str(tag)][param] = value

return map


def getfile(filedir):
listfile = []
for root, dirs, files in os.walk(filedir):
for f in files:
listfile.append(os.path.join(root, f))
return listfile


def userinfo(i):
listfile = []
user = map[i]["user" + i]
password = map[i]["password" + i]
key = map[i]["key" + i]
keypasswd = map[i]["keypasswd" + i]
port = int(map[i]["port" + i])
host = map[i]["host" + i]
filedir = map[i]["filedir" + i]
uploaddir = map[i]["uploaddir" + i]
if os.path.exists(filedir):
listfile = getfile(filedir)
else:
print(filedir + "目录不存在本地")
save_log(filedir + "目录不存在本地")
return {"user": user, "password": password, "key": key, "keypasswd": keypasswd, "port": port, "host": host,
"listfile": listfile, "uploaddir": uploaddir}


def sftplogin(user, password, key, keypasswd, port, host):
# paramiko log
creat_path('./log/paramiko/')
paramiko.util.log_to_file('./log/paramiko/log' + time.strftime("_%Y-%m-%d", time.localtime()))
paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
try:
pkey = paramiko.RSAKey.from_private_key_file(key, keypasswd)
transport = paramiko.Transport((host, port))
transport.start_client()
transport.get_remote_server_key()
# auth the public key as usual, auth service now is activated on server
transport.auth_publickey(username=user, key=pkey)

event = threading.Event()
auth_handler = paramiko.auth_handler.AuthHandler(transport)
transport.auth_handler = auth_handler
transport.lock.acquire()
try:
auth_handler.auth_event = event
auth_handler.auth_method = 'password'
auth_handler.username = user
auth_handler.password = password
message = paramiko.Message().add_string('ssh-userauth')
message.rewind()
auth_handler._parse_service_accept(message)
finally:
transport.lock.release()
auth_handler.wait_for_response(event)

# transport.auth_password(username=user,password=password)
# try to send another userauth request without request auth service
# m = paramiko.Message()
# m.add_byte(paramiko.common.cMSG_USERAUTH_REQUEST)
# m.add_string(user)
# m.add_string('ssh-connection')
# m.add_string('password')
# m.add_boolean(False)
# py3_password = paramiko.py3compat.u(password)
# m.add_string(py3_password)
# transport._send_message(m)
return transport
except Exception as e:
print("私钥错误" + str(e))
save_log("私钥错误" + str(e))


lock = threading.RLock()


def putfile(sftp_client, file, dir):
try:

filename = os.path.basename(file)
print("uplodad filename: " + str(filename))
save_log("uplodad filename: " + str(filename))
lock.acquire()
sftp_client.put(file, dir + '/' + filename)
lock.release()
print("uplodad filename: " + str(filename) + " is success")
save_log("uplodad filename: " + str(filename) + " is success")
except Exception as e:
print(e)
save_log(e)


if __name__ == '__main__':
# sftplogin('sftp01', '123456', r'C:\Users\YANG\Desktop\logDir\id_rsa', '123456', 19000, '192.168.109.140',
# r'C:\Users\YANG\Desktop\logDir\id_rsa')
countfile = 0
map = getparam()
print(map)
starttimestamp = time.time()
startTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
print('开始时间:' + startTime)
save_log('开始时间:' + startTime)
for i in (list(map.keys())):
userfilecount = 0
print(i)
list_task = []
list_userinfo = userinfo(i)
transport = sftplogin(list_userinfo["user"], list_userinfo["password"], list_userinfo["key"],
list_userinfo["keypasswd"],
list_userinfo["port"], list_userinfo["host"])
list_file = list_userinfo["listfile"]
try:

sftp_client = paramiko.SFTPClient.from_transport(transport)
save_log("success")
for file in list_file:
userfilecount += 1
list_task.append(((sftp_client, file, list_userinfo["uploaddir"]), None))
# 创建线程池
pool = threadpool.ThreadPool(10)
requests = threadpool.makeRequests(putfile, list_task)
[pool.putRequest(req) for req in requests]
pool.wait()
transport.close()
except Exception as e:
print("用户:" + list_userinfo["user"] + "登录失败,检查密码和私钥密码是否正确 " + str(e))
save_log("用户:" + list_userinfo["user"] + "登录失败,检查密码和私钥密码是否正确 " + str(e))
countfile = countfile + userfilecount
print("用户:" + list_userinfo["user"] + "上传文件数量为" + str(userfilecount))
save_log("用户:" + list_userinfo["user"] + "上传文件数量为" + str(userfilecount))
print("此次总共上传文件数量为" + str(countfile))
save_log("此次总共上传文件数量为" + str(countfile))
endtimestamp = time.time()
endTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
print('结束时间:' + endTime)
save_log('结束时间:' + endTime)
print('耗时:' + str(int(endtimestamp) - int(starttimestamp)) + 's')
save_log('耗时:' + str(int(endtimestamp) - int(starttimestamp)) + 's')




sftplogin.properties设置如下
user01=1234567891110210001
password01=FD088B290DB3EA21D4F4AB2644C7C9E3
port01=19000
host01=192.168.109.140
key01=C:\Users\YANG\Desktop\log_20221206\1214
keypasswd01=123456
filedir01=C:\Users\YANG\Desktop\logs
uploaddir01=/0121234567891110210001/inbox
#2
#user02=test01
#password02=123456
#port02=19000
#host02=192.168.109.140
#key02=C:\Users\YANG\Desktop\logDir\id_rsa
#keypasswd02=123456
#filedir02=C:\Users\YANG\Desktop\ssp_sea
#uploaddir02=/inbox





posted @ 2022-12-21 17:50  瘦阿瘦  阅读(270)  评论(0编辑  收藏  举报