From cd547f66c04262fb11a923b3f097b4b2dcf7924c Mon Sep 17 00:00:00 2001 From: Alex Bramley Date: Sat, 13 Mar 2010 15:00:04 +0000 Subject: [PATCH] Make -t optional and configurable from config file (2/2). This also fixes a fairly major bug that could have caused config file options to override command-line ones, with no-doubt confusing consequences ;-) --- bin/ca-create-cert | 25 ++++++++++++++----------- bin/ca-init | 12 +++++++++++- bin/ca-renew-cert | 12 +++++------- bin/ca-revoke-cert | 5 ++--- lib/ca-functions | 17 ++++++++++++++++- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/bin/ca-create-cert b/bin/ca-create-cert index 067bfae..2748e0e 100755 --- a/bin/ca-create-cert +++ b/bin/ca-create-cert @@ -53,31 +53,34 @@ while :; do -h|--help) usage; exit 0;; -c|--encrypt) CRYPTKEY=""; shift;; -f|--config) shift; CONFFILE="$1"; shift;; - -t|--type) shift; CA_CRT_TYPE="$1"; shift;; - -d|--days) shift; CA_CRT_DAYS="$1"; shift;; - -b|--bits) shift; CA_CRT_BITS="$1"; shift;; + -t|--type) shift; USER_CA_CRT_TYPE="$1"; shift;; + -d|--days) shift; USER_CA_CRT_DAYS="$1"; shift;; + -b|--bits) shift; USER_CA_CRT_BITS="$1"; shift;; -n|--alt-name) shift; ALT_NAMES+=("$1"); shift;; -p|--pkcs12) MAKE_P12=1; shift;; -q|--no-qualify) QUALIFY=0; shift;; -r|--csr-only) CSR_ONLY=1; shift;; -s|--crt-only) CRT_ONLY=1; shift;; -x|--cnf-only) CNF_ONLY=1; shift;; - --country) shift; CA_CRT_C="$1"; shift;; - --state) shift; CA_CRT_ST="$1"; shift;; - --location) shift; CA_CRT_L="$1"; shift;; - --org) shift; CA_CRT_O="$1"; shift;; - --ounit) shift; CA_CRT_OU="$1"; shift;; - --email) shift; CA_CRT_E="$1"; shift;; - --comment) shift; CA_CRT_COMMENT="$1"; shift;; + --country) shift; USER_CA_CRT_C="$1"; shift;; + --state) shift; USER_CA_CRT_ST="$1"; shift;; + --location) shift; USER_CA_CRT_L="$1"; shift;; + --org) shift; USER_CA_CRT_O="$1"; shift;; + --ounit) shift; USER_CA_CRT_OU="$1"; shift;; + --email) shift; USER_CA_CRT_E="$1"; shift;; + --comment) shift; USER_CA_CRT_COMMENT="$1"; shift;; --) shift; break;; *) echo "Unknown value '$1'"; exit 1;; esac done -CA_CRT_CN="$1"; # load up the configuration file ca_load_conf +# This must be provided on the command line. There's no point setting a +# "default" certificate CN in the config, it should be different every time. +CA_CRT_CN="$1" + # parameter checking fun -- we need a type and a cn (either user or host name) if [ -z "$CA_CRT_CN" ]; then error "The host or username parameter is mandatory!" diff --git a/bin/ca-init b/bin/ca-init index 73d0990..83cffe3 100755 --- a/bin/ca-init +++ b/bin/ca-init @@ -2,6 +2,17 @@ . "/home/alex/code/ca-scripts/lib/ca-functions" +# XXX: Add an interactive mode to this script to obviate the need for a +# pre-existing config file? e.g. +# $ cd /empty/directory or /dir/containing/partial/conf +# $ ca-init -i +# or maybe: +# $ ca-init -i /path/to/CA_HOME +# + modify config file loading to check current directory too? + +# XXX: corollary to above: provide --long-options for all config file +# variables also, reducing or eliminating *requirement* for config file? + usage() { cat <<__EOT__ Usage: $PROGNAME [options] @@ -39,7 +50,6 @@ while :; do done # load up the configuration file -CA_CRT_TYPE="ca" ca_load_conf if [ 1 -eq "$CRT_ONLY" -a 1 -eq "$CNF_ONLY" ]; then diff --git a/bin/ca-renew-cert b/bin/ca-renew-cert index caf4e3a..1c8bef2 100755 --- a/bin/ca-renew-cert +++ b/bin/ca-renew-cert @@ -15,8 +15,8 @@ Options: __EOT__ } -short='hf:t:' -long='help,config:,type:' +short="hf:t:d:" +long="help,config:,type:,days:" opts=$( getopt -o "$short" -l "$long" -n "$PROGNAME" -- "$@" ) if [ 0 -ne $? ]; then echo; usage; exit 1; fi eval set -- "$opts"; @@ -25,18 +25,16 @@ while :; do case "$1" in -h|--help) usage; exit 0;; -f|--config) shift; CONFFILE="$1"; shift;; - -t|--type) shift; CA_CRT_TYPE="$1"; shift;; - -d|--days) shift; CA_CRT_DAYS="$1"; shift;; + -t|--type) shift; USER_CA_CRT_TYPE="$1"; shift;; + -d|--days) shift; USER_CA_CRT_DAYS="$1"; shift;; --) shift; break;; *) echo "Unknown value '$1'"; exit 1;; esac done -CNF_NAME="$1" - ca_load_conf -CNF_NAME=$( ca_find_cnf "$CNF_NAME" ) +CNF_NAME=$( ca_find_cnf "$1" ) CRT="$CA_HOME/crt/$CNF_NAME.crt" # make sure that configuration files are present as expected diff --git a/bin/ca-revoke-cert b/bin/ca-revoke-cert index fa74a16..ebe8804 100755 --- a/bin/ca-revoke-cert +++ b/bin/ca-revoke-cert @@ -26,18 +26,17 @@ while :; do case "$1" in -h|--help) usage; exit 0;; -f|--config) shift; CONFFILE="$1"; shift;; - -t|--type) shift; CA_CRT_TYPE="$1"; shift;; + -t|--type) shift; USER_CA_CRT_TYPE="$1"; shift;; -i|--template) shift; INDEXTPL="$1"; shift;; -o|--output) shift; INDEXOUT="$1"; shift;; --) shift; break;; *) echo "Unknown value '$1'"; exit 1;; esac done -CNF_NAME="$1" ca_load_conf -CNF_NAME=$( ca_find_cnf "$CNF_NAME" "$TYPE" ) +CNF_NAME=$( ca_find_cnf "$1" ) CRT="$CA_HOME/crt/$CNF_NAME.crt" openssl ca -config $CA_HOME/cnf/$CA_NAME.ca.cnf \ diff --git a/lib/ca-functions b/lib/ca-functions index 6ec333a..c5cda17 100644 --- a/lib/ca-functions +++ b/lib/ca-functions @@ -30,13 +30,20 @@ ca_check_var() { fi" } +ca_override_conf() { + local varname + + varname="${1#USER_}" + eval "$varname=\"\$USER_$varname\"" +} + ca_set_default() { local varname vardef varname="$1" vardef="$2" eval "if [ -z \"\$$varname\" ]; then - $varname=\"$vardef\"; + $varname=\"$vardef\" fi" } @@ -72,6 +79,14 @@ __TESTS__ error "Parsing config file $CONFFILE failed:\n$error" fi + # check user-provided variables and copy them to CA_ namespace to override + # any defaults that have potentially been set in configuration file + # XXX: this is getting really dirty now, perhaps find an alternative? + set | awk -F\= '/^USER_CA_[A-Z_]*=/{print $1}' | while read user_var; do + ca_override_conf "$user_var" + done + + # XXX: and this alternative should probably have better validation ;-) case "$CA_CRT_TYPE" in server|client|user) :;; *) error "Unrecognised certificate type '$CA_CRT_TYPE'!";;