Browse Source

fix ca ssh generation, add initial autocomplete function support

master
Andrea Cimbalo 8 years ago
parent
commit
42d25685f9
5 changed files with 47 additions and 18 deletions
  1. +1
    -1
      lookup.py
  2. +3
    -1
      models/authority.py
  3. +10
    -6
      models/ssh.py
  4. +2
    -0
      models/ssl.py
  5. +31
    -10
      shell.py

+ 1
- 1
lookup.py View File

@ -89,7 +89,7 @@ class RequestLookup:
root_requested = request_data.get('rootRequested', False) root_requested = request_data.get('rootRequested', False)
key_data = request_data.get('keyData', None) key_data = request_data.get('keyData', None)
values = request_data['request'].values()
values = request_data.values()
if 'ssh_user' in values: if 'ssh_user' in values:
return UserSSHRequest( return UserSSHRequest(


+ 3
- 1
models/authority.py View File

@ -36,6 +36,8 @@ class Authority(Model):
help_text = 'last certificate serial number', help_text = 'last certificate serial number',
) )
compatible_requests = []
def __bool__(self): def __bool__(self):
return os.path.exists(self.path) return os.path.exists(self.path)
@ -50,4 +52,4 @@ class Authority(Model):
raise NotImplementedError() raise NotImplementedError()
def __repr__(self): def __repr__(self):
return ( "%s %s" % ( self.__class__.__name__, self.ca_id ) )
return ( "%s %s (%s)" % ( self.__class__.__name__, self.ca_id, self.name ) )

+ 10
- 6
models/ssh.py View File

@ -12,7 +12,6 @@ from models.certificate import Certificate
from models.request import SignRequest from models.request import SignRequest
from paths import * from paths import *
class UserSSHRequest(SignRequest): class UserSSHRequest(SignRequest):
def __init__(self, req_id, user_name, root_requested, key_data): def __init__(self, req_id, user_name, root_requested, key_data):
super(UserSSHRequest, self).__init__(req_id) super(UserSSHRequest, self).__init__(req_id)
@ -38,6 +37,7 @@ class UserSSHRequest(SignRequest):
class HostSSHRequest(SignRequest): class HostSSHRequest(SignRequest):
def __init__(self, req_id, host_name, key_data): def __init__(self, req_id, host_name, key_data):
super(HostSSHRequest, self).__init__(req_id) super(HostSSHRequest, self).__init__(req_id)
@ -65,7 +65,10 @@ class SSHAuthority(Authority):
key_algorithm = 'ed25519' key_algorithm = 'ed25519'
cert_validity = '+52w'
user_validity = '+52w'
host_validity = '+52w'
compatible_requests = [HostSSHRequest, UserSSHRequest]
def __bool__(self): def __bool__(self):
""" """
@ -105,9 +108,8 @@ class SSHAuthority(Authority):
signed_by = self, signed_by = self,
cert_id = request.req_id, cert_id = request.req_id,
date_issued = datetime.now(), date_issued = datetime.now(),
receiver = self.receiver,
receiver = request.receiver,
serial_number = self.serial, serial_number = self.serial,
validity_interval = self.user_validity,
) )
# write the key data from the request into # write the key data from the request into
@ -124,22 +126,24 @@ class SSHAuthority(Authority):
subprocess.check_output(['ssh-keygen', subprocess.check_output(['ssh-keygen',
'-s', ca_private_key, '-s', ca_private_key,
'-I', 'user_%s' % request.user_name,
'-I', 'user_%s' % request.receiver,
'-n', ','.join(login_names), '-n', ','.join(login_names),
'-V', self.user_validity, '-V', self.user_validity,
'-z', str(self.serial), '-z', str(self.serial),
pub_key_path]) pub_key_path])
cert.validity_interval = self.user_validity
elif type(request) == HostSSHRequest: elif type(request) == HostSSHRequest:
subprocess.check_output(['ssh-keygen', subprocess.check_output(['ssh-keygen',
'-s', ca_private_key, '-s', ca_private_key,
'-I', 'host_%s' % request.host_name.replace('.', '_'),
'-I', 'host_%s' % request.receiver.replace('.', '_'),
'-h', '-h',
'-n', request.host_name, '-n', request.host_name,
'-V', self.host_validity, '-V', self.host_validity,
'-z', str(self.serial), '-z', str(self.serial),
pub_key_path]) pub_key_path])
cert.validity_interval = self.host_validity
self.serial += 1 self.serial += 1


+ 2
- 0
models/ssl.py View File

@ -40,6 +40,8 @@ class SSLAuthority(Authority):
ca_validity = '365' ca_validity = '365'
cert_validity = '365' cert_validity = '365'
compatible_requests = [HostSSLRequest]
def generate(self): def generate(self):
if os.path.exists(self.path): if os.path.exists(self.path):
raise ValueError("A CA with the same id and type already exists") raise ValueError("A CA with the same id and type already exists")


+ 31
- 10
shell.py View File

@ -3,6 +3,7 @@
import cmd import cmd
import sys import sys
from datetime import datetime
from models.ssh import SSHAuthority from models.ssh import SSHAuthority
from models.ssl import SSLAuthority from models.ssl import SSLAuthority
@ -38,8 +39,8 @@ class CAManagerShell(cmd.Cmd):
'List the available certification requests: LS_REQUESTS' 'List the available certification requests: LS_REQUESTS'
print_available_requests(self.ca_manager) 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_id = l.split()[0]
ca = self.ca_manager.ca[ca_id] ca = self.ca_manager.ca[ca_id]
@ -136,6 +137,8 @@ class CAManagerShell(cmd.Cmd):
ca_id = ca_id, ca_id = ca_id,
name = name, name = name,
serial = 0, serial = 0,
active = True,
creation_date = datetime.now(),
) )
new_auth.generate() new_auth.generate()
@ -150,6 +153,8 @@ class CAManagerShell(cmd.Cmd):
ca_id = ca_id, ca_id = ca_id,
name = name, name = name,
serial = 0, serial = 0,
active = True,
creation_date = datetime.now(),
) )
new_auth.generate() new_auth.generate()
@ -177,17 +182,33 @@ class CAManagerShell(cmd.Cmd):
sign_request(self.ca_manager, request_id, authority_id) 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): def complete(self, text, state):
results = super().complete(text, state) results = super().complete(text, state)


Loading…
Cancel
Save