mirror of
				https://github.com/laurivosandi/certidude
				synced 2025-10-31 17:39:12 +00:00 
			
		
		
		
	Token mechanism fixes
This commit is contained in:
		
							
								
								
									
										10
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.rst
									
									
									
									
									
								
							| @@ -71,19 +71,19 @@ Common: | |||||||
| * Kerberos and basic auth based web interface authentication. | * Kerberos and basic auth based web interface authentication. | ||||||
| * PAM and Active Directory compliant authentication backends: Kerberos single sign-on, LDAP simple bind. | * PAM and Active Directory compliant authentication backends: Kerberos single sign-on, LDAP simple bind. | ||||||
| * POSIX groups and Active Directory (LDAP) group membership based authorization. | * POSIX groups and Active Directory (LDAP) group membership based authorization. | ||||||
| * Command-line interface, check out ``certidude list``. | * Server-side command-line interface, check out ``certidude list``, ``certidude sign`` and ``certidude revoke``. | ||||||
| * Privilege isolation, separate signer process is spawned per private key isolating | * Privilege isolation, separate signer process is spawned per private key isolating | ||||||
|   private key use from the the web interface. |   private key use from the the web interface. | ||||||
| * Certificate serial numbers are intentionally randomized to avoid leaking information about business practices. | * Certificate serial numbers are intentionally randomized to avoid leaking information about business practices. | ||||||
| * Server-side events support via `nchan <https://nchan.slact.net/>`_. | * Server-side events support via `nchan <https://nchan.slact.net/>`_. | ||||||
| * E-mail notifications about pending, signed and revoked certificates. | * E-mail notifications about pending, signed, revoked, renewed and overwritten certificates | ||||||
|  |  | ||||||
| Virtual private networking: | Virtual private networking: | ||||||
|  |  | ||||||
| * Send OpenVPN profile URL tokens via e-mail, for simplified VPN adoption on Android, iOS, Windows, Mac OS X and Ubuntu. | * Send OpenVPN profile URL tokens via e-mail, for simplified VPN adoption on Android, iOS, Windows, Mac OS X and Ubuntu. | ||||||
| * OpenVPN integration, check out ``certidude setup openvpn server`` and ``certidude setup openvpn client``. | * OpenVPN gateway and roadwarrior integration, check out ``certidude setup openvpn server`` and ``certidude setup openvpn client``. | ||||||
| * strongSwan integration, check out ``certidude setup strongswan server`` and ``certidude setup strongswan client``. | * StrongSwan gateway and roadwarrior integration, check out ``certidude setup strongswan server`` and ``certidude setup strongswan client``. | ||||||
| * NetworkManager integration, check out ``certidude setup openvpn networkmanager`` and ``certidude setup strongswan networkmanager``. | * NetworkManager integration for Ubuntu and Fedora, check out ``certidude setup openvpn networkmanager`` and ``certidude setup strongswan networkmanager``. | ||||||
|  |  | ||||||
| HTTPS: | HTTPS: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,5 +10,5 @@ class BootstrapResource(object): | |||||||
|     def on_get(self, req, resp): |     def on_get(self, req, resp): | ||||||
|         resp.body = Template(open(config.BOOTSTRAP_TEMPLATE).read()).render( |         resp.body = Template(open(config.BOOTSTRAP_TEMPLATE).read()).render( | ||||||
|             authority = const.FQDN, |             authority = const.FQDN, | ||||||
|             servers = [cn for cn, path, buf, cert, server in authority.list_signed() if server]) |             servers = authority.list_server_names()) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,11 +35,12 @@ class TokenResource(object): | |||||||
|         csum.update(username) |         csum.update(username) | ||||||
|         csum.update(str(timestamp)) |         csum.update(str(timestamp)) | ||||||
|  |  | ||||||
|  |         margin = 300 # Tolerate 5 minute clock skew as Kerberos does | ||||||
|         if csum.hexdigest() != req.get_param("c", required=True): |         if csum.hexdigest() != req.get_param("c", required=True): | ||||||
|             raise falcon.HTTPUnauthorized("Forbidden", "Invalid token supplied, did you copy-paste link correctly?") |             raise falcon.HTTPUnauthorized("Forbidden", "Invalid token supplied, did you copy-paste link correctly?") | ||||||
|         if now < timestamp: |         if now < timestamp - margin: | ||||||
|             raise falcon.HTTPUnauthorized("Forbidden", "Token not valid yet, are you sure server clock is correct?") |             raise falcon.HTTPUnauthorized("Forbidden", "Token not valid yet, are you sure server clock is correct?") | ||||||
|         if now > timestamp + config.TOKEN_LIFETIME: |         if now > timestamp + margin + config.TOKEN_LIFETIME: | ||||||
|             raise falcon.HTTPUnauthorized("Forbidden", "Token expired") |             raise falcon.HTTPUnauthorized("Forbidden", "Token expired") | ||||||
|  |  | ||||||
|         # At this point consider token to be legitimate |         # At this point consider token to be legitimate | ||||||
|   | |||||||
| @@ -165,6 +165,9 @@ def list_signed(): | |||||||
| def list_revoked(): | def list_revoked(): | ||||||
|     return _list_certificates(config.REVOKED_DIR) |     return _list_certificates(config.REVOKED_DIR) | ||||||
|  |  | ||||||
|  | def list_server_names(): | ||||||
|  |     return [cn for cn, path, buf, cert, server in list_signed() if server] | ||||||
|  |  | ||||||
| def export_crl(): | def export_crl(): | ||||||
|     sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) |     sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | ||||||
|     sock.connect(const.SIGNER_SOCKET_PATH) |     sock.connect(const.SIGNER_SOCKET_PATH) | ||||||
| @@ -228,7 +231,7 @@ def generate_ovpn_bundle(common_name, owner=None): | |||||||
|  |  | ||||||
|     bundle = Template(open(config.OPENVPN_PROFILE_TEMPLATE).read()).render( |     bundle = Template(open(config.OPENVPN_PROFILE_TEMPLATE).read()).render( | ||||||
|         ca = ca_buf, key = key_buf, cert = cert_buf, crl=export_crl(), |         ca = ca_buf, key = key_buf, cert = cert_buf, crl=export_crl(), | ||||||
|         servers = [cn for cn, path, buf, cert, server in list_signed() if server]) |         servers = list_server_names()) | ||||||
|     return bundle, cert |     return bundle, cert | ||||||
|  |  | ||||||
| def generate_pkcs12_bundle(common_name, key_size=4096, owner=None): | def generate_pkcs12_bundle(common_name, key_size=4096, owner=None): | ||||||
|   | |||||||
| @@ -980,6 +980,7 @@ def certidude_setup_authority(username, kerberos_keytab, nginx_config, country, | |||||||
|                 encryption_algorithm=serialization.NoEncryption() # TODO: Implement passphrase |                 encryption_algorithm=serialization.NoEncryption() # TODO: Implement passphrase | ||||||
|             )) |             )) | ||||||
|  |  | ||||||
|  |     click.echo("To enable e-mail notifications install Postfix as sattelite system and set mailer address in %s" % const.CONFIG_PATH) | ||||||
|     click.echo() |     click.echo() | ||||||
|     click.echo("Use following commands to inspect the newly created files:") |     click.echo("Use following commands to inspect the newly created files:") | ||||||
|     click.echo() |     click.echo() | ||||||
| @@ -987,9 +988,10 @@ def certidude_setup_authority(username, kerberos_keytab, nginx_config, country, | |||||||
|     click.echo("  openssl rsa -check -in %s" % ca_key) |     click.echo("  openssl rsa -check -in %s" % ca_key) | ||||||
|     click.echo("  openssl verify -CAfile %s %s" % (ca_crt, ca_crt)) |     click.echo("  openssl verify -CAfile %s %s" % (ca_crt, ca_crt)) | ||||||
|     click.echo() |     click.echo() | ||||||
|     click.echo("Use following command to serve CA read-only:") |     click.echo("To enable and start the service:") | ||||||
|     click.echo() |     click.echo() | ||||||
|     click.echo("  certidude serve") |     click.echo("  systemctl enable certidude") | ||||||
|  |     click.echo("  systemctl start certidude") | ||||||
|  |  | ||||||
|  |  | ||||||
| @click.command("users", help="List users") | @click.command("users", help="List users") | ||||||
|   | |||||||
| @@ -98,7 +98,7 @@ TAG_TYPES = [j.split("/", 1) + [cp.get("tagging", j)] for j in cp.options("taggi | |||||||
| BUNDLE_FORMAT = cp.get("token", "format") | BUNDLE_FORMAT = cp.get("token", "format") | ||||||
| OPENVPN_PROFILE_TEMPLATE = cp.get("token", "openvpn profile template") | OPENVPN_PROFILE_TEMPLATE = cp.get("token", "openvpn profile template") | ||||||
| TOKEN_URL = cp.get("token", "url") | TOKEN_URL = cp.get("token", "url") | ||||||
| TOKEN_LIFETIME = cp.getint("token", "lifetime") | TOKEN_LIFETIME = cp.getint("token", "lifetime") * 60 # Convert minutes to seconds | ||||||
| TOKEN_SECRET = cp.get("token", "secret") | TOKEN_SECRET = cp.get("token", "secret") | ||||||
|  |  | ||||||
| # TODO: Check if we don't have base or servers | # TODO: Check if we don't have base or servers | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| # Run as OpenVPN client, pull routes, DNS server, DNS suffix from gateway | # Run as OpenVPN client, pull routes, DNS server, DNS suffix from gateway | ||||||
| client | client | ||||||
|  |  | ||||||
| # OpenVPN gateway(s), uncomment remote-random to load balance | # OpenVPN gateway(s) | ||||||
| comp-lzo | comp-lzo | ||||||
| nobind | nobind | ||||||
| ;proto udp | ;proto udp | ||||||
|   | |||||||
| @@ -158,8 +158,9 @@ services template = {{ template_path }}/bootstrap.conf | |||||||
| # Token URL could be for example exposed on the internet via proxypass. | # Token URL could be for example exposed on the internet via proxypass. | ||||||
| url = http://{{ common_name }}/api/token | url = http://{{ common_name }}/api/token | ||||||
|  |  | ||||||
| # Token lifetime in seconds | # Token lifetime in minutes, 30 minutes by default. | ||||||
| lifetime = 3600 | # Note that code tolerates 5 minute clock skew. | ||||||
|  | lifetime = 30 | ||||||
|  |  | ||||||
| # Secret for generating and validating tokens, regenerate occasionally | # Secret for generating and validating tokens, regenerate occasionally | ||||||
| secret = {{ token_secret }} | secret = {{ token_secret }} | ||||||
| @@ -170,5 +171,8 @@ format = | |||||||
| ;format = ovpn | ;format = ovpn | ||||||
|  |  | ||||||
| # Template for OpenVPN profile, copy certidude/templates/openvpn-client.conf | # Template for OpenVPN profile, copy certidude/templates/openvpn-client.conf | ||||||
| # to /etc/certidude/ and make modifications as necessary | # to /etc/certidude/ and make modifications as necessary. | ||||||
|  | # Note that by default all TLS Server flagged certificates are included | ||||||
|  | # as remote endpoints for the OpenVPN client. | ||||||
| openvpn profile template = {{ template_path }}/openvpn-client.conf | openvpn profile template = {{ template_path }}/openvpn-client.conf | ||||||
|  | ;openvpn profile template = /etc/certidude/openvpn-client.conf | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user