Skip to content

Commit

Permalink
Add installation option for certificate (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
anders-kiaer authored Sep 30, 2019
1 parent 86a9289 commit f4c3efe
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 16 deletions.
59 changes: 45 additions & 14 deletions webviz_config/_certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
import re
import sys
import socket
import datetime
import pathlib
import getpass
import datetime
import subprocess # nosec

from cryptography import x509
from cryptography.x509.oid import NameOID
Expand All @@ -30,15 +32,13 @@
SERVER_KEY_FILENAME = "server.key"
SERVER_CRT_FILENAME = "server.crt"

DNS_NAME = re.sub("[0-9]+", "*", socket.getfqdn())


def user_data_dir():
"""Returns platform specific path to store user application data
"""

if sys.platform == "win32":
return os.path.normpath(os.path.expanduser("~/Application Data/" "webviz_cert"))
return os.path.normpath(os.path.expanduser("~/Application Data/webviz"))
elif sys.platform == "darwin":
return os.path.expanduser("~/Library/Application Support/webviz")
else:
Expand Down Expand Up @@ -66,7 +66,7 @@ def create_key(key_path):
def certificate_template(subject, issuer, public_key, ca=False):

if ca:
not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(days=365)
not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(days=365 * 10)

else: # shorter valid length for on-the-fly certificates
not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(days=7)
Expand All @@ -80,10 +80,7 @@ def certificate_template(subject, issuer, public_key, ca=False):
.not_valid_before(datetime.datetime.utcnow())
.not_valid_after(not_valid_after)
.add_extension(
x509.SubjectAlternativeName(
[x509.DNSName("localhost"), x509.DNSName(DNS_NAME)]
),
critical=True,
x509.SubjectAlternativeName([x509.DNSName("localhost")]), critical=True
)
.add_extension(x509.BasicConstraints(ca=ca, path_length=None), critical=True)
)
Expand Down Expand Up @@ -121,8 +118,42 @@ def create_ca(args):
re.findall(".{8,8}", cert.fingerprint(hashes.SHA1()).hex()) # nosec
).upper()

print(
f"""\n{terminal_colors.BLUE}{terminal_colors.BOLD}
installed = False
if args.auto_install:
try:
subprocess.run( # nosec
[
"certutil",
"-d",
f"sql:{pathlib.Path.home() / '.pki' / 'nssdb'}",
"-A",
"-t",
"CT,C,c",
"-n",
"webviz",
"-i",
ca_crt_path,
],
check=True,
)
installed = True
print(
f"{terminal_colors.GREEN}{terminal_colors.BOLD}"
"Successfully installed webviz certificate. "
"Ready to browse applications on localhost."
f"{terminal_colors.END}"
)
except (PermissionError, subprocess.CalledProcessError):
print(
f"{terminal_colors.RED}"
"Automatic installation of webviz certificate failed. "
"Falling back to manual installation."
f"{terminal_colors.END}"
)

if not installed:
print(
f"""{terminal_colors.BLUE}{terminal_colors.BOLD}
Created CA key and certificate files (both saved in {directory}).
Keep the key file ({CA_KEY_FILENAME}) private. The certificate file
({CA_CRT_FILENAME}) is not sensitive, and you can import it in
Expand All @@ -143,8 +174,8 @@ def create_ca(args):
When done, you do not have to rerun "webviz certificate" or do this procedure
before the certificate expiry date has passed. The certificate is only valid
for localhost and {DNS_NAME}.{terminal_colors.END}"""
)
for localhost.{terminal_colors.END}"""
)


def create_certificate(directory):
Expand All @@ -159,7 +190,7 @@ def create_certificate(directory):
if not os.path.isfile(ca_key_path) or not os.path.isfile(ca_crt_path):
raise RuntimeError(
"Could not find CA key and certificate. Please "
'run the command "webviz certificate" and '
'run the command "webviz certificate --auto-install" and '
"try again"
)

Expand Down
13 changes: 11 additions & 2 deletions webviz_config/command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,22 @@ def check_port(port):
# Add "certificate" parser:

parser_cert = subparsers.add_parser(
"certificate", help="Create a root " "certificate " "for https"
"certificate",
help="Create a https certificate authority for webviz "
"(validity limited to localhost only)",
)

parser_cert.add_argument(
"--force",
action="store_true",
help="Overwrite webviz root https certificate if it already exist",
help="Overwrite webviz root https certificate if it already exists",
)

parser_cert.add_argument(
"--auto-install",
action="store_true",
help="Automatically install the webviz certificate in "
"your personal public key infrastructure",
)

parser_cert.set_defaults(func=create_ca)
Expand Down

0 comments on commit f4c3efe

Please sign in to comment.