diff --git a/configuration/etckeeper_notifier.sh b/configuration/etckeeper_notifier.sh new file mode 100755 index 0000000000000000000000000000000000000000..45712ef88a082b8b2907a980a8e2398e50b92756 --- /dev/null +++ b/configuration/etckeeper_notifier.sh @@ -0,0 +1,134 @@ +#!/bin/bash +# +# etckeeper_notifier.sh +# +# Copyright (C) 2012, Branko Majic +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +program="etckeeper_notifier.sh" +version="0.1" + +function usage() { + cat <. +EOF +} + +function version() { + cat < | +| | +| This program is free software: you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by | +| the Free Software Foundation, either version 3 of the License, or | +| (at your option) any later version. | +| | +| This program is distributed 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 General Public License for more details. | +| | +| You should have received a copy of the GNU General Public License | +| along with this program. If not, see . | ++-----------------------------------------------------------------------+ + +EOF +} + +# If no arguments were given, just show usage help. +if [[ -z $1 ]]; then + usage + exit 0 +fi + +# Set-up some default values. +notificationRecipients="root@localhost" + +# Location of the etckeeper binary. +etckeeper="/usr/bin/etckeeper" + +# Parse the arguments +while getopts "e:m:vh" opt; do + case "$opt" in + e) etckeeper="$OPTARG";; + m) notificationRecipients="$OPTARG";; + v) version + exit 0;; + h) usage + exit 0;; + *) usage + exit 1;; + esac +done +i=$OPTIND +shift $(($i-1)) + +# Read the positional arguments +directory="$1" + +# Verify arguments +if [[ ! -d "$directory" ]]; then + echo "No such directory: '$directory'" >&2 + exit 2 +fi +# Verify that etckeeper is available. +if [[ ! -f $etckeeper ]]; then + echo "The etckeeper was not found in location: '$etckeeper'." >&2 + exit 2 +fi + +if "$etckeeper" -d "$directory"; then + mail -s "Uncommited changes on '$(hostname -f)' in '$directory'" $notificationRecipients < +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +program="crlpublisher.sh" +version="0.1.1" + +function usage() { + cat <. +EOF +} + +function version() { + cat < | +| | +| This program is free software: you can redistribute it and/or modify | +| it under the terms of the GNU General Public License as published by | +| the Free Software Foundation, either version 3 of the License, or | +| (at your option) any later version. | +| | +| This program is distributed 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 General Public License for more details. | +| | +| You should have received a copy of the GNU General Public License | +| along with this program. If not, see . | ++-----------------------------------------------------------------------+ + +EOF +} + +# +# Helper function that parses a CRL. +# +# Sets: +# crlIssuerDn - to the value of the CRL issuer's distinguished name. +# +function readCrlInfo() { + local crlFile="$1" + unset crlIssuerDn + + # Assume that the CRL is in DER format + if ! crlIssuerDn="$(openssl crl -issuer -inform DER -noout -in "$crlFile")"; then + if ! crlIssuerDn="$(openssl crl -issuer -inform PEM -noout -in "$crlFile")"; then + echo "Invalid CRL file '$crlFile'" >&2 + return 1 + fi + fi + + crlIssuerDn="$(echo "$crlIssuerDn" | sed -e 's#^issuer=/##;s#/#,#g')" + + return 0 +} + +# +# Helper function for clearing the common parameters. This function output +# commands that should be executed in order to clear the parameters (by using +# the "echo" command for example). +# +function clearCommonParameters() { + echo "local issuerDn publisher" +} + +# +# Helper function for verifying the common parameters +# +function verifyCommonParameters() { + if [[ -z "$issuerDn" ]]; then + echo "Publisher ($configFile): missing issuer DN" >&2 + return 1 + fi + if [[ -z "$publisher" ]]; then + echo "Publisher ($configFile): missing publisher type." >&2 + return 1 + fi +} + +# +# Implementation of scp-based publisher. +# +function publish_through_scp() { + local configFile="$1" crlFile="$2" + local remoteUser="$USER" remoteHost remoteLocation privateKey="$HOME/.ssh/id_rsa" remotePort="22" + + $(clearCommonParameters) + + . "$configFile" + + verifyCommonParameters || return 1 + + if ! [[ -f $privateKey ]]; then + echo "SCP publisher ($configFile): invalid private key - '$privateKey'." >&2 + return 1 + elif [[ -z $remoteHost ]]; then + echo "SCP publisher ($configFile): missing 'remoteHost' option." >&2 + return 1 + elif [[ -z $remoteLocation ]]; then + echo "SCP publisher ($configFile): missing 'remoteLocation' option." >&2 + return 1 + elif [[ -z "$remotePort" ]]; then + echo "SCP publisher ($configFile): missing 'remotePort' option." >&2 + return 1 + elif [[ ! $remotePort =~ ^[[:digit:]]+$ ]]; then + echo "SCP publisher ($configFile): invalid remote port - '$remotePort'." >&2 + return 1 + fi + + if [[ $issuerDn == $crlIssuerDn ]]; then + if ! scp -P "$remotePort" -i "$privateKey" "$crlFile" "$remoteUser"@"$remoteHost":"$remoteLocation"; then + echo "SCP publisher ($configFile): failed to publish CRL for '$crlIssuerDn'." >&2 + return 2 + fi + fi +} + +# If no arguments were given, just show usage help. +if [[ -z $1 ]]; then + usage + exit 0 +fi + +# Parse the arguments +while getopts "vh" opt; do + case "$opt" in + v) version + exit 0;; + h) usage + exit 0;; + *) usage + exit 1;; + esac +done +i=$OPTIND +shift $(($i-1)) + +# Determine the configuration directory to be used +configDir="/etc/crlpublisher" + +[[ ! -d $configDir ]] && configDir="$HOME/.crlpublisher" + +if [[ ! -d $configDir ]]; then + cat <&2 +No configuration directory could be found. Please create configuration directory +and the necessary configuration files in one of the following locations: + +- /etc/crlpublisher/ +- $HOME/crlpublisher/ +EOF + exit 2 +fi + +# The first argument should be a CRL file +crlFile="$1" + +# Obtain the issuer's DN first +readCrlInfo "$crlFile" || exit $? + +# Assume that the operation suceeds unless the publisher fails for any reason. +operationResult=0 + +# Process each configuration file +while read configFile; do + unset publisher + eval "$(grep "^publisher=" "$configFile")" + # Execute operation and if it failed, that's the status the script will + # return. + "publish_through_$publisher" "$configFile" "$crlFile" || operationResult="$?" +done < <(find "$configDir" -name "*.conf") + +exit "$operationResult" +