From 755d7f5f94b720b028d085cf971c5935c130dec1 Mon Sep 17 00:00:00 2001 From: Sam Chudnick Date: Mon, 4 Jul 2022 12:24:59 -0400 Subject: Implemented TLS encrypted connections Implemented TLS encrypted connections. Added command line argument and configuration file option to accept invalid (self-signed) certificates. Fixed a couple of unrelated issues. --- client/client.py | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'client') diff --git a/client/client.py b/client/client.py index 70d85a0..cc22d0b 100755 --- a/client/client.py +++ b/client/client.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import socket +import ssl import time import argparse import sys @@ -25,6 +26,8 @@ def parse_arguments(): parser.add_argument("--config",type=str,help="Path to config file",\ default="/etc/mfa/mfa.conf") parser.add_argument("--key",type=str,help="Client connection key") + parser.add_argument("--insecure",action="store_true",\ + help="Accept invalid TLS certificates") return parser.parse_args() def prompt_user(prompt): @@ -34,7 +37,7 @@ def prompt_user(prompt): return result -def init_connection(mfa_server, client_port, client_key): +def init_connection(mfa_server, client_port, client_key, insecure=False): # Attempts to connect to MFA server with provided address,port, and key. # Repeats attempt once a seconds until timeout is reached. # Returns socket or None if unable to connect @@ -42,9 +45,16 @@ def init_connection(mfa_server, client_port, client_key): timeout = 0 timeout_length = 5 sleep_length = 1 + context = ssl.create_default_context() + if insecure: + context.check_hostname = False + context.verify_mode = 0 while connection == None and timeout < timeout_length: try: - connection = socket.create_connection((mfa_server,client_port)) + #connection = socket.create_connection((mfa_server,client_port)) + connection = context.wrap_socket(socket.socket(socket.AF_INET), + server_hostname=mfa_server) + connection.connect((mfa_server,int(client_port))) connection.send(client_key.encode(FORMAT)) response = connection.recv(ACK_LENGTH).decode(FORMAT) if response == ACK_MESSAGE: @@ -55,6 +65,8 @@ def init_connection(mfa_server, client_port, client_key): except ConnectionError: time.sleep(sleep_length) timeout += sleep_length + except ssl.SSLCertVerificationError: + die("error: server presented invalid certificate") return connection @@ -72,27 +84,31 @@ def get_vars(args,confparser): server = None port = None key = None + insecure = None # Set values from config file first if confparser.has_section("client"): server = confparser.get("client","server",fallback=None) port = confparser.get("client","port",fallback=None) key = confparser.get("client","key",fallback=None) + insecure = bool(confparser.get("client","insecure",fallback=False)) # Let command line args overwrite any values - if args.server: + if args.server != None: server = args.server - if args.port: + if args.port != None: port = args.port - if args.key: + if args.key != None: key = args.key + if args.insecure: + insecure = args.insecure # Exit if any value is null if None in [server,port,key]: print("error: one or more items unspecified") sys.exit(1) - return server,port,key + return server,port,key,insecure def main(): @@ -100,7 +116,7 @@ def main(): args = parse_arguments() confparser = read_config(args.config) - mfa_server,client_port,client_key = get_vars(args,confparser) + mfa_server,client_port,client_key,insecure = get_vars(args,confparser) # Exit if invalid key is provided if len(client_key) != KEY_LENGTH: @@ -108,7 +124,7 @@ def main(): sys.exit(1) # Open connection to server - conn = init_connection(mfa_server,client_port,client_key) + conn = init_connection(mfa_server,client_port,client_key,insecure) if conn == None: print("timed out attempting to connect to server") sys.exit(1) -- cgit v1.2.3