summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorSam Chudnick <sam@chudnick.com>2022-07-04 20:03:27 -0400
committerSam Chudnick <sam@chudnick.com>2022-07-04 20:03:27 -0400
commit2e840e7c381f88425952c6fa9d68e0d433084a5a (patch)
tree31f7888ade33fbc112bd2b7509aac5c39bb2af82 /client
parent46564f357c175c7a01a36422307f05b543a83190 (diff)
Support both TLS encrypted sessions and plaintext sessions
Added support for both TLS and plaintext connections. Server can accept both types of connection simultaneously or in different combinations (i.e encrypted client and plaintext PAM). Added options for specifying dedicated TLS ports on server. Added --plain options for client and PAM to force plaintext connections, default is to use encrypted connections. Configuring encrypted client and PAM connections and plaintext server connections allows for use of a reverse proxy setup with something like nginx. This will avoid having to expose the MFA server directly in setups that traverse the internet.
Diffstat (limited to 'client')
-rwxr-xr-xclient/client.py44
1 files changed, 39 insertions, 5 deletions
diff --git a/client/client.py b/client/client.py
index cc22d0b..0388073 100755
--- a/client/client.py
+++ b/client/client.py
@@ -26,6 +26,7 @@ def parse_arguments():
26 parser.add_argument("--config",type=str,help="Path to config file",\ 26 parser.add_argument("--config",type=str,help="Path to config file",\
27 default="/etc/mfa/mfa.conf") 27 default="/etc/mfa/mfa.conf")
28 parser.add_argument("--key",type=str,help="Client connection key") 28 parser.add_argument("--key",type=str,help="Client connection key")
29 parser.add_argument("--plain",action="store_true",help="Connect without TLS")
29 parser.add_argument("--insecure",action="store_true",\ 30 parser.add_argument("--insecure",action="store_true",\
30 help="Accept invalid TLS certificates") 31 help="Accept invalid TLS certificates")
31 return parser.parse_args() 32 return parser.parse_args()
@@ -37,7 +38,7 @@ def prompt_user(prompt):
37 return result 38 return result
38 39
39 40
40def init_connection(mfa_server, client_port, client_key, insecure=False): 41def init_connection_tls(mfa_server, client_port, client_key, insecure=False):
41 # Attempts to connect to MFA server with provided address,port, and key. 42 # Attempts to connect to MFA server with provided address,port, and key.
42 # Repeats attempt once a seconds until timeout is reached. 43 # Repeats attempt once a seconds until timeout is reached.
43 # Returns socket or None if unable to connect 44 # Returns socket or None if unable to connect
@@ -70,6 +71,27 @@ def init_connection(mfa_server, client_port, client_key, insecure=False):
70 return connection 71 return connection
71 72
72 73
74def init_connection(mfa_server, client_port, client_key):
75 connection = None
76 timeout = 0
77 timeout_length = 5
78 sleep_length = 1
79 while connection == None and timeout < timeout_length:
80 try:
81 connection = socket.create_connection((mfa_server,client_port))
82 connection.send(client_key.encode(FORMAT))
83 response = connection.recv(ACK_LENGTH).decode(FORMAT)
84 if response == ACK_MESSAGE:
85 print("connected to mfa server")
86 elif response == DISCONNECT_MESSAGE:
87 print("server terminated connection")
88 sys.exit(1)
89 except ConnectionError:
90 time.sleep(sleep_length)
91 timeout += sleep_length
92 return connection
93
94
73def read_config(config_file): 95def read_config(config_file):
74 parser = configparser.ConfigParser(inline_comment_prefixes="#") 96 parser = configparser.ConfigParser(inline_comment_prefixes="#")
75 parser.read(config_file) 97 parser.read(config_file)
@@ -84,6 +106,7 @@ def get_vars(args,confparser):
84 server = None 106 server = None
85 port = None 107 port = None
86 key = None 108 key = None
109 plain = None
87 insecure = None 110 insecure = None
88 111
89 # Set values from config file first 112 # Set values from config file first
@@ -91,7 +114,13 @@ def get_vars(args,confparser):
91 server = confparser.get("client","server",fallback=None) 114 server = confparser.get("client","server",fallback=None)
92 port = confparser.get("client","port",fallback=None) 115 port = confparser.get("client","port",fallback=None)
93 key = confparser.get("client","key",fallback=None) 116 key = confparser.get("client","key",fallback=None)
94 insecure = bool(confparser.get("client","insecure",fallback=False)) 117 plain = confparser.get("client","plain",fallback=False)
118 insecure = confparser.get("client","insecure",fallback=False)
119
120 if plain.lower() == "false":
121 plain = False
122 if insecure.lower() == "false":
123 insecure = False
95 124
96 # Let command line args overwrite any values 125 # Let command line args overwrite any values
97 if args.server != None: 126 if args.server != None:
@@ -100,6 +129,8 @@ def get_vars(args,confparser):
100 port = args.port 129 port = args.port
101 if args.key != None: 130 if args.key != None:
102 key = args.key 131 key = args.key
132 if args.plain:
133 plain = args.plain
103 if args.insecure: 134 if args.insecure:
104 insecure = args.insecure 135 insecure = args.insecure
105 136
@@ -108,7 +139,7 @@ def get_vars(args,confparser):
108 print("error: one or more items unspecified") 139 print("error: one or more items unspecified")
109 sys.exit(1) 140 sys.exit(1)
110 141
111 return server,port,key,insecure 142 return server,port,key,plain,insecure
112 143
113 144
114def main(): 145def main():
@@ -116,7 +147,7 @@ def main():
116 args = parse_arguments() 147 args = parse_arguments()
117 confparser = read_config(args.config) 148 confparser = read_config(args.config)
118 149
119 mfa_server,client_port,client_key,insecure = get_vars(args,confparser) 150 mfa_server,client_port,client_key,plain,insecure = get_vars(args,confparser)
120 151
121 # Exit if invalid key is provided 152 # Exit if invalid key is provided
122 if len(client_key) != KEY_LENGTH: 153 if len(client_key) != KEY_LENGTH:
@@ -124,7 +155,10 @@ def main():
124 sys.exit(1) 155 sys.exit(1)
125 156
126 # Open connection to server 157 # Open connection to server
127 conn = init_connection(mfa_server,client_port,client_key,insecure) 158 if plain:
159 conn = init_connection(mfa_server,client_port,client_key)
160 else:
161 conn = init_connection_tls(mfa_server,client_port,client_key,insecure)
128 if conn == None: 162 if conn == None:
129 print("timed out attempting to connect to server") 163 print("timed out attempting to connect to server")
130 sys.exit(1) 164 sys.exit(1)