seg/trabalho4/client.py

242 lines
6.0 KiB
Python

from AES import AESCipher
from random import randint
from common import *
import socket
import time
HOST = "127.0.0.1"
CLIENT_ID = None
KEY = None
SAVED_INFO = {}
def register_user(username, password):
global CLIENT_ID, KEY
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, AS_PORT))
message = f"register||{username}<>{password}"
s.sendall(message.encode())
data = s.recv(4096)
data = data.decode()
data = data.split("<>")
if data[0] == "success":
print("Login succeeded!")
CLIENT_ID = username
KEY = eval(data[1])
def login(username, password):
global CLIENT_ID, KEY
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, AS_PORT))
message = f"login||{username}<>{password}"
s.sendall(message.encode())
data = s.recv(4096)
data = data.decode()
data = data.split("<>")
if data[0] == "success":
print(f"Login succeeded!")
CLIENT_ID = username
KEY = eval(data[1])
def send_messages():
global CLIENT_ID, KEY
if CLIENT_ID is None:
print("You must register or login first!")
return
AES = AESCipher(KEY)
ID_C = CLIENT_ID
ID_S = "DOOR"
T_R = int(input("Enter the ticket lifetime (seconds): "))
N1 = randint(0, 1000000)
M2 = None
M4 = None
M6 = None
M1_inner = f"{ID_S}<>{T_R}<>{N1}"
M1_inner = AES.encrypt(M1_inner)
M1 = f"{ID_C}<>{M1_inner}"
message = f"request||{M1}"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, AS_PORT))
print('Sending M1', f'{ID_C}<>[{ID_S}<>{T_R}<>{N1}]')
s.sendall(message.encode())
data = s.recv(4096)
data = data.decode()
print('Received M2', data)
M2 = data
time.sleep(3)
'''
M2 = [{K_c_tgs + N_1}Kc + T_c_tgs]
M3 = [{ID_C + ID_S + T_R + N2}K_c_tgs + T_c_tgs]
'''
M2 = M2.split("<>")
M2_inner = AES.decrypt(M2[0])
M2_inner = M2_inner.split("<>")
K_c_tgs = eval(M2_inner[0])
M2_N1 = int(M2_inner[1])
if M2_N1 != N1:
print("Invalid ticket [N1 mismatch]")
return
T_c_tgs = M2[1]
M2_AES = AESCipher(K_c_tgs)
N2 = randint(0, 1000000)
M3_inner = f"{ID_C}<>{ID_S}<>{T_R}<>{N2}"
M3_inner = M2_AES.encrypt(M3_inner)
M3 = f"{M3_inner}<>{T_c_tgs}"
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, TGS_PORT))
message = f"request||{M3}"
print('Sending M3', f'[{ID_C}<>{ID_S}<>{T_R}<>{N2}]<>[T_c_tgs]')
s.sendall(message.encode())
data = s.recv(4096)
data = data.decode()
print('Received M4', data)
M4 = data
time.sleep(3)
'''
M4 = [{K_c_s + T_A + N2}K_c_tgs + T_c_s]
T_c_s = {ID_C + T_A + K_c_s}K_s
M5 = [{ID_C + T_A + S_R + N3}K_c_s + T_c_s]
'''
M4 = M4.split("<>")
M4_AES = AESCipher(K_c_tgs)
M4_inner = M4_AES.decrypt(M4[0])
M4_inner = M4_inner.split("<>")
K_c_s = eval(M4_inner[0])
T_A = M4_inner[1]
M4_N2 = int(M4_inner[2])
if M4_N2 != N2:
print("Invalid ticket [N2 mismatch]")
return
T_c_s = M4[1]
M5_AES = AESCipher(K_c_s)
N3 = randint(0, 1000000)
M5_inner = f"{ID_C}<>{T_A}<>{ID_S}<>{N3}"
M5_inner = M5_AES.encrypt(M5_inner)
M5 = f"{M5_inner}<>{T_c_s}"
SAVED_INFO['M5'] = M5
SAVED_INFO['N3'] = N3
SAVED_INFO['K_c_s'] = K_c_s
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, SERVICE_PORT))
message = f"request||{M5}"
print('Sending M5', f'[{ID_C}<>{T_A}<>{ID_S}<>{N3}]<>[T_c_s]')
s.sendall(message.encode())
data = s.recv(4096)
data = data.decode()
print('Received M6', data)
M6 = data
time.sleep(3)
'''
M6 = [{Resposta, N3}K_c_s]
'''
M6 = M6.split("<>")
M6_AES = AESCipher(K_c_s)
M6_inner = M6_AES.decrypt(M6[0])
M6_inner = M6_inner.split("<>")
resposta = M6_inner[0]
M6_N3 = int(M6_inner[1])
if M6_N3 != N3:
print("Invalid ticket [N3 mismatch]")
return
print(f"Resposta: [{resposta}]")
print("Finished!")
def resend_service_message():
M5 = SAVED_INFO['M5']
N3 = SAVED_INFO['N3']
K_c_s = SAVED_INFO['K_c_s']
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, SERVICE_PORT))
message = f"request||{M5}"
print('Sending M5', message)
s.sendall(message.encode())
data = s.recv(4096)
data = data.decode()
print('Received M6', data)
M6 = data
'''
M6 = [{Resposta, N3}K_c_s]
'''
M6 = M6.split("<>")
M6_AES = AESCipher(K_c_s)
M6_inner = M6_AES.decrypt(M6[0])
M6_inner = M6_inner.split("<>")
resposta = M6_inner[0]
M6_N3 = int(M6_inner[1])
if M6_N3 != N3:
print("Invalid ticket [N3 mismatch]")
return
print(f"Resposta: [{resposta}]")
print("Finished!")
def main():
global CLIENT_ID
while True:
print(f"Hello world! Logged as [{CLIENT_ID}]")
print("1. Register")
print("2. Login")
if CLIENT_ID is not None:
print("3. Open door [M1 -> M6]")
print("4. Open door [M5 -> M6]")
print("0. Exit")
choice = input("Enter your choice: ")
if choice == "1":
username = input("Enter your username: ")
password = input("Enter your password: ")
register_user(username, password)
elif choice == "2":
username = input("Enter your username: ")
password = input("Enter your password: ")
login(username, password)
elif choice == "3":
send_messages()
elif choice == "4":
resend_service_message()
elif choice == "0":
break
else:
print("Invalid choice")
if __name__ == "__main__":
main()