diff options
Diffstat (limited to 'client')
-rwxr-xr-x | client/client.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/client/client.py b/client/client.py new file mode 100755 index 0000000..abbc9de --- /dev/null +++ b/client/client.py | |||
@@ -0,0 +1,90 @@ | |||
1 | #!/usr/bin/env python3 | ||
2 | |||
3 | import socket | ||
4 | import time | ||
5 | import argparse | ||
6 | import sys | ||
7 | |||
8 | HEADER_LENGTH = 64 | ||
9 | KEY_LENGTH = 64 | ||
10 | DISCONNECT_LENGTH = ACK_LENGTH = 3 | ||
11 | ACK_MESSAGE = "ACK" | ||
12 | DISCONNECT_MESSAGE = "BYE" | ||
13 | FORMAT = "utf-8" | ||
14 | |||
15 | def parse_arguments(): | ||
16 | parser = argparse.ArgumentParser() | ||
17 | parser.add_argument("--server",type=str,help="IP of MFA Server",required=True) | ||
18 | parser.add_argument("--port",type=int,help="Port to connect to",required=True) | ||
19 | parser.add_argument("--key",type=str,help="Client connection key",required=True) | ||
20 | return parser.parse_args() | ||
21 | |||
22 | def prompt_user(prompt): | ||
23 | # Prompt user for input and return input | ||
24 | print(prompt) | ||
25 | result = input("> ") | ||
26 | return result | ||
27 | |||
28 | |||
29 | def init_connection(mfa_server, client_port, client_key): | ||
30 | # Attempts to connect to MFA server with provided address,port, and key. | ||
31 | # Repeats attempt once a seconds until timeout is reached. | ||
32 | # Returns socket or None if unable to connect | ||
33 | connection = None | ||
34 | timeout = 0 | ||
35 | timeout_length = 5 | ||
36 | sleep_length = 1 | ||
37 | while connection == None and timeout < timeout_length: | ||
38 | try: | ||
39 | connection = socket.create_connection((mfa_server,client_port)) | ||
40 | connection.send(client_key.encode(FORMAT)) | ||
41 | response = connection.recv(ACK_LENGTH).decode(FORMAT) | ||
42 | if response == ACK_MESSAGE: | ||
43 | print("connected to mfa server") | ||
44 | elif response == DISCONNECT_MESSAGE: | ||
45 | print("server terminated connection") | ||
46 | sys.exit(1) | ||
47 | except ConnectionError: | ||
48 | time.sleep(sleep_length) | ||
49 | timeout += sleep_length | ||
50 | return connection | ||
51 | |||
52 | |||
53 | def main(): | ||
54 | # Get arguments, exit if unable to connect | ||
55 | args = parse_arguments() | ||
56 | mfa_server = args.server | ||
57 | client_port = args.port | ||
58 | client_key = args.key | ||
59 | |||
60 | # Exit if invalid key is provided | ||
61 | if len(client_key) != KEY_LENGTH: | ||
62 | print("invalid key") | ||
63 | sys.exit(1) | ||
64 | |||
65 | # Open connection to server | ||
66 | conn = init_connection(mfa_server,client_port,client_key) | ||
67 | if conn == None: | ||
68 | print("timed out attempting to connect to server") | ||
69 | sys.exit(1) | ||
70 | |||
71 | # Main loop | ||
72 | running = True | ||
73 | while running: | ||
74 | # Receive MFA prompt from server | ||
75 | prompt_len = int(conn.recv(HEADER_LENGTH).decode(FORMAT)) | ||
76 | prompt = conn.recv(prompt_len).decode(FORMAT) | ||
77 | # Ask user for response | ||
78 | answer = prompt_user(prompt) | ||
79 | # Send answer to MFA server | ||
80 | answer_length = len(answer) | ||
81 | length_msg = str(answer_length) | ||
82 | length_msg += ' ' * (HEADER_LENGTH - len(length_msg)) | ||
83 | conn.send(length_msg.encode(FORMAT)) | ||
84 | conn.send(answer.encode(FORMAT)) | ||
85 | |||
86 | |||
87 | |||
88 | |||
89 | if __name__ == '__main__': | ||
90 | main() | ||