mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-31 01:19:11 +00:00 
			
		
		
		
	Sevral bugfixes
This commit is contained in:
		| @@ -100,6 +100,7 @@ class SessionResource(AuthorityHandler): | |||||||
|                 except IOError: |                 except IOError: | ||||||
|                     signer_username = None |                     signer_username = None | ||||||
|  |  | ||||||
|  |                 # TODO: dedup | ||||||
|                 yield dict( |                 yield dict( | ||||||
|                     serial = "%x" % cert.serial_number, |                     serial = "%x" % cert.serial_number, | ||||||
|                     organizational_unit = cert.subject.native.get("organizational_unit_name"), |                     organizational_unit = cert.subject.native.get("organizational_unit_name"), | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ import json | |||||||
| import hashlib | import hashlib | ||||||
| from certidude.auth import login_required, authorize_admin | from certidude.auth import login_required, authorize_admin | ||||||
| from certidude.decorators import csrf_protection | from certidude.decorators import csrf_protection | ||||||
| from xattr import getxattr | from xattr import listxattr, getxattr | ||||||
| from .utils import AuthorityHandler | from .utils import AuthorityHandler | ||||||
|  |  | ||||||
| logger = logging.getLogger(__name__) | logger = logging.getLogger(__name__) | ||||||
| @@ -34,14 +34,28 @@ class SignedCertificateDetailResource(AuthorityHandler): | |||||||
|                 signer_username = getxattr(path, "user.signature.username").decode("ascii") |                 signer_username = getxattr(path, "user.signature.username").decode("ascii") | ||||||
|             except IOError: |             except IOError: | ||||||
|                 signer_username = None |                 signer_username = None | ||||||
|  |  | ||||||
|  |             attributes = {} | ||||||
|  |             for key in listxattr(path): | ||||||
|  |                 if key.startswith(b"user.machine."): | ||||||
|  |                     attributes[key[13:].decode("ascii")] = getxattr(path, key).decode("ascii") | ||||||
|  |  | ||||||
|  |             # TODO: dedup | ||||||
|             resp.body = json.dumps(dict( |             resp.body = json.dumps(dict( | ||||||
|                 common_name = cn, |                 common_name = cn, | ||||||
|                 signer = signer_username, |                 signer = signer_username, | ||||||
|                 serial_number = "%x" % cert.serial_number, |                 serial = "%x" % cert.serial_number, | ||||||
|                 organizational_unit = cert.subject.native.get("organizational_unit_name"), |                 organizational_unit = cert.subject.native.get("organizational_unit_name"), | ||||||
|                 signed = cert["tbs_certificate"]["validity"]["not_before"].native.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z", |                 signed = cert["tbs_certificate"]["validity"]["not_before"].native.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z", | ||||||
|                 expires = cert["tbs_certificate"]["validity"]["not_after"].native.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z", |                 expires = cert["tbs_certificate"]["validity"]["not_after"].native.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z", | ||||||
|                 sha256sum = hashlib.sha256(buf).hexdigest())) |                 sha256sum = hashlib.sha256(buf).hexdigest(), | ||||||
|  |                 attributes = attributes or None, | ||||||
|  |                 lease = None, | ||||||
|  |                 extensions = dict([ | ||||||
|  |                     (e["extn_id"].native, e["extn_value"].native) | ||||||
|  |                     for e in cert["tbs_certificate"]["extensions"] | ||||||
|  |                     if e["extn_value"] in ("extended_key_usage",)]) | ||||||
|  |             )) | ||||||
|             logger.debug("Served certificate %s to %s as application/json", |             logger.debug("Served certificate %s to %s as application/json", | ||||||
|                 cn, req.context.get("remote_addr")) |                 cn, req.context.get("remote_addr")) | ||||||
|         else: |         else: | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ class TokenResource(AuthorityHandler): | |||||||
|         common_name = csr["certification_request_info"]["subject"].native["common_name"] |         common_name = csr["certification_request_info"]["subject"].native["common_name"] | ||||||
|         assert common_name == username or common_name.startswith(username + "@"), "Invalid common name %s" % common_name |         assert common_name == username or common_name.startswith(username + "@"), "Invalid common name %s" % common_name | ||||||
|         try: |         try: | ||||||
|             _, resp.body = self.authority._sign(csr, body) |             _, resp.body = self.authority._sign(csr, body, profile="default") | ||||||
|             resp.set_header("Content-Type", "application/x-pem-file") |             resp.set_header("Content-Type", "application/x-pem-file") | ||||||
|             logger.info("Autosigned %s as proven by token ownership", common_name) |             logger.info("Autosigned %s as proven by token ownership", common_name) | ||||||
|         except FileExistsError: |         except FileExistsError: | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ def self_enroll(): | |||||||
|         from certidude import authority |         from certidude import authority | ||||||
|         from certidude.common import drop_privileges |         from certidude.common import drop_privileges | ||||||
|         drop_privileges() |         drop_privileges() | ||||||
|         authority.sign(common_name, skip_push=True, overwrite=True) |         authority.sign(common_name, skip_push=True, overwrite=True, profile="srv") | ||||||
|         sys.exit(0) |         sys.exit(0) | ||||||
|     else: |     else: | ||||||
|         os.waitpid(pid, 0) |         os.waitpid(pid, 0) | ||||||
| @@ -307,7 +307,7 @@ def delete_request(common_name): | |||||||
|         config.LONG_POLL_PUBLISH % hashlib.sha256(buf).hexdigest(), |         config.LONG_POLL_PUBLISH % hashlib.sha256(buf).hexdigest(), | ||||||
|         headers={"User-Agent": "Certidude API"}) |         headers={"User-Agent": "Certidude API"}) | ||||||
|  |  | ||||||
| def sign(common_name, skip_notify=False, skip_push=False, overwrite=False, profile="default", signer=None): | def sign(common_name, skip_notify=False, skip_push=False, overwrite=False, profile=None, signer=None): | ||||||
|     """ |     """ | ||||||
|     Sign certificate signing request by it's common name |     Sign certificate signing request by it's common name | ||||||
|     """ |     """ | ||||||
| @@ -325,12 +325,12 @@ def sign(common_name, skip_notify=False, skip_push=False, overwrite=False, profi | |||||||
|     os.unlink(req_path) |     os.unlink(req_path) | ||||||
|     return cert, buf |     return cert, buf | ||||||
|  |  | ||||||
| def _sign(csr, buf, skip_notify=False, skip_push=False, overwrite=False, profile="default", signer=None): | def _sign(csr, buf, skip_notify=False, skip_push=False, overwrite=False, profile=None, signer=None): | ||||||
|     # TODO: CRLDistributionPoints, OCSP URL, Certificate URL |     # TODO: CRLDistributionPoints, OCSP URL, Certificate URL | ||||||
|     if profile not in config.PROFILES: |     if profile not in config.PROFILES: | ||||||
|         raise ValueError("Invalid profile supplied '%s'" % profile) |         raise ValueError("Invalid profile supplied '%s'" % profile) | ||||||
|  |  | ||||||
|     assert buf.startswith(b"-----BEGIN CERTIFICATE REQUEST-----") |     assert buf.startswith(b"-----BEGIN ") | ||||||
|     assert isinstance(csr, CertificationRequest) |     assert isinstance(csr, CertificationRequest) | ||||||
|     csr_pubkey = asymmetric.load_public_key(csr["certification_request_info"]["subject_pk_info"]) |     csr_pubkey = asymmetric.load_public_key(csr["certification_request_info"]["subject_pk_info"]) | ||||||
|     common_name = csr["certification_request_info"]["subject"].native["common_name"] |     common_name = csr["certification_request_info"]["subject"].native["common_name"] | ||||||
|   | |||||||
| @@ -956,7 +956,7 @@ def certidude_setup_authority(username, kerberos_keytab, nginx_config, country, | |||||||
|         os.system("apt-get install -qq -y cython3 python3-dev python3-mimeparse \ |         os.system("apt-get install -qq -y cython3 python3-dev python3-mimeparse \ | ||||||
|             python3-markdown python3-pyxattr python3-jinja2 python3-cffi \ |             python3-markdown python3-pyxattr python3-jinja2 python3-cffi \ | ||||||
|             software-properties-common libsasl2-modules-gssapi-mit npm nodejs \ |             software-properties-common libsasl2-modules-gssapi-mit npm nodejs \ | ||||||
|             libkrb5-dev libldap2-dev libsasl2-dev gawk libncurses5-dev") |             libkrb5-dev libldap2-dev libsasl2-dev gawk libncurses5-dev rsync") | ||||||
|         os.system("pip3 install -q --upgrade gssapi falcon humanize ipaddress simplepam") |         os.system("pip3 install -q --upgrade gssapi falcon humanize ipaddress simplepam") | ||||||
|         os.system("pip3 install -q --pre --upgrade python-ldap") |         os.system("pip3 install -q --pre --upgrade python-ldap") | ||||||
|  |  | ||||||
| @@ -1308,11 +1308,12 @@ def certidude_list(verbose, show_key_type, show_extensions, show_path, show_sign | |||||||
|  |  | ||||||
| @click.command("sign", help="Sign certificate") | @click.command("sign", help="Sign certificate") | ||||||
| @click.argument("common_name") | @click.argument("common_name") | ||||||
|  | @click.option("--profile", "-p", default=None, help="Profile") | ||||||
| @click.option("--overwrite", "-o", default=False, is_flag=True, help="Revoke valid certificate with same CN") | @click.option("--overwrite", "-o", default=False, is_flag=True, help="Revoke valid certificate with same CN") | ||||||
| def certidude_sign(common_name, overwrite): | def certidude_sign(common_name, overwrite, profile): | ||||||
|     from certidude import authority |     from certidude import authority | ||||||
|     drop_privileges() |     drop_privileges() | ||||||
|     cert = authority.sign(common_name, overwrite=overwrite) |     cert = authority.sign(common_name, overwrite=overwrite, profile=profile) | ||||||
|  |  | ||||||
|  |  | ||||||
| @click.command("revoke", help="Revoke certificate") | @click.command("revoke", help="Revoke certificate") | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| <i class="fa fa-circle" style="color:{% if certificate.lease.age > 86400 %}#d9534f{% else %}{% if certificate.lease.age > 3600 %}#0275d8{% else %}#5cb85c{% endif %}{% endif %};"/> | <i class="fa fa-circle" style="color:{% if certificate.lease.age > 172800 %}#d9534f{% else %}{% if certificate.lease.age > 3600 %}#0275d8{% else %}#5cb85c{% endif %}{% endif %};"/> | ||||||
| Last seen | Last seen | ||||||
| <time class="timeago" datetime="{{ certificate.lease.last_seen }}">{{ certificate.lease.last_seen }}</time> | <time class="timeago" datetime="{{ certificate.lease.last_seen }}">{{ certificate.lease.last_seen }}</time> | ||||||
| at | at | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user