Added SSL for Client and server. LIST still buggy.
This commit is contained in:
parent
6f22116691
commit
9cb37654fc
|
@ -0,0 +1,33 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
|
@ -0,0 +1,52 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDeXiMcayRnWBiP
|
||||
LCnEsLaDDBt3cIXHzLdT4R05FV1eJl9jlc3gxRG1YooBvfXoFJdxKDlL1GuBJRNR
|
||||
M2hRYJE3wa0iIXBagKIoE9n//2nCsvpZmsndAutfrKXQglA0LZzhIaamD5DmkN2Z
|
||||
CPg4ahEOXb5IFtt6qWKcmDXxbiN33PDVX5Xc1wvLnbLRBA+tPGUwNbeI/7BCLj62
|
||||
245rE0S7yKR3tOpJKIStuFYbuVTceuHjQ8Wh3F0mLPysNBJ7DtmWxku6jQSjysXJ
|
||||
2VwRDJcXo9TvNQfgwZTFJdese6+fYUb3ecSJX4C6JM3U6W67c5K/j9tXVgFfbFPq
|
||||
Jgt0xhfXhi/yR+ell/pee82CWEsTVgZCyaS8t6BE5K/Sx13+6jRm+yglnhSqkwrp
|
||||
3Xj0+hzrN9q6G+XlTF9mdr5jfuhC+DMfep64xxAfTEHanyrdvRzyxsuRF7fOWSVT
|
||||
PK2zCOW588NZg/pDgTvqEp4s4NCqvcgPPMjxf6cHGzLCmjC3hdLMkwVA6g7jVwBy
|
||||
NinfmRin44urPVAqxStiQ6grfZWqOoHYVCaWoHH8Rr1msSNPxCtU4/lwybROzDUy
|
||||
FHwd8eYbxuZ6Njd+s40GNOcQwhmExVekAq62lapnnos3ugVAfb2QcXy1fgwkdteq
|
||||
qfYYrC/HFDyOuzINjlJAn2grYopCuwIDAQABAoICADPZPVSWAuH535gakw6iqZu6
|
||||
yfi6iucAa8qqFbdGrQOT7O/6cQu0x6FEfatUUK8xhfJDj8CHoh11uKBZXTyESLf4
|
||||
d9cadukTTzwLDOys8EsOkmMsPV9EG/+t8OfCStMvw4GW6BWWUZIBOzpApif5S0rP
|
||||
PtvuQHTEZBLhRsqphKmhIaKO7BGXLs/mUFh+Gu2oxGtOSyIthDqaL9NRNE7xKjii
|
||||
2v5yd6JhSTZ8Yc+LEidqm5rzJXTNPgb1vGCmr5xz5PZL/EJeOTO7xwx+mwH6row7
|
||||
jh3Mfq7AVGD3puc328ZM11BC2zmwxAIjLL81QrWAiDoUX+9oRV+rkZFqF4e93Lbb
|
||||
21VCNB6elkNPTR+y6JhjLebhYfLQKPAIwEpUv4AKfLu9SX0bCUBDNfbxYHbS5qwO
|
||||
4ci196n7jCx/b2PpJT9X4TugiEijabw8rzKqW2Dgs67DOzsQLENp3ep+38KWAoay
|
||||
iS5eus85jNMaiuIUyOyWdsd1pMzwDqHIv05S7bpLYn+VrpmupCBShCKaUQ/uCfAp
|
||||
nV+U5TxmDsHiGOoP5C0OeAJefgHQTsxZGuWzPG2aTCG86u53pOQuWlm+3PTpoI4m
|
||||
QQ8Sw6blHNXCE9IQDIDnFdPSPZOjpro3vKnSnEtXUQuFoZVkMDWRym6rj1hO6dkj
|
||||
xx71RONwRynaKdXXPk0BAoIBAQD5Lf+JKGw2aIflr/fDpX0rpjexUWKMV/vg49LD
|
||||
0JoCeC5KqP7vJ5/+kFdreRp8d9xd9SSXLxiYVTtTjIz0vd9ADoD+IDPs584CgWl4
|
||||
1nipCzDvi4yXsrHtsKj6hni7Zo3SyMM4SI3xv0uVg6hHldsyT1VGCRK4z4ljuCjx
|
||||
qMPCkhSeaHViXqbrUsCs7wUPFtm0oD84XJT0c+wlTvJDUSz4QbKLOLhn8t7oHj/9
|
||||
6yRHzc5u57+wzdvhQP3phmMNSkJWS43NkMIN2NxvxZCPQTvwPCEcVjTVhMgmmzBl
|
||||
3lF0wIvMc28iiZz86TFfqMTyD4LeYKXWHLqk5o3Nf/idnYU7AoIBAQDkdESBtcdM
|
||||
nSXrGGGnJ12lL3E/v3R4HXHp6Idb/kuGXx9GafgNJ5ZkMX5epKGGajkGh2xYGFGV
|
||||
S7AlDl3Tm3rNdbG9PtJjrNrjiRFqLYqFBjk0x/7QaUzEKAxd0xqkyzwxmYXUQp85
|
||||
Eypz0p8BrvxAaaq6fDZpxS7SP5h3BoyyiXW6grRsgHUii3LfdlsIF1AKvcRnHAE/
|
||||
DFUNB40DA0EwaF+1MCMaYab6nrO9a3P2kJ7qZQwjpkWQVDZtBXKts7FAxbiyHfj2
|
||||
HzL8ThPkzPomu1W7pyFAHZ4FHZ7WM8z7rh1xvL9d8htrqHkFtzlR/OIyIrHjhyF4
|
||||
rknxFtrZXGCBAoIBAG5yphaslTKUqM/1bJQK8W18kqkFEvJ0OVAYi56CAxHfJV2w
|
||||
hLeKz88tOaKInmXXVxVKiLp+hJ9ZAB/rZ7s/wgoJo8GAkqOKp/TSWebW4crEDB/R
|
||||
sjK3YUijCnNpUXB3Z5uro2R6PHiQOzd9kQSR9wPYyEpv0R2b2CEcSwG6tXKz/3Gr
|
||||
iYRdwg0CtCazF4H1te/rK7qWxuuHyn9K+/U8sPslW7d8H7jrnUQzzFeHd6BgKAVe
|
||||
scfzp2ezwBhXmeYVKUxI1wTsCifLHQJqBsaIusGkVWTTDT4rSfBaz1wH7AEdK5om
|
||||
/HbJmo0768ej7hABMhfRrRA30b8v9mDFPXTXkmsCggEBANwVpmnPVVDZk84IjwsZ
|
||||
QX4BVnizWODefP96o+xb7yZkPRz4uZ7ypE+h3rwOng2AB6/iht3Xj8DkSa1pSbqx
|
||||
7nxBBhnqi4S64aSSR9SiSvAcLsBKa5Eb4HiYnFFHLkPUBwlBfUwfYoT5kcxC/CwD
|
||||
B8CGC5PcVg9PhuvFmHwSMzlMc75abLaaij3dWa0tuETzMIkoiC1NLWYv2z/SJmbg
|
||||
m8ymwI0s8qRXryWB/mZdPjoq2O22qxss85c3ibc9qFzu37QmxufROCbjp5qpHUEu
|
||||
t07Y6p79Q2shHTqQbpStEqzj8DnCPBmlRAVTKEP5X588oCzsf7NSW0yHm3RHME52
|
||||
UAECggEBAL0Y36LkkGzeV9v1+5mTfkGKKFpdTe1bAVOW/dX3wsE3UNooCd5Otta9
|
||||
fOC/JwcQr2t5rAVPbSz5Pk0x9nksaUBibYmq+E6kqP14OOTupbLVQiL84VpKU/8m
|
||||
bdF9NEL0k1S0kx39Z5X3z8oJe7tBpLRfetmL7Y20/yUs5oGhFep2AUSEUoWsr1i0
|
||||
RHCqlMvXjlqGYEBcKoq3/G8vnjBN9J04JKK8NWWS9wPSCHOtK27zexYB1M9VKj4q
|
||||
wB4hJ/EnphJUXcnn6AGWT0j33NVarmKEi83EO/PGaa+acU7y1gIR/O/9T04TEPQY
|
||||
jsryOfVmeGQ4HMfMdrYsCMTG4QBDo84=
|
||||
-----END PRIVATE KEY-----
|
70
client.py
70
client.py
|
@ -1,19 +1,34 @@
|
|||
import os
|
||||
import socket
|
||||
from socket import *
|
||||
import configparser
|
||||
import ssl
|
||||
import sys
|
||||
|
||||
CLIENT_FILE = "clientfile"
|
||||
BUFFER_SIZE = 1024
|
||||
|
||||
|
||||
# TODO: Buggy after some time, Not everything is transmitted
|
||||
def handle_list(conn, args):
|
||||
# send command over
|
||||
conn.sendall("LIST\r\n".encode())
|
||||
|
||||
num_of_files_received = 0
|
||||
num_of_files = int(conn.recv(BUFFER_SIZE).decode('utf-8'))
|
||||
print("Total files in directory: "+ str(num_of_files))
|
||||
num_of_files = 0
|
||||
# Receive response from server
|
||||
# Decode bytes to string
|
||||
response = conn.recv(BUFFER_SIZE).decode('utf-8').strip()
|
||||
try:
|
||||
num_of_files = int(response)
|
||||
except ValueError:
|
||||
print(response)
|
||||
return
|
||||
|
||||
while num_of_files_received < num_of_files:
|
||||
file_info = conn.recv(BUFFER_SIZE).decode('utf-8')
|
||||
print(file_info)
|
||||
# Print response
|
||||
print(conn.recv(BUFFER_SIZE).decode('utf-8').strip())
|
||||
num_of_files_received += 1
|
||||
response = conn.recv(BUFFER_SIZE).decode('utf-8')
|
||||
print(response)
|
||||
|
||||
|
||||
def handle_quit(conn, args):
|
||||
conn.sendall("QUIT\r\n".encode())
|
||||
|
@ -24,6 +39,7 @@ def handle_quit(conn, args):
|
|||
conn.close()
|
||||
return True
|
||||
|
||||
|
||||
def handle_DWLD(conn, args):
|
||||
# send command over
|
||||
filename = args
|
||||
|
@ -41,6 +57,7 @@ def handle_DWLD(conn, args):
|
|||
print(response)
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
def handle_UPLD(conn, args):
|
||||
filename = args
|
||||
os.chdir(os.path.abspath(CLIENT_FILE))
|
||||
|
@ -50,15 +67,15 @@ def handle_UPLD(conn, args):
|
|||
bytes_sent = 0
|
||||
file_size = os.path.getsize(filename)
|
||||
conn.sendall(f"UPLD {filename} {file_size}\r".encode())
|
||||
#does file exist at the server?
|
||||
# does file exist at the server?
|
||||
serverExist = conn.recv(BUFFER_SIZE).decode('utf-8')
|
||||
#if server already has the file
|
||||
# if server already has the file
|
||||
if serverExist == 'T':
|
||||
#do you want to overwrite?
|
||||
# do you want to overwrite?
|
||||
print(conn.recv(BUFFER_SIZE).decode('utf-8'))
|
||||
overwrite = input()
|
||||
conn.sendall(overwrite.encode('utf-8'))
|
||||
#yes, overwrite
|
||||
# yes, overwrite
|
||||
if overwrite.upper() == 'Y':
|
||||
with open(filename, "rb") as f:
|
||||
while bytes_sent < file_size:
|
||||
|
@ -68,12 +85,12 @@ def handle_UPLD(conn, args):
|
|||
response = conn.recv(BUFFER_SIZE).decode().strip()
|
||||
print(response)
|
||||
os.chdir("../")
|
||||
#no, dont overwrite
|
||||
# no, dont overwrite
|
||||
elif overwrite.upper() == 'N':
|
||||
response = conn.recv(BUFFER_SIZE).decode().strip()
|
||||
print(response)
|
||||
os.chdir("../")
|
||||
#server doesnt have the file
|
||||
# server doesnt have the file
|
||||
elif serverExist == 'F':
|
||||
print(conn.recv(BUFFER_SIZE).decode('utf-8'))
|
||||
with open(filename, "rb") as f:
|
||||
|
@ -85,11 +102,13 @@ def handle_UPLD(conn, args):
|
|||
print(response)
|
||||
os.chdir("../")
|
||||
|
||||
|
||||
def handle_HELP(conn, args):
|
||||
conn.sendall(f"HELP\r".encode())
|
||||
response = conn.recv(BUFFER_SIZE).decode('utf-8')
|
||||
print(response)
|
||||
|
||||
|
||||
def user_input():
|
||||
# Get user input
|
||||
user_input = input("> ").strip()
|
||||
|
@ -103,8 +122,12 @@ def user_input():
|
|||
return command, args
|
||||
|
||||
|
||||
def ftp_cient(host, port):
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
def ftp_client(host, port, cert):
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
context.load_verify_locations(cert)
|
||||
context.check_hostname = False
|
||||
|
||||
sock = context.wrap_socket(socket(AF_INET, SOCK_STREAM), server_hostname=host)
|
||||
sock.connect((host, port))
|
||||
|
||||
response = sock.recv(BUFFER_SIZE).decode().strip()
|
||||
|
@ -119,7 +142,7 @@ def ftp_cient(host, port):
|
|||
command, args = user_input, ""
|
||||
|
||||
if command.upper() == "LIST":
|
||||
sock.sendall("LIST\r\n".encode())
|
||||
# sock.sendall("LIST\r\n".encode())
|
||||
handle_list(sock, args)
|
||||
elif command.upper() == "QUIT":
|
||||
handle_quit(sock, args)
|
||||
|
@ -146,4 +169,17 @@ def ftp_cient(host, port):
|
|||
|
||||
if __name__ == "__main__":
|
||||
# FTP Client should be able to define IP and port
|
||||
ftp_cient("127.0.0.1", 2001)
|
||||
config = configparser.ConfigParser()
|
||||
config.read('./config/config.ini')
|
||||
ip = config['FTPSERVER']['ip']
|
||||
port = int(config['FTPSERVER']['port'])
|
||||
cert = config['SSL']['cert']
|
||||
|
||||
try:
|
||||
ftp_client(ip, port, cert)
|
||||
except KeyboardInterrupt:
|
||||
print("Client interrupted")
|
||||
try:
|
||||
sys.exit(0)
|
||||
except SystemExit:
|
||||
os._exit(0)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[FTPSERVER]
|
||||
ip = 127.0.0.1
|
||||
port = 5000
|
||||
|
||||
[SSL]
|
||||
cert = ./SSL/certificate.pem
|
||||
key = ./SSL/privatekey.pem
|
62
server.py
62
server.py
|
@ -5,17 +5,19 @@ import sys
|
|||
import threading
|
||||
import struct
|
||||
import time
|
||||
import configparser
|
||||
|
||||
BUFFER_SIZE = 1024
|
||||
SERVER_FILE = "serverfile"
|
||||
|
||||
# TODO: Buggy after some time, Not everything is transmitted
|
||||
def handle_list(conn, args):
|
||||
#conn.send(b'150 Opening ASCII mode data connection for file list.\n')
|
||||
#home_directory = os.path.expanduser('~')
|
||||
os.chdir(os.path.abspath(SERVER_FILE))
|
||||
files = os.listdir(os.getcwd())
|
||||
#send number of files over
|
||||
conn.sendall(str(len(files)).encode('utf-8'))
|
||||
conn.sendall(str(len(files)).encode('utf-8') +b'\r\n')
|
||||
|
||||
for file in files:
|
||||
file_info = os.stat(file)
|
||||
|
@ -29,7 +31,6 @@ def handle_list(conn, args):
|
|||
if not files:
|
||||
conn.sendall(b'226 No files in directory.\n')
|
||||
os.chdir("../")
|
||||
conn.sendall(b'226 Transfer complete.\n')
|
||||
|
||||
def handle_upload(conn, args):
|
||||
filename = args[1]
|
||||
|
@ -161,22 +162,28 @@ def handle_connection(conn):
|
|||
conn.sendall(b'220 Welcome to the FTP server.\n')
|
||||
|
||||
while True:
|
||||
|
||||
data = conn.recv(BUFFER_SIZE).decode()
|
||||
print(f'Server received: {data}')
|
||||
if not data:
|
||||
break
|
||||
args = data.split()
|
||||
command = args[0]
|
||||
print(f'Command: {command}')
|
||||
if command in commands:
|
||||
if commands == handle_quit:
|
||||
conn.sendall(b'Closing Connection')
|
||||
conn.close()
|
||||
try:
|
||||
data = conn.recv(BUFFER_SIZE).decode()
|
||||
print(f'Server received: {data}')
|
||||
if not data:
|
||||
break
|
||||
commands[command](conn, args)
|
||||
else:
|
||||
conn.sendall(b'Invalid command.\n')
|
||||
args = data.split()
|
||||
command = args[0]
|
||||
print(f'Command: {command}')
|
||||
if command in commands:
|
||||
if commands == handle_quit:
|
||||
conn.sendall(b'Closing Connection')
|
||||
conn.close()
|
||||
break
|
||||
commands[command](conn, args)
|
||||
else:
|
||||
conn.sendall(b'Invalid command.\n')
|
||||
except ConnectionResetError:
|
||||
print('Connection closed by client')
|
||||
break
|
||||
except OSError as e:
|
||||
print(e)
|
||||
break
|
||||
|
||||
# For FTP client testing
|
||||
#handle_pwd(conn, [])
|
||||
|
@ -192,12 +199,23 @@ def main():
|
|||
# print("Usage: python3 server.py <port>")
|
||||
# return
|
||||
|
||||
#context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
#context.load_cert_chain("certificate.pem", "privatekey.pem")
|
||||
config = configparser.ConfigParser()
|
||||
config.read('./config/config.ini')
|
||||
|
||||
port = 2001
|
||||
#server = context.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), server_side=True)
|
||||
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
# TODO: Need to allow user to define port through command line as well
|
||||
port = int(config['FTPSERVER']['port'])
|
||||
cert = config['SSL']['cert']
|
||||
key = config['SSL']['key']
|
||||
|
||||
# print(cert, key)
|
||||
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
# context.load_cert_chain("./SSL/certificate.pem", "./SSL/privatekey.pem")
|
||||
context.load_cert_chain(cert,key)
|
||||
|
||||
#port = 2001
|
||||
server = context.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), server_side=True)
|
||||
# server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
server.bind(('', port))
|
||||
server.listen(1)
|
||||
print("Listening on port", port)
|
||||
|
|
Loading…
Reference in New Issue