Files
@ b14d3faa45c4
Branch filter:
Location: majic-scripts/x509/crlpublisher.sh
b14d3faa45c4
10.6 KiB
text/x-sh
[factorio_development.sh] Added (personal) workaround for tag signing:
- Older versions of git (<2.23) do not have the tag.gpgSign
option. Try to emulate it by appending the --sign option if it is
set in git configuration.
- Older versions of git (<2.23) do not have the tag.gpgSign
option. Try to emulate it by appending the --sign option if it is
set in git configuration.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | #!/bin/bash
#
# crlpublisher.sh
#
# Copyright (C) 2012, Branko Majic <branko@majic.rs>
#
# 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 <http://www.gnu.org/licenses/>.
#
program="crlpublisher.sh"
version="0.1.2"
function usage() {
cat <<EOF
$program $version, a non-interactive utility for publishing CRL's.
Usage: $program [OPTIONS] crl_file
$program is a non-interactive utility for publishing CRL's. It takes a single
argument pointing to the CRL file which should be published. The CRL file should
be provided either in DER or PEM encoding.
The script is written to support several types of publishers. Currently
supported publishers are:
- scp - Publishes to a remote server using public-key authentication through
SSH's scp command.
- archiver - Archives CRLs to a local directory. This publisher will output
the CRLs to a specific directory using the filename pattern
'issuerdn_fulldateutc_crlnumber.format' where issuerdn is replaced by the
issuer DN of the CRL, fulldateutc is replaced with last update date of CRL
in format YYYY-MM-DD-HH:MM:SS:TZ (e.g. 2013-01-01-00:00:00:+00:00),
crlnumber is replaced with the CRL number in decimal format, and format is
replaced by the format of the CRL file (PEM for OpenSSL-style
base64-encoded CRLs, DER for binary CRLs).
Publishing options are kept within configuration files. Configuration files
should be placed in the explicitly set configurtion directory (set with the -c
option), or one of the following default locations:
- /etc/crlpublisher/
- ~/.crlpublisher/
Configuration files must end with a .conf extension. All other files will be
ignored. Each configuraiton file should contain information for a single
publisher matching a single issuer DN.
Common configuration options
issuerDn (mandatory) - Specifies the distinguished name of the issuer of CRL
which should be matched for the particular configuration.
publisher (mandatory) - Type of publisher this configuration refers to.
Configuration options for 'scp' publisher:
remoteHost (mandatory) - Remote IP or resolvable hostname/FQDN of the target
server to which the CRL will be published.
remoteLocation (mandatory) - Full path on the remote server to the directory
location to which the CRL will be published.
remoteUser (optional) - Name of the remote user which will be used for
logging-in. Default is the user executing the script.
privateKey (optional) - Path to the private key which should be used for
logging-in onto remote server. Default is ~/.ssh/id_rsa.
remotePort (optional) - Remote port that should be used for connecting to
the SSH server on remote host. Default is to use port 22.
Configuration options for 'archiver' publisher:
acrhiveDir (mandatory) - Directory where the CRLs will be archived.
$program accepts the following options:
-c dir Explicit configuration directory from which the publisher
configuration files should be read.
-v show script version and licensing information
-h show usage help
Please report bugs and send feature requests to <branko@majic.rs>.
EOF
}
function version() {
cat <<EOF
$program, version $version
+-----------------------------------------------------------------------+
| Copyright (C) 2012, Branko Majic <branko@majic.rs> |
| |
| 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 <http://www.gnu.org/licenses/>. |
+-----------------------------------------------------------------------+
EOF
}
#
# Helper function that parses a CRL.
#
# Sets:
# crlIssuerDn - to the value of the CRL issuer's distinguished name.
# crlNumber - to the value of CRL number.
# crlFormat - to the type of CRL (PEM/DER).
# crlLastUpdate - to the last update time of CRL.
# crlNextUpdate - to the next update time of CRL.
#
function readCrlInfo() {
local crlFile="$1"
unset crlIssuerDn crlNumber crlFormat crlLastUpdate crlNextUpdate
# Detect format of the CRL.
if openssl crl -noout -inform DER -in "$crlFile" 2>/dev/null; then
crlFormat="DER"
elif openssl crl -noout -inform PEM -in "$crlFile" 2>/dev/null; then
crlFormat="PEM"
else
echo "Invalid CRL file '$crlFile'" >&2
return 1
fi
# Read the CRL information
crlIssuerDn=$(openssl crl -issuer -inform "$crlFormat" -noout -in "$crlFile" | sed -e 's#^issuer=/##;s#/#,#g')
# @TODO: The -crlnumber option was added only to more recent versions of OpenSSL.
#crlNumber=$(echo "ibase=16;obase=A;$(openssl crl -crlnumber -inform "$crlFormat" -noout -in "$crlFile" | sed -e 's/crlNumber=//')" | bc)
crlNumber=$(openssl crl -text -inform "$crlFormat" -noout -in "$crlFile" | grep -A1 'X509v3 CRL Number' | tail -n1 | grep -o '[[:digit:]]\+')
crlLastUpdate=$(openssl crl -lastupdate -inform "$crlFormat" -noout -in "$crlFile" | sed -e 's/lastUpdate=//')
crlNextUpdate=$(openssl crl -nextupdate -inform "$crlFormat" -noout -in "$crlFile" | sed -e 's/nextUpdate=//')
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
}
#
# Implementation of archiver.
#
function publish_through_archiver() {
local configFile="$1" crlFile="$2"
local archiveDir crlLastUpdateParsed
$(clearCommonParameters)
. "$configFile"
verifyCommonParameters || return 1
if ! [[ -d $archiveDir ]]; then
echo "Archiver publisher ($configFile): invalid archive directory - '$archiveDir'" >&2
return 1
fi
# Get the issuance date/time of the issued CRL.
crlLastUpdateParsed=$(TZ=UTC date -d "$crlLastUpdate" +%F-%T:%z)
# Set-up the filename.
filename="${crlIssuerDn}_${crlLastUpdateParsed}_${crlNumber}.$crlFormat"
# Copy the file.
cp "$crlFile" "$archiveDir/$filename"
}
# If no arguments were given, just show usage help.
if [[ -z $1 ]]; then
usage
exit 0
fi
# Parse the arguments
while getopts "c:vh" opt; do
case "$opt" in
c) configDir="$OPTARG";;
v) version
exit 0;;
h) usage
exit 0;;
*) usage
exit 1;;
esac
done
i=$OPTIND
shift $(($i-1))
# Figure out which configuration directory to use.
if [[ -n $configDir && ! -d $configDir ]]; then
echo "Specified configuration directory '$configDir' does not exist." >&2
exit 2
# If no configuration directory was provided, try one of the default ones.
elif [[ -z $configDir ]]; then
configDir="/etc/crlpublisher"
[[ ! -d $configDir ]] && configDir="$HOME/.crlpublisher"
if [[ ! -d $configDir ]]; then
cat <<EOF >&2
No configuration directory could be found. Please provide configuration
directory path using the -c option, or create configuration directory and the
necessary configuration files in one of the following locations:
- /etc/crlpublisher/
- $HOME/crlpublisher/
EOF
exit 2
fi
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"
|