#!/bin/bash
#
# Univention SSL
#  openssl wrapper
#
# Copyright 2004-2025 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.


script=${0##*/}
usage () {
	if [ -n "$1" ]; then
		echo ""
		echo "$1"
		echo ""
	fi

	echo ""
	echo "Usage: $script command [options] "
	echo ""
	echo "Commands:"
	echo "        new"
	echo "        revoke"
	echo "        renew"
	echo "        check"
	echo "        dump"
	echo "        list"
	echo ""
	echo "Options"
	echo "        -name <uid>"
	echo "        -days <int>"
	echo "        -email <emailAddress>"
	echo "        -certname | -cn <string>"
	echo "        -organizationalunit <string>"
	echo "        -certpath <path>"
	echo "        -sslbase <path>"
	echo "        -ca <path>"
	echo "        -admingroup <groupName>"
	echo "        -country <twoLetterCountryCode>"
	echo "        -state <string>"
	echo "        -locality <string>"
	echo "        -organization <string>"
	echo "        -extfile <filename>"
	echo ""

	exit 1
}

command="$1"
shift || usage

while [ $# -gt 0 ]; do
	case "$1" in
	"-path") path="$2" ;;
	"-name") name="$2" ;;
	"-days") days="$2" ;;
	"-sslbase")
		sslbase="$2"
		test -d "$sslbase" || usage "$sslbase is not a valid directory"
		;;
	"-ca") ca="$2" ;;
	"-certpath")
		certpath="$2"
		test -d "$certpath" || usage "$certpath is not a valid directory"
		;;
	"-extfile")
		extfile="$2"
		test -f "$extfile" || usage "$extfile is not a valid file"
		;;
	"-certname" | "-cn") cn="$2" ;;
	"-organizationalunit") organizationalunit="$2" ;;
	"-email") email="$2" ;;
	"-admingroup") admingroup="$2" ;;
	"-country") country="$2" ;;
	"-state") state="$2" ;;
	"-locality") locality="$2" ;;
	"-organization") organization="$2" ;;
	*) usage "unknown option $1" ;;
	esac
	shift 2 || usage "Missing argument to $1"
done

. /usr/share/univention-ssl/make-certificates-user.sh

if [ -n "$ca" ]; then
	test -n "$sslbase" || usage "missing -sslbase for -ca"
	test -d "$sslbase/$ca" || usage "$sslbase/$ca is not a valid directory"
fi

case "$command" in
"list")
	echo "List all certificates"
	list_cert_names
	exit $?
	;;
esac

[ -n "$name" ] || usage "missing -name"
path="${certpath:-$(ucr get ssl/usercert/certpath)}/${name}"

case "$script" in
univention-certificate-user)
	[ -n "$cn" ] || usage "missing -certname or -cn"
	owner="$name"
	[ -n "$admingroup" ] || admingroup="Domain Admins"
	;;
*)
	cn="$name"
	owner="root"
	[ -n "$admingroup" ] || admingroup="DC Backup Hosts"
	;;
esac

case "$command" in
	"new")
		echo "Creating certificate: $name"
		# 1. path to cert, 2. cn, 3. days, 4. email, 5. organizationalunit, 6. country,
		# 7. state, 8. locality, 9. organization, 10. owner (uid), 11. extensions file
		if ! gencert "$path" "$cn" "$days" "$email" "$organizationalunit" "$country" "$state" "$locality" "$organization" "$owner" "$extfile"
		then
			usage "failed to generate certificate"
		fi
		if getent group "$admingroup" 2>&1 >/dev/null
		then
			chgrp -R "$admingroup" "$path"
		fi
		if getent passwd "$owner" 2>&1 >/dev/null
		then
			chown -R "$owner" "$path"
		fi
		chmod -R g+rx "$path"
		;;
	"revoke")
		echo "Revoke certificate: $name"
		revoke_cert "$cn"
		;;
	"renew")
		[ -n "$days" ] || usage "missing -days"
		echo "Renew certificate: $name"
		# 1. path to cert, 2. cn, 3. days, 4. owner (uid), 5. extensions file
		renew_cert "$path" "$cn" "$days" "$owner" "$extfile"
		;;
	"check")
		echo -n "Certificate \"$cn\" is "
		has_valid_cert "$cn" >/dev/null 2>&1
		retval=$?
		if [ $retval -eq 0 ]; then
			echo "valid"
		else
			echo "invalid"
		fi
		exit $retval
		;;
	"dump")
		echo "Dump certificate: $cn"
		openssl x509 -in "$path/cert.pem" -noout -text
		;;
	*)
		usage "unknown command: $command"
		;;
esac
