mirror_corosync-qdevice/qdevices/corosync-qnetd-certutil.sh
Jan Friesse e1e9ae1086 certutils: Fix warnings found by coverity
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
2018-11-26 14:04:46 +01:00

256 lines
7.3 KiB
Bash

#!@BASHPATH@
#
# Copyright (c) 2015-2018 Red Hat, Inc.
#
# All rights reserved.
#
# Author: Jan Friesse (jfriesse@redhat.com)
#
# This software licensed under BSD license, the text of which follows:
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# - Neither the name of the Red Hat, Inc. nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
#
CONFIG_DIR="@COROSYSCONFDIR@/qnetd"
DB_DIR="$CONFIG_DIR/nssdb"
# Validity of certificate (months)
CRT_VALIDITY=1200
CA_NICKNAME="QNet CA"
SERVER_NICKNAME="QNetd Cert"
CA_SUBJECT="CN=QNet CA"
SERVER_SUBJECT="CN=Qnetd Server"
PWD_FILE="$DB_DIR/pwdfile.txt"
NOISE_FILE="$DB_DIR/noise.txt"
SERIAL_NO_FILE="$DB_DIR/serial.txt"
CA_EXPORT_FILE="$DB_DIR/qnetd-cacert.crt"
CERTDB_FILES=("cert9.db key4.db pkcs11.txt"
"cert8.db key3.db secmod.db")
usage() {
echo "$0: [-i|-s] [-c certificate] [-G] [-n cluster_name]"
echo
echo " -i Initialize QNetd CA and generate server certificate"
echo " -s Sign cluster certificate (needs cluster certificate)"
echo " -c certificate CRQ certificate file name"
echo " -G Do not set group write bit for new files"
echo " -n cluster_name Name of cluster (for -s operation)"
exit 0
}
chown_ref_cfgdir() {
if [ "$UID" == "0" ];then
chown --reference="$CONFIG_DIR" "$@" 2>/dev/null || chown "$(stat -f "%u:%g" "$CONFIG_DIR")" "$@" 2>/dev/null || return $?
fi
}
# get_perm [directory]
# Return permission based on -G and directory flag
get_perm() {
if [ "$1" == true ];then
[ "$SET_GROUP_WRITE_BIT" == true ] && echo "0770" || echo "0750"
else
[ "$SET_GROUP_WRITE_BIT" == true ] && echo "0660" || echo "0640"
fi
}
create_new_noise_file() {
local noise_file="$1"
if [ ! -e "$noise_file" ];then
echo "Creating new noise file $noise_file"
(ps -elf; date; w) | sha1sum | (read sha_sum rest; echo $sha_sum) > "$noise_file"
chown_ref_cfgdir "$noise_file"
chmod "$(get_perm)" "$noise_file"
else
echo "Using existing noise file $noise_file"
fi
}
get_serial_no() {
local serial_no
if ! [ -f "$SERIAL_NO_FILE" ];then
echo "100" > $SERIAL_NO_FILE
chown_ref_cfgdir "$SERIAL_NO_FILE"
chmod "$(get_perm)" "$SERIAL_NO_FILE"
fi
serial_no=`cat $SERIAL_NO_FILE`
serial_no=$((serial_no+1))
echo "$serial_no" > $SERIAL_NO_FILE
echo "$serial_no"
}
find_certdb_files() {
for cert_files_index in "${!CERTDB_FILES[@]}";do
cert_files=${CERTDB_FILES[$cert_files_index]}
test_file=${cert_files%% *}
if [ -f "$DB_DIR/$test_file" ];then
echo "$cert_files"
return 0
fi
done
return 1
}
init_qnetd_ca() {
cert_files=`find_certdb_files`
if [ "$cert_files" != "" ];then
echo "Certificate database ($DB_DIR) already exists. Delete it to initialize new db" >&2
exit 1
fi
if ! [ -d "$DB_DIR" ];then
echo "Creating $DB_DIR"
mkdir -p "$DB_DIR"
chown_ref_cfgdir "$DB_DIR"
chmod "$(get_perm true)" "$DB_DIR"
fi
echo "Creating new key and cert db"
echo -n "" > "$PWD_FILE"
chown_ref_cfgdir "$PWD_FILE"
chmod "$(get_perm)" "$PWD_FILE"
certutil -N -d "$DB_DIR" -f "$PWD_FILE"
cert_files=`find_certdb_files`
if [ "$cert_files" == "" ];then
echo "Can't find certificate database files. Certificate database ($DB_DIR) cannot be created" >&2
exit 1
fi
for fname in $cert_files;do
chown_ref_cfgdir "$DB_DIR/$fname"
chmod "$(get_perm)" "$DB_DIR/$fname"
done
create_new_noise_file "$NOISE_FILE"
echo "Creating new CA"
# Create self-signed certificate (CA). Asks 3 questions (is this CA, lifetime and critical extension
echo -e "y\n0\ny\n" | certutil -S -n "$CA_NICKNAME" -s "$CA_SUBJECT" -x \
-t "CT,," -m "$(get_serial_no)" -v $CRT_VALIDITY -d "$DB_DIR" \
-z "$NOISE_FILE" -f "$PWD_FILE" -2
# Export CA certificate in ascii
certutil -L -d "$DB_DIR" -n "$CA_NICKNAME" > "$CA_EXPORT_FILE"
certutil -L -d "$DB_DIR" -n "$CA_NICKNAME" -a >> "$CA_EXPORT_FILE"
chown_ref_cfgdir "$CA_EXPORT_FILE"
certutil -S -n "$SERVER_NICKNAME" -s "$SERVER_SUBJECT" -c "$CA_NICKNAME" -t "u,u,u" -m "$(get_serial_no)" \
-v $CRT_VALIDITY -d "$DB_DIR" -z "$NOISE_FILE" -f "$PWD_FILE"
echo "QNetd CA certificate is exported as $CA_EXPORT_FILE"
}
sign_cluster_cert() {
cert_files=`find_certdb_files`
if [ "$cert_files" == "" ];then
echo "Certificate database doesn't exists. Use $0 -i to create it" >&2
exit 1
fi
echo "Signing cluster certificate"
certutil -C -v "$CRT_VALIDITY" -m "$(get_serial_no)" -i "$CERTIFICATE_FILE" -o "$CRT_FILE" -c "$CA_NICKNAME" -d "$DB_DIR"
chown_ref_cfgdir "$CRT_FILE"
echo "Certificate stored in $CRT_FILE"
}
OPERATION=""
CERTIFICATE_FILE=""
CLUSTER_NAME=""
SET_GROUP_WRITE_BIT=true
while getopts ":Ghisc:n:" opt; do
case $opt in
i)
OPERATION=init_qnetd_ca
;;
s)
OPERATION=sign_cluster_cert
;;
h)
usage
;;
c)
CERTIFICATE_FILE="$OPTARG"
;;
G)
SET_GROUP_WRITE_BIT=false
;;
n)
CLUSTER_NAME="$OPTARG"
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
[ "$OPERATION" == "" ] && usage
CRT_FILE="$DB_DIR/cluster-$CLUSTER_NAME.crt"
case "$OPERATION" in
"init_qnetd_ca")
init_qnetd_ca
;;
"sign_cluster_cert")
if ! [ -e "$CERTIFICATE_FILE" ];then
echo "Can't open certificate file $CERTIFICATE_FILE" >&2
exit 2
fi
if [ "$CLUSTER_NAME" == "" ];then
echo "You have to specify cluster name" >&2
exit 2
fi
sign_cluster_cert
;;
*)
usage
;;
esac