Commit | Line | Data |
---|---|---|
b7068ae3 | 1 | #!/bin/bash |
4c237a24 | 2 | # |
3 | # Install a signed certificate, placing a complimentary copy in the | |
139a90c8 | 4 | # member's homedir. Validation is done on the certificate before |
5 | # allowing it to be installed. Also grant member domtool permissions | |
6 | # for the certificate. | |
4c237a24 | 7 | # |
b7068ae3 | 8 | # If the certificate comes from the member's home directory, then |
9 | # don't place an extra copy there. | |
4c237a24 | 10 | # |
652feaf6 | 11 | # Run this on an administrative node while holding admin tokens. |
4c237a24 | 12 | # |
b7068ae3 | 13 | # Usage: ca-install member domain cert-file.pem [key-file.pem] |
14 | ||
15 | function usage () { | |
28174df8 | 16 | echo "Usage: ca-install member domain cert-file.pem [key-file.pem] [intermediate-chain.pem]" |
b7068ae3 | 17 | exit 1 |
18 | } | |
4c237a24 | 19 | |
20 | # Check arguments | |
28174df8 | 21 | if test -n "$6"; then |
b7068ae3 | 22 | echo "Error: Too many arguments." |
23 | usage | |
4c237a24 | 24 | elif test -z "$3"; then |
b7068ae3 | 25 | echo "Error: Not enough arguments." |
26 | usage | |
4c237a24 | 27 | else |
b7068ae3 | 28 | MEMBER=$1 |
4c237a24 | 29 | DOMAIN=$2 |
30 | CERT=$3 | |
31 | KEY=$4 | |
28174df8 | 32 | CHAIN=$5 |
4c237a24 | 33 | fi |
34 | ||
e7dafc9b | 35 | WEBSERVERS="shelob.hcoop.net minsky.hcoop.net" |
b7068ae3 | 36 | |
37 | function verify_cert () { | |
38 | if test -z "$2" || test -n "$3"; then | |
39 | echo "Bad programming." | |
40 | exit 1 | |
41 | fi | |
42 | local CERT=$1 | |
43 | local KEY=$2 | |
44 | local MOD1=$(openssl x509 -noout -modulus -in "$CERT" 2>&1) | |
45 | if test $(echo "$MOD1" | wc -c) -lt 500; then | |
46 | echo "Error: Bad x509 part in certificate." | |
47 | exit 1 | |
48 | fi | |
49 | local MOD2=$(openssl rsa -noout -modulus -in "$KEY" 2>&1) | |
50 | if test $(echo "$MOD2" | wc -c) -lt 500; then | |
51 | echo "Error: Bad RSA part in certificate or key." | |
52 | exit 1 | |
53 | fi | |
54 | if test "$MOD1" != "$MOD2"; then | |
55 | echo "Error: x509 and RSA parts in certificate do not match." | |
56 | exit 1 | |
57 | fi | |
58 | } | |
59 | ||
28174df8 CE |
60 | function verify_chain () { |
61 | if test -z "$1" || test -n "$2"; then | |
62 | echo "Bad programming." | |
63 | exit 1 | |
64 | fi | |
65 | # just make sure the intermediate chain contains a cert, might be | |
66 | # nice if this checked if it was used to sign the user's cert | |
67 | local CERT=$1 | |
68 | local MOD1=$(openssl x509 -noout -modulus -in "$CERT" 2>&1) | |
69 | if test $(echo "$MOD1" | wc -c) -lt 500; then | |
70 | echo "Error: Bad x509 part in intermediate chain." | |
71 | exit 1 | |
72 | fi | |
73 | } | |
74 | ||
652feaf6 | 75 | # Make sure we run this from an admin host... |
00034618 | 76 | if test "$(hostname -s)" != "gibran"; then |
6d76f213 | 77 | echo "Error: This script must be run from gibran." |
b7068ae3 | 78 | exit 1 |
79 | fi | |
80 | ||
4c237a24 | 81 | # Sanity-check some paths |
b7068ae3 | 82 | if test ! -f "$CERT"; then |
83 | echo "Error: Nonexistent or unreadable cert $CERT." | |
4c237a24 | 84 | exit 1 |
85 | fi | |
b7068ae3 | 86 | if test -n "$KEY" && test ! -f "$KEY"; then |
87 | echo "Error: Nonexistent or unreadable key $KEY." | |
4c237a24 | 88 | exit 1 |
28174df8 CE |
89 | fi |
90 | if test -n "$CHAIN" && test ! -f "$CHAIN"; then | |
91 | echo "Error: Nonexistent or unreadable intermediate chain $CHAIN." | |
92 | exit 1 | |
4c237a24 | 93 | fi |
94 | ||
b7068ae3 | 95 | # Check for valid username |
96 | if ! getent passwd "$MEMBER" > /dev/null; then | |
97 | echo "Error: Invalid user \"$MEMBER\"." | |
98 | exit 1 | |
99 | fi | |
100 | ||
4c237a24 | 101 | # Figure out destination for complimentary copy |
102 | APACHE_DEST=/etc/apache2/ssl/user/$DOMAIN.pem | |
b7068ae3 | 103 | MEMBERHOME=$(getent passwd $MEMBER | cut -d':' -f 6) |
4c237a24 | 104 | if test -n "$KEY"; then |
b7068ae3 | 105 | DEST="$(dirname $KEY)/$DOMAIN.pem" |
4c237a24 | 106 | else |
107 | DEST= | |
108 | fi | |
109 | ||
110 | # Perform complimentary copy | |
111 | if test -z "$DEST"; then | |
b7068ae3 | 112 | echo "No key specified, so skipping complimentary copy." |
113 | elif echo "$CERT" | grep "^$MEMBERHOME" > /dev/null; then | |
114 | echo "Member already has a cert, skipping the complimentary copy." | |
115 | elif test -f "$DEST"; then | |
116 | echo "Not overwriting existing file $DEST." | |
4c237a24 | 117 | else |
b7068ae3 | 118 | echo "Copying signed certificate to member's home directory ..." |
119 | cp "$CERT" "$DEST" | |
120 | chown $MEMBER:nogroup "$DEST" | |
4c237a24 | 121 | fi |
122 | echo | |
123 | ||
124 | # Determine whether we need to concatenate a private key | |
53aedbca | 125 | if openssl rsa -noout -check -in "$CERT" > /dev/null; then |
4c237a24 | 126 | KEY= |
127 | else | |
128 | if test -z "$KEY"; then | |
b7068ae3 | 129 | echo "Error: No RSA private key is included with this certificate." |
4c237a24 | 130 | exit 1 |
131 | fi | |
132 | fi | |
133 | ||
b7068ae3 | 134 | # Verify certificate and key |
135 | echo "Validating certificate ..." | |
4c237a24 | 136 | if test -z "$KEY"; then |
b7068ae3 | 137 | verify_cert "$CERT" "$CERT" |
4c237a24 | 138 | else |
b7068ae3 | 139 | verify_cert "$CERT" "$KEY" |
140 | fi | |
28174df8 CE |
141 | if test -n "$CHAIN"; then |
142 | verify_chain "$CHAIN" | |
143 | fi | |
b7068ae3 | 144 | echo "Certificate passed validatation." |
145 | echo | |
146 | ||
147 | # Copy complete certificate to webserver | |
148 | if test -z "$KEY"; then | |
149 | echo "Installing certificate to Apache SSL directory ..." | |
00034618 CE |
150 | for WEBSERVER in $WEBSERVERS; do |
151 | < "$CERT" ssh $WEBSERVER sudo tee "$APACHE_DEST" > /dev/null | |
152 | done | |
b7068ae3 | 153 | else |
154 | echo "Installing certificate and key to Apache SSL directory ..." | |
00034618 | 155 | for WEBSERVER in $WEBSERVERS; do |
28174df8 | 156 | cat "$CERT" "$KEY" "$CHAIN" | ssh $WEBSERVER sudo tee "$APACHE_DEST" > /dev/null |
00034618 | 157 | done |
4c237a24 | 158 | fi |
00034618 CE |
159 | for WEBSERVER in $WEBSERVERS; do |
160 | ssh $WEBSERVER sudo chmod 400 "$APACHE_DEST" > /dev/null | |
161 | done | |
4c237a24 | 162 | echo |
163 | ||
164 | # Grant Domtool permissions | |
b7068ae3 | 165 | echo "Granting member Domtool permissions for the certificate ..." |
166 | domtool-admin grant $MEMBER cert "$APACHE_DEST" | |
167 | echo | |
168 | ||
13910790 | 169 | echo "Restarting apache ..." |
00034618 CE |
170 | for WEBSERVER in $WEBSERVERS; do |
171 | ssh $WEBSERVER sudo apache2ctl graceful | |
172 | done | |
13910790 | 173 | echo |
174 | ||
b7068ae3 | 175 | # Tell admin what to do |
176 | echo "Done. Tell $MEMBER that the certificate is available for use at" | |
177 | echo " $APACHE_DEST" |