From 42d25685f9244d3fb583ac3f3e39f61e62d88722 Mon Sep 17 00:00:00 2001 From: Andrea Cimbalo Date: Tue, 7 Mar 2017 21:57:53 +0100 Subject: [PATCH] fix ca ssh generation, add initial autocomplete function support --- lookup.py | 2 +- models/authority.py | 4 +++- models/ssh.py | 16 ++++++++++------ models/ssl.py | 2 ++ shell.py | 41 +++++++++++++++++++++++++++++++---------- 5 files changed, 47 insertions(+), 18 deletions(-) diff --git a/lookup.py b/lookup.py index 9769822..7338cc1 100755 --- a/lookup.py +++ b/lookup.py @@ -89,7 +89,7 @@ class RequestLookup: root_requested = request_data.get('rootRequested', False) key_data = request_data.get('keyData', None) - values = request_data['request'].values() + values = request_data.values() if 'ssh_user' in values: return UserSSHRequest( diff --git a/models/authority.py b/models/authority.py index 96942bf..5a72ead 100755 --- a/models/authority.py +++ b/models/authority.py @@ -36,6 +36,8 @@ class Authority(Model): help_text = 'last certificate serial number', ) + compatible_requests = [] + def __bool__(self): return os.path.exists(self.path) @@ -50,4 +52,4 @@ class Authority(Model): raise NotImplementedError() def __repr__(self): - return ( "%s %s" % ( self.__class__.__name__, self.ca_id ) ) + return ( "%s %s (%s)" % ( self.__class__.__name__, self.ca_id, self.name ) ) diff --git a/models/ssh.py b/models/ssh.py index 5734576..cc166e2 100644 --- a/models/ssh.py +++ b/models/ssh.py @@ -12,7 +12,6 @@ from models.certificate import Certificate from models.request import SignRequest from paths import * - class UserSSHRequest(SignRequest): def __init__(self, req_id, user_name, root_requested, key_data): super(UserSSHRequest, self).__init__(req_id) @@ -38,6 +37,7 @@ class UserSSHRequest(SignRequest): class HostSSHRequest(SignRequest): + def __init__(self, req_id, host_name, key_data): super(HostSSHRequest, self).__init__(req_id) @@ -65,7 +65,10 @@ class SSHAuthority(Authority): key_algorithm = 'ed25519' - cert_validity = '+52w' + user_validity = '+52w' + host_validity = '+52w' + + compatible_requests = [HostSSHRequest, UserSSHRequest] def __bool__(self): """ @@ -105,9 +108,8 @@ class SSHAuthority(Authority): signed_by = self, cert_id = request.req_id, date_issued = datetime.now(), - receiver = self.receiver, + receiver = request.receiver, serial_number = self.serial, - validity_interval = self.user_validity, ) # write the key data from the request into @@ -124,22 +126,24 @@ class SSHAuthority(Authority): subprocess.check_output(['ssh-keygen', '-s', ca_private_key, - '-I', 'user_%s' % request.user_name, + '-I', 'user_%s' % request.receiver, '-n', ','.join(login_names), '-V', self.user_validity, '-z', str(self.serial), pub_key_path]) + cert.validity_interval = self.user_validity elif type(request) == HostSSHRequest: subprocess.check_output(['ssh-keygen', '-s', ca_private_key, - '-I', 'host_%s' % request.host_name.replace('.', '_'), + '-I', 'host_%s' % request.receiver.replace('.', '_'), '-h', '-n', request.host_name, '-V', self.host_validity, '-z', str(self.serial), pub_key_path]) + cert.validity_interval = self.host_validity self.serial += 1 diff --git a/models/ssl.py b/models/ssl.py index 5361c1f..1a1bbdd 100644 --- a/models/ssl.py +++ b/models/ssl.py @@ -40,6 +40,8 @@ class SSLAuthority(Authority): ca_validity = '365' cert_validity = '365' + compatible_requests = [HostSSLRequest] + def generate(self): if os.path.exists(self.path): raise ValueError("A CA with the same id and type already exists") diff --git a/shell.py b/shell.py index 46b2010..b100164 100755 --- a/shell.py +++ b/shell.py @@ -3,6 +3,7 @@ import cmd import sys +from datetime import datetime from models.ssh import SSHAuthority from models.ssl import SSLAuthority @@ -38,8 +39,8 @@ class CAManagerShell(cmd.Cmd): 'List the available certification requests: LS_REQUESTS' print_available_requests(self.ca_manager) - def do_describe_cas(self, l): - 'Show certification authority information: DESCRIBE_CAS' + def do_describe_ca(self, l): + 'Show certification authority information: DESCRIBE_CA' ca_id = l.split()[0] ca = self.ca_manager.ca[ca_id] @@ -136,6 +137,8 @@ class CAManagerShell(cmd.Cmd): ca_id = ca_id, name = name, serial = 0, + active = True, + creation_date = datetime.now(), ) new_auth.generate() @@ -150,6 +153,8 @@ class CAManagerShell(cmd.Cmd): ca_id = ca_id, name = name, serial = 0, + active = True, + creation_date = datetime.now(), ) new_auth.generate() @@ -177,17 +182,33 @@ class CAManagerShell(cmd.Cmd): sign_request(self.ca_manager, request_id, authority_id) - def complete_sign_request(self, text, line, begidx, endidx): + def common_complete_request(self, text, line, begidx, endidx): + argc = len(("%send"%line).split()) + if argc == 2: + return [request.req_id for i, request in enumerate(self.ca_manager.request) if request.req_id.startswith(text)] + + def complete_drop_request(self, text, line, begidx, endidx): + return self.common_complete_request(text, line, begidx, endidx) - ca_results = [ - a for a in self.ca_manager.ca if a.ca_id.startswith(text) - ] - req_result = [ - a for a in self.ca_manager.request if a.req_id.startswith(text) - ] + def complete_describe_request(self, text, line, begidx, endidx): + return self.common_complete_request(text, line, begidx, endidx) - return ' '.join(results) + def complete_sign_request(self, text, line, begidx, endidx): + results = '' + argc = len(("%send"%line).split()) + + if argc == 2: + results = [ca_item.ca_id for i, ca_item in enumerate(self.ca_manager.ca) if ca_item.ca_id.startswith(text)] + elif argc == 3: + try: + ca = self.ca_manager.ca[line.split()[1]] + except Exception as e: + print ("Error: %s"%e) + return + + results = [request.req_id for i, request in enumerate(self.ca_manager.request) if request.req_id.startswith(text) and request.__class__ in ca.compatible_requests] + return results def complete(self, text, state): results = super().complete(text, state)