def test_export_pkcs12(self): entry = CertificateEntry('test_pkcs12', organizationName='test_org', organizationalUnitName='test_unit', emailAddress='test@example .com', localityName='City', countryName='FR', stateOrProvinceName='Province', altNames=[], role=TEST_SHA256, dirname=self.dirname) filename = self.get_tmp_filename() password = '******' self.pki.gen_pkcs12(entry, filename=filename, password=password) with codecs.open(entry.key_filename, 'r', encoding='utf-8') as fd: src_key_content = fd.read() password_file = self.get_tmp_filename() with codecs.open(password_file, 'w', encoding='utf-8') as fd: fd.write(password) fd.flush() p = subprocess.Popen([ settings.OPENSSL_PATH, 'pkcs12', '-in', filename, '-passin', 'file:%s' % password_file, '-nodes', '-nocerts', ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate(input=password.encode('utf-8')) dst_key_content = stdout.decode('utf-8') self.assertTrue(src_key_content in dst_key_content)
def handle(self, *args, **options): role = options['role'] if role not in ROLES: self.stdout.write(self.style.ERROR('Invalid role: %s' % role)) self.stdout.write('Valid roles: %s' % ', '.join(ROLES)) return alt_names = [] for alt_name in options['altNames']: kind, sep, value = alt_name.partition(':') if sep != ':' or kind not in dict(ALT_TYPES): self.stdout.write( self.style.ERROR( 'Altname %s must be of form KIND:VALUE with KIND one of %s' % (alt_name, ', '.join(ALT_TYPES)))) return alt_names.append((kind, value)) for key in 'cert', 'key', 'ssh', 'ca', 'pubssh', 'pubkey': if not options[key]: continue try: with open(options[key], 'wb') as fd: fd.write(b'') except OSError: self.stdout.write( self.style.ERROR('Unable to write file: %s' % options[key])) return entry = CertificateEntry( options['commonName'], organizationalUnitName=options['organizationalUnitName'], emailAddress=options['emailAddress'], localityName=options['localityName'], countryName=options['countryName'], stateOrProvinceName=options['stateOrProvinceName'], altNames=alt_names, role=role) pki = PKI() pki.initialize() if options['initialize']: pki.ensure_ca(entry) else: pki.ensure_certificate(entry) ca_crt_path, ca_key_path = pki.get_subca_infos(entry) for key, attr in ( ('cert', 'crt_filename'), ('key', 'key_filename'), ('ssh', 'key_filename'), ('ca', 'ca_filename'), ('pubssh', 'ssh_filename'), ('pubkey', 'pub_filename'), ): dst_filename = options[key] if not dst_filename: continue if key == 'ca': open(dst_filename, 'ab').write(open(ca_crt_path, 'rb').read()) src_filename = getattr(entry, attr) open(dst_filename, 'ab').write(open(src_filename, 'rb').read()) self.stdout.write('File %s written' % dst_filename)
def setUpClass(cls): TestCase.setUpClass() pki = PKI() pki.initialize() entry = CertificateEntry(cls.domain_name, organizationalUnitName='certificates', emailAddress=settings.PENATES_EMAIL_ADDRESS, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=CA) pki.ensure_ca(entry)
def setUpClass(cls): TestCase.setUpClass() cls.dirname = tempfile.mkdtemp() cls.pki = PKI(dirname=cls.dirname) cls.ca_entry = CertificateEntry('test_CA', organizationName='test_org', organizationalUnitName='test_unit', emailAddress='*****@*****.**', localityName='City', countryName='FR', stateOrProvinceName='Province', altNames=[], role=CA_TEST, dirname=cls.dirname)
def test_computer(self): entry = CertificateEntry('test_computer', organizationName='test_org', organizationalUnitName='test_unit', emailAddress='test@example .com', localityName='City', countryName='FR', stateOrProvinceName='Province', altNames=[], role=COMPUTER_TEST, dirname=self.dirname) self.pki.ensure_certificate(entry) self.assertTrue(entry.pub_filename) self.assertTrue(entry.key_filename) self.assertTrue(entry.crt_filename) self.assertTrue(entry.ssh_filename)
def test_crl(self): entry = CertificateEntry('test_computer', organizationName='test_org', organizationalUnitName='test_unit', emailAddress='test@example .com', localityName='City', countryName='FR', stateOrProvinceName='Province', altNames=[], role=COMPUTER_TEST, dirname=self.dirname) self.pki.ensure_certificate(entry) with codecs.open(entry.crt_filename, 'r', encoding='utf-8') as fd: content = fd.read() self.pki.ensure_crl() self.pki.ensure_crl() self.pki.revoke_certificate(content) self.pki.ensure_certificate(entry) self.pki.ensure_certificate(entry) with open(self.pki.dirname + '/index.txt', b'r') as fd: self.assertEqual(6, len(fd.read().splitlines()))
def get_service_certificate(request, scheme, hostname, port): try: fqdn = hostname_from_principal(request.user.username) except ValueError: return HttpResponse( status=401, content='Unable to get service certificate: invalid username') role = request.GET.get('role', SERVICE) protocol = request.GET.get('protocol', 'tcp') port = int(port) query = Service.objects.filter(fqdn=fqdn, scheme=scheme, hostname=hostname, port=port, protocol=protocol) services = list(query[0:1]) if not services: return HttpResponse(status=404, content='%s://%s:%s/ unknown' % (scheme, hostname, port)) if role not in (SERVICE, KERBEROS_DC, PRINTER, TIME_SERVER, SERVICE_1024): return HttpResponse(status=401, content='Role %s is not allowed' % role) entry = CertificateEntry(hostname, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Services'), emailAddress=settings.PENATES_EMAIL_ADDRESS, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=role) pki = PKI() pki.ensure_certificate(entry) record_name, sep, domain_name = hostname.partition('.') domain = Domain.objects.get(name=domain_name) domain.set_certificate_records(entry, protocol, hostname, port) return CertificateEntryResponse(entry)
def set_service(request, scheme, hostname, port): try: fqdn = hostname_from_principal(request.user.username) except ValueError: return HttpResponse( status=401, content='Unable to create %s://%s:%s/: invalid username' % (scheme, hostname, port)) encryption = request.GET.get('encryption', 'none') srv_field = request.GET.get('srv', None) kerberos_service = request.GET.get('keytab', None) role = request.GET.get('role', SERVICE) protocol = request.GET.get('protocol', 'tcp') if encryption not in ('none', 'tls', 'starttls'): return HttpResponse( 'valid encryption levels are none, tls, or starttls') port = int(port) if not (0 <= port <= 65536): return HttpResponse('Invalid port: %s' % port, status=403, content_type='text/plain') if protocol not in ('tcp', 'udp', 'socket'): return HttpResponse('Invalid protocol: %s' % protocol, status=403, content_type='text/plain') description = request.body # a few checks if Service.objects.filter(hostname=hostname).exclude( fqdn=fqdn).count() > 0: return HttpResponse(status=401, content='%s is already registered' % hostname) if role not in (SERVICE, KERBEROS_DC, PRINTER, TIME_SERVER, SERVICE_1024): return HttpResponse(status=401, content='Role %s is not allowed' % role) if kerberos_service and kerberos_service not in settings.KERBEROS_SERVICES: return HttpResponse(status=401, content='Kerberos service %s is not allowed' % role) hosts = list(Host.objects.filter(fqdn=fqdn)[0:1]) if not hosts: return HttpResponse(status=401, content='Unknown host %s is not allowed' % fqdn) host = hosts[0] if scheme == 'ssh' and host.admin_ip_address != host.main_ip_address: fqdn = '%s.%s%s' % (fqdn.partition('.')[0], settings.PDNS_ADMIN_PREFIX, settings.PENATES_DOMAIN) # Penates service service, created = Service.objects.get_or_create(fqdn=fqdn, scheme=scheme, hostname=hostname, port=port, protocol=protocol, defaults={ 'kerberos_service': kerberos_service, 'dns_srv': srv_field, 'encryption': encryption, 'description': description }) Service.objects.filter(pk=service.pk).update( kerberos_service=kerberos_service, description=description, dns_srv=srv_field, encryption=encryption) # certificates entry = CertificateEntry(hostname, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Services'), emailAddress=settings.PENATES_EMAIL_ADDRESS, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=role) pki = PKI() pki.ensure_certificate(entry) if kerberos_service: add_principal(service.principal_name) # DNS part record_name, sep, domain_name = hostname.partition('.') if sep == '.': domains = list(Domain.objects.filter(name=domain_name)[0:1]) if domains: domain = domains[0] domain.ensure_record(fqdn, hostname) domain.set_extra_records(scheme, hostname, port, fqdn, srv_field, entry=entry) domain.update_soa() return HttpResponse(status=201, content='%s://%s:%s/ created' % (scheme, hostname, port))
def encipherment_certificate_entry(self): return CertificateEntry(self.name, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Users'), emailAddress=self.mail, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=ENCIPHERMENT)
def handle(self, *args, **options): # read provided arguments kerberos_service = options['kerberos_service'] fqdn = options['fqdn'] hostname = options['hostname'] keytab = options['keytab'] scheme = options['scheme'] encryption = options['encryption'] port = int(options['port']) protocol = options['protocol'] srv_field = options['srv'] if keytab and not kerberos_service: self.stdout.write( self.style.ERROR('--keytab is set without --kerberos_service')) return if kerberos_service and not fqdn: self.stdout.write( self.style.ERROR('--kerberos_service is set without --fqdn')) return # create service object service, created = Service.objects.get_or_create(fqdn=fqdn, scheme=scheme, hostname=hostname, port=port, protocol=protocol) Service.objects.filter(pk=service.pk).update( kerberos_service=kerberos_service, description=options['description'], dns_srv=srv_field, encryption=encryption) # certificate part if options['role']: call_command('certificate', hostname, options['role'], organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Services'), emailAddress=settings.PENATES_EMAIL_ADDRESS, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], cert=options['cert'], key=options['key'], pubkey=options['pubkey'], ssh=options['ssh'], pubssh=options['pubssh'], ca=options['ca'], initialize=False) entry = CertificateEntry( hostname, organizationName=settings.PENATES_ORGANIZATION, organizationalUnitName=_('Services'), emailAddress=settings.PENATES_EMAIL_ADDRESS, localityName=settings.PENATES_LOCALITY, countryName=settings.PENATES_COUNTRY, stateOrProvinceName=settings.PENATES_STATE, altNames=[], role=options['role']) else: entry = None # kerberos part if kerberos_service: principal = '%s/%s' % (kerberos_service, fqdn) call_command('keytab', principal, keytab=keytab) # DNS part record_name, sep, domain_name = hostname.partition('.') if sep == '.': domain, created = Domain.objects.get_or_create(name=domain_name) domain.ensure_record(fqdn, hostname) domain.set_extra_records(scheme, hostname, port, fqdn, srv_field, entry=entry) domain.update_soa() if entry: domain.set_certificate_records(entry, protocol, hostname, port)