aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconvertsecrets217
1 files changed, 0 insertions, 217 deletions
diff --git a/convertsecrets b/convertsecrets
deleted file mode 100755
index b93f8c6..0000000
--- a/convertsecrets
+++ /dev/null
@@ -1,217 +0,0 @@
-#!/usr/bin/env nix-shell
-#!nix-shell -i python3 -p "python3.withPackages(ps: [ ps.pip ps.consul ps.ldap ps.passlib ps.requests ps.six ])"
-
-# DEPENDENCY: python-consul
-import consul
-
-# DEPENDENCY: python-ldap
-import ldap
-
-# DEPENDENCY: passlib
-from passlib.hash import ldap_salted_sha1
-
-import os
-import sys
-import glob
-import subprocess
-import getpass
-import base64
-from secrets import token_bytes
-
-
-"""
-TODO: this will be a utility to handle secrets in the Consul database
-for the various components of the Deuxfleurs infrastructure
-
-Functionnalities:
-- check that secrets are correctly configured
-- help user fill in secrets
-- create LDAP service users and fill in corresponding secrets
-- maybe one day: manage SSL certificates and keys
-
-It uses files placed in <module_name>/secrets/* to know what secrets
-it should handle. These secret files contain directives for what to do
-about these secrets.
-
-Example directives:
-
-USER <description>
-(a secret that must be filled in by the user)
-
-USER_LONG <description>
-(the same, indicates that the secret fits on several lines)
-
-CMD <command>
-(a secret that is generated by running this command)
-
-CMD_ONCE <command>
-(same, but value is not changed when doing a regen)
-
-CONST <constant value>
-(the secret has a constant value set here)
-
-CONST_LONG
-<constant value, several lines>
-(same)
-
-SERVICE_DN <service name> <service description>
-(the LDAP DN of a service user)
-
-SERVICE_PASSWORD <service name>
-(the LDAP password for the corresponding service user)
-
-SSL_CERT <cert name> <list of domains>
-(a SSL domain for the given domains)
-
-SSL_KEY <cert name>
-(the SSL key going with corresponding certificate)
-
-RSA_PUBLIC_KEY <key name> <key description>
-(a public RSA key)
-
-RSA_PRIVATE_KEY <key name>
-(the corresponding private RSA key)
-"""
-
-
-# Parameters
-LDAP_URL = "ldap://localhost:1389"
-SERVICE_DN_SUFFIX = "ou=services,ou=users,dc=deuxfleurs,dc=fr"
-consul_server = consul.Consul()
-
-
-# ----
-
-USER = "USER"
-USER_LONG = "USER_LONG"
-CMD = "CMD"
-CMD_ONCE = "CMD_ONCE"
-CONST = "CONST"
-CONST_LONG = "CONST_LONG"
-SERVICE_DN = "SERVICE_DN"
-SERVICE_PASSWORD = "SERVICE_PASSWORD"
-SSL_CERT = "SSL_CERT"
-SSL_KEY = "SSL_KEY"
-RSA_PUBLIC_KEY = "RSA_PUBLIC_KEY"
-RSA_PRIVATE_KEY = "RSA_PRIVATE_KEY"
-
-class bcolors:
- HEADER = '\033[95m'
- OKBLUE = '\033[94m'
- OKCYAN = '\033[96m'
- OKGREEN = '\033[92m'
- WARNING = '\033[93m'
- FAIL = '\033[91m'
- ENDC = '\033[0m'
- BOLD = '\033[1m'
- UNDERLINE = '\033[4m'
-
-def read_secret(key, file_path):
- lines = [l.strip() for l in open(file_path, "r")]
- if len(lines) == 0:
- print(bcolors.FAIL, "ERROR:", bcolors.ENDC, "Empty file in", file_path)
- sys.exit(-1)
- l0 = lines[0].split(" ")
- stype = l0[0]
- secret = {"type": stype, "key": key}
- if stype in [USER, USER_LONG]:
- secret["desc"] = " ".join(l0[1:])
- elif stype in [CMD, CMD_ONCE]:
- secret["cmd"] = " ".join(l0[1:])
- elif stype == CONST:
- secret["value"] = " ".join(l0[1:])
- elif stype == CONST_LONG:
- secret["value"] = "\n".join(lines[1:])
- elif stype in [SERVICE_DN, SERVICE_PASSWORD]:
- secret["service"] = l0[1]
- if stype == SERVICE_DN:
- secret["service_desc"] = " ".join(l0[2:])
- elif stype in [SSL_CERT, SSL_KEY]:
- secret["cert_name"] = l0[1]
- if stype == SSL_CERT:
- secret["cert_domains"] = l0[2:]
- elif stype in [RSA_PUBLIC_KEY, RSA_PRIVATE_KEY]:
- secret["key_name"] = l0[1]
- if stype == RSA_PUBLIC_KEY:
- secret["key_desc"] = " ".join(l0[2:])
- else:
- print(bcolors.FAIL, "ERROR:", bcolors.ENDC, "Invalid secret type", stype, "in", file_path)
- sys.exit(-1)
-
- return secret
-
-def read_secrets(module_list):
- secrets = {}
- for mod in module_list:
- for file_path in glob.glob(mod.strip('/') + "/secrets/**", recursive=True):
- if os.path.isfile(file_path):
- key = '/'.join(file_path.split("/")[1:])
- secrets[key] = read_secret(key, file_path)
- return secrets
-
-def convert_secrets(module_list):
- for mod in module_list:
- print("converting module: ", mod)
- secrets = read_secrets([mod])
- with open(os.path.join(mod.strip('/'), "secrets.toml"), "w") as file:
- for (secret_key, secret) in secrets.items():
- file.write("[secrets.\"{}\"]\n".format("/".join(secret_key.split("/")[1:])))
- ty = secret["type"]
- if ty in [CMD, CMD_ONCE]:
- newsecret = {
- "type": "command",
- "rotate": ty != "CMD_ONCE",
- "command": secret["cmd"],
- }
- elif ty in [USER, USER_LONG]:
- newsecret = {
- "type": "user",
- "multiline": ty == "USER_LONG",
- "description": secret["desc"],
- }
- elif ty in [CONST, CONST_LONG]:
- newsecret = {
- "type": "constant",
- "value": secret["value"],
- }
- else:
- newsecret = {
- "type": secret["type"],
- }
- if "service_desc" in secret:
- newsecret["description"] = secret["service_desc"]
- if "key_desc" in secret:
- newsecret["description"] = secret["key_desc"]
- if "cert_name" in secret:
- newsecret["name"] = secret["cert_name"]
- if "key_name" in secret:
- newsecret["name"] = secret["key_name"]
- for k in ["service", "cert_domains"]:
- if k in secret:
- newsecret[k] = secret[k]
- for (k, v) in newsecret.items():
- if type(v) == bool:
- if v:
- file.write("{} = true\n".format(k))
- elif type(v) == str:
- file.write("{} = {}\n".format(k, repr(v)))
- else:
- print("warning: invalid value: ", v)
- print("secret to fix: ", k)
- file.write("{} = {}\n".format(k, repr(repr(v))))
- file.write("\n")
-
-
-# ---- MAIN ----
-
-if __name__ == "__main__":
- for i, val in enumerate(sys.argv):
- if val == "convert":
- convert_secrets(sys.argv[i+1:])
- break
- else:
- print("Usage:")
- print(" convertsecrets convert <module name>...")
-
-
-# vim: set sts=4 ts=4 sw=4 tw=0 ft=python et :