]>
Commit | Line | Data |
---|---|---|
064af421 BP |
1 | #! /bin/sh |
2 | ||
e0edde6f | 3 | # Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc. |
a14bc59f BP |
4 | # |
5 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | # you may not use this file except in compliance with the License. | |
7 | # You may obtain a copy of the License at: | |
8 | # | |
9 | # http://www.apache.org/licenses/LICENSE-2.0 | |
10 | # | |
11 | # Unless required by applicable law or agreed to in writing, software | |
12 | # distributed under the License is distributed on an "AS IS" BASIS, | |
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | # See the License for the specific language governing permissions and | |
15 | # limitations under the License. | |
16 | ||
064af421 BP |
17 | set -e |
18 | ||
19 | pkidir='@PKIDIR@' | |
20 | command= | |
21 | prev= | |
22 | force=no | |
23 | batch=no | |
24 | log='@LOGDIR@/ovs-pki.log' | |
25 | keytype=rsa | |
26 | bits=2048 | |
27 | for option; do | |
28 | # This option-parsing mechanism borrowed from a Autoconf-generated | |
29 | # configure script under the following license: | |
30 | ||
31 | # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, | |
32 | # 2002, 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. | |
33 | # This configure script is free software; the Free Software Foundation | |
34 | # gives unlimited permission to copy, distribute and modify it. | |
35 | ||
36 | # If the previous option needs an argument, assign it. | |
37 | if test -n "$prev"; then | |
38 | eval $prev=\$option | |
39 | prev= | |
40 | continue | |
41 | fi | |
42 | case $option in | |
43 | *=*) optarg=`expr "X$option" : '[^=]*=\(.*\)'` ;; | |
44 | *) optarg=yes ;; | |
45 | esac | |
46 | ||
47 | case $dashdash$option in | |
48 | --) | |
49 | dashdash=yes ;; | |
50 | -h|--help) | |
51 | cat <<EOF | |
52 | ovs-pki, for managing a simple OpenFlow public key infrastructure | |
53 | usage: $0 [OPTION...] COMMAND [ARG...] | |
54 | ||
55 | The valid stand-alone commands and their arguments are: | |
56 | init Initialize the PKI | |
57 | req NAME Create new private key and certificate request | |
58 | named NAME-privkey.pem and NAME-req.pem, resp. | |
59 | sign NAME [TYPE] Sign switch certificate request NAME-req.pem, | |
60 | producing certificate NAME-cert.pem | |
61 | req+sign NAME [TYPE] Combine the above two steps, producing all three files. | |
62 | verify NAME [TYPE] Checks that NAME-cert.pem is a valid TYPE certificate | |
63 | fingerprint FILE Prints the fingerprint for FILE | |
64 | self-sign NAME Sign NAME-req.pem with NAME-privkey.pem, | |
65 | producing self-signed certificate NAME-cert.pem | |
66 | ||
67 | The following additional commands manage an online PKI: | |
68 | ls [PREFIX] [TYPE] Lists incoming requests of the given TYPE, optionally | |
69 | limited to those whose fingerprint begins with PREFIX | |
70 | flush [TYPE] Rejects all incoming requests of the given TYPE | |
71 | reject PREFIX [TYPE] Rejects the incoming request(s) whose fingerprint begins | |
72 | with PREFIX and has the given TYPE | |
73 | approve PREFIX [TYPE] Approves the incoming request whose fingerprint begins | |
74 | with PREFIX and has the given TYPE | |
75 | expire [AGE] Rejects all incoming requests older than AGE, in | |
76 | one of the forms Ns, Nmin, Nh, Nday (default: 1day) | |
77 | prompt [TYPE] Interactively prompts to accept or reject each incoming | |
78 | request of the given TYPE | |
79 | ||
80 | Each TYPE above is a certificate type: 'switch' (default) or 'controller'. | |
81 | ||
82 | Options for 'init', 'req', and 'req+sign' only: | |
83 | -k, --key=rsa|dsa Type of keys to use (default: rsa) | |
84 | -B, --bits=NBITS Number of bits in keys (default: 2048). For DSA keys, | |
85 | this has an effect only on 'init'. | |
86 | -D, --dsaparam=FILE File with DSA parameters (DSA only) | |
87 | (default: dsaparam.pem within PKI directory) | |
88 | Options for use with the 'sign' and 'approve' commands: | |
89 | -b, --batch Skip fingerprint verification | |
90 | Options that apply to any command: | |
91 | -d, --dir=DIR Directory where the PKI is located | |
92 | (default: $pkidir) | |
93 | -f, --force Continue even if file or directory already exists | |
94 | -l, --log=FILE Log openssl output to FILE (default: ovs-log.log) | |
95 | -h, --help Print this usage message. | |
d3e565ce | 96 | -V, --version Display version information. |
064af421 BP |
97 | EOF |
98 | exit 0 | |
99 | ;; | |
d3e565ce BP |
100 | -V|--version) |
101 | echo "ovs-pki (Open vSwitch) @VERSION@" | |
102 | exit 0 | |
103 | ;; | |
064af421 BP |
104 | --di*=*) |
105 | pkidir=$optarg | |
106 | ;; | |
107 | --di*|-d) | |
108 | prev=pkidir | |
109 | ;; | |
110 | --k*=*) | |
111 | keytype=$optarg | |
112 | ;; | |
113 | --k*|-k) | |
114 | prev=keytype | |
115 | ;; | |
116 | --bi*=*) | |
117 | bits=$optarg | |
118 | ;; | |
119 | --bi*|-B) | |
120 | prev=bits | |
121 | ;; | |
122 | --ds*=*) | |
123 | dsaparam=$optarg | |
124 | ;; | |
125 | --ds*|-D) | |
126 | prev=dsaparam | |
127 | ;; | |
128 | --l*=*) | |
129 | log=$optarg | |
130 | ;; | |
131 | --l*|-l) | |
132 | prev=log | |
133 | ;; | |
134 | --force|-f) | |
135 | force=yes | |
136 | ;; | |
137 | --ba*|-b) | |
138 | batch=yes | |
139 | ;; | |
140 | -*) | |
141 | echo "unrecognized option $option" >&2 | |
142 | exit 1 | |
143 | ;; | |
144 | *) | |
145 | if test -z "$command"; then | |
146 | command=$option | |
147 | elif test -z "${arg1+set}"; then | |
148 | arg1=$option | |
149 | elif test -z "${arg2+set}"; then | |
150 | arg2=$option | |
151 | else | |
152 | echo "$option: only two arguments may be specified" >&2 | |
153 | exit 1 | |
154 | fi | |
155 | ;; | |
156 | esac | |
157 | shift | |
158 | done | |
159 | if test -n "$prev"; then | |
160 | option=--`echo $prev | sed 's/_/-/g'` | |
161 | { echo "$as_me: error: missing argument to $option" >&2 | |
162 | { (exit 1); exit 1; }; } | |
163 | fi | |
164 | if test -z "$command"; then | |
165 | echo "$0: missing command name; use --help for help" >&2 | |
166 | exit 1 | |
167 | fi | |
168 | if test "$keytype" != rsa && test "$keytype" != dsa; then | |
7cdc630f | 169 | echo "$0: argument to -k or --key must be rsa or dsa" >&2 |
064af421 BP |
170 | exit 1 |
171 | fi | |
172 | if test "$bits" -lt 1024; then | |
7cdc630f | 173 | echo "$0: argument to -B or --bits must be at least 1024" >&2 |
064af421 BP |
174 | exit 1 |
175 | fi | |
176 | if test -z "$dsaparam"; then | |
177 | dsaparam=$pkidir/dsaparam.pem | |
178 | fi | |
179 | case $log in | |
180 | /*) ;; | |
37d03458 | 181 | *) log=`pwd`/$log ;; |
064af421 BP |
182 | esac |
183 | ||
ccc9fc5a BP |
184 | logdir=$(dirname "$log") |
185 | if test ! -d "$logdir"; then | |
186 | mkdir -p -m755 "$logdir" 2>/dev/null || true | |
187 | if test ! -d "$logdir"; then | |
188 | echo "$0: log directory $logdir does not exist and cannot be created" >&2 | |
189 | exit 1 | |
190 | fi | |
191 | fi | |
192 | ||
064af421 BP |
193 | if test "$command" = "init"; then |
194 | if test -e "$pkidir" && test "$force" != "yes"; then | |
195 | echo "$0: $pkidir already exists and --force not specified" >&2 | |
196 | exit 1 | |
197 | fi | |
198 | ||
199 | if test ! -d "$pkidir"; then | |
200 | mkdir -p "$pkidir" | |
201 | fi | |
202 | cd "$pkidir" | |
203 | exec 3>>$log | |
204 | ||
205 | if test $keytype = dsa && test ! -e dsaparam.pem; then | |
206 | echo "Generating DSA parameters, please wait..." >&2 | |
207 | openssl dsaparam -out dsaparam.pem $bits 1>&3 2>&3 | |
208 | fi | |
209 | ||
a20d2466 JP |
210 | # Get the current date to add some uniqueness to this certificate |
211 | curr_date=`date +"%Y %b %d %T"` | |
212 | ||
064af421 BP |
213 | # Create the CAs. |
214 | for ca in controllerca switchca; do | |
215 | echo "Creating $ca..." >&2 | |
37d03458 | 216 | oldpwd=`pwd` |
064af421 BP |
217 | mkdir -p $ca |
218 | cd $ca | |
219 | ||
220 | mkdir -p certs crl newcerts | |
221 | mkdir -p -m 0700 private | |
222 | mkdir -p -m 0733 incoming | |
223 | touch index.txt | |
224 | test -e crlnumber || echo 01 > crlnumber | |
225 | test -e serial || echo 01 > serial | |
226 | ||
227 | # Put DSA parameters in directory. | |
228 | if test $keytype = dsa && test ! -e dsaparam.pem; then | |
229 | cp ../dsaparam.pem . | |
230 | fi | |
231 | ||
a20d2466 | 232 | # Write CA configuration file. |
064af421 | 233 | if test ! -e ca.cnf; then |
a20d2466 | 234 | sed "s/@ca@/$ca/g;s/@curr_date@/$curr_date/g" > ca.cnf <<'EOF' |
064af421 BP |
235 | [ req ] |
236 | prompt = no | |
237 | distinguished_name = req_distinguished_name | |
238 | ||
239 | [ req_distinguished_name ] | |
240 | C = US | |
241 | ST = CA | |
242 | L = Palo Alto | |
243 | O = Open vSwitch | |
244 | OU = @ca@ | |
a20d2466 | 245 | CN = OVS @ca@ CA Certificate (@curr_date@) |
064af421 BP |
246 | |
247 | [ ca ] | |
248 | default_ca = the_ca | |
249 | ||
250 | [ the_ca ] | |
251 | dir = . # top dir | |
252 | database = $dir/index.txt # index file. | |
253 | new_certs_dir = $dir/newcerts # new certs dir | |
254 | certificate = $dir/cacert.pem # The CA cert | |
255 | serial = $dir/serial # serial no file | |
256 | private_key = $dir/private/cakey.pem# CA private key | |
257 | RANDFILE = $dir/private/.rand # random number file | |
258 | default_days = 365 # how long to certify for | |
259 | default_crl_days= 30 # how long before next CRL | |
260 | default_md = md5 # md to use | |
261 | policy = policy # default policy | |
262 | email_in_dn = no # Don't add the email into cert DN | |
263 | name_opt = ca_default # Subject name display option | |
264 | cert_opt = ca_default # Certificate display option | |
265 | copy_extensions = none # Don't copy extensions from request | |
c6c9e1e3 | 266 | unique_subject = no # Allow certs with duplicate subjects |
064af421 BP |
267 | |
268 | # For the CA policy | |
269 | [ policy ] | |
270 | countryName = optional | |
271 | stateOrProvinceName = optional | |
272 | organizationName = match | |
273 | organizationalUnitName = optional | |
274 | commonName = supplied | |
275 | emailAddress = optional | |
276 | EOF | |
277 | fi | |
278 | ||
279 | # Create certificate authority. | |
280 | if test $keytype = dsa; then | |
281 | newkey=dsa:dsaparam.pem | |
282 | else | |
283 | newkey=rsa:$bits | |
284 | fi | |
285 | openssl req -config ca.cnf -nodes \ | |
286 | -newkey $newkey -keyout private/cakey.pem -out careq.pem \ | |
287 | 1>&3 2>&3 | |
288 | openssl ca -config ca.cnf -create_serial -out cacert.pem \ | |
72aa493e | 289 | -days 2191 -batch -keyfile private/cakey.pem -selfsign \ |
064af421 BP |
290 | -infiles careq.pem 1>&3 2>&3 |
291 | chmod 0700 private/cakey.pem | |
292 | ||
293 | cd "$oldpwd" | |
294 | done | |
295 | exit 0 | |
296 | fi | |
297 | ||
298 | one_arg() { | |
299 | if test -z "$arg1" || test -n "$arg2"; then | |
300 | echo "$0: $command must have exactly one argument; use --help for help" >&2 | |
301 | exit 1 | |
302 | fi | |
303 | } | |
304 | ||
305 | zero_or_one_args() { | |
306 | if test -n "$arg2"; then | |
307 | echo "$0: $command must have zero or one arguments; use --help for help" >&2 | |
308 | exit 1 | |
309 | fi | |
310 | } | |
311 | ||
312 | one_or_two_args() { | |
313 | if test -z "$arg1"; then | |
314 | echo "$0: $command must have one or two arguments; use --help for help" >&2 | |
315 | exit 1 | |
316 | fi | |
317 | } | |
318 | ||
319 | must_not_exist() { | |
320 | if test -e "$1" && test "$force" != "yes"; then | |
321 | echo "$0: $1 already exists and --force not supplied" >&2 | |
322 | exit 1 | |
323 | fi | |
324 | } | |
325 | ||
326 | resolve_prefix() { | |
327 | test -n "$type" || exit 123 # Forgot to call check_type? | |
328 | ||
329 | case $1 in | |
330 | ????*) | |
331 | ;; | |
332 | *) | |
7cdc630f | 333 | echo "Prefix $arg1 is too short (less than 4 hex digits)" >&2 |
064af421 BP |
334 | exit 0 |
335 | ;; | |
336 | esac | |
337 | ||
338 | fingerprint=$(cd "$pkidir/${type}ca/incoming" && echo "$1"*-req.pem | sed 's/-req\.pem$//') | |
339 | case $fingerprint in | |
340 | "${1}*") | |
7cdc630f | 341 | echo "No certificate requests matching $1" >&2 |
064af421 BP |
342 | exit 1 |
343 | ;; | |
344 | *" "*) | |
7cdc630f | 345 | echo "$1 matches more than one certificate request:" >&2 |
064af421 | 346 | echo $fingerprint | sed 's/ /\ |
7cdc630f | 347 | /g' >&2 |
064af421 BP |
348 | exit 1 |
349 | ;; | |
350 | *) | |
351 | # Nothing to do. | |
352 | ;; | |
353 | esac | |
354 | req="$pkidir/${type}ca/incoming/$fingerprint-req.pem" | |
355 | cert="$pkidir/${type}ca/certs/$fingerprint-cert.pem" | |
356 | } | |
357 | ||
358 | make_tmpdir() { | |
359 | TMP=/tmp/ovs-pki.tmp$$ | |
360 | rm -rf $TMP | |
361 | trap "rm -rf $TMP" 0 | |
362 | mkdir -m 0700 $TMP | |
363 | } | |
364 | ||
365 | fingerprint() { | |
bb60fa74 BP |
366 | file=$1 |
367 | name=${1-$2} | |
368 | date=$(date -r $file) | |
00961f7c | 369 | if grep -e '-BEGIN CERTIFICATE-' "$file" > /dev/null; then |
064af421 BP |
370 | fingerprint=$(openssl x509 -noout -in "$file" -fingerprint | |
371 | sed 's/SHA1 Fingerprint=//' | tr -d ':') | |
372 | else | |
373 | fingerprint=$(sha1sum "$file" | awk '{print $1}') | |
374 | fi | |
375 | printf "$name\\t$date\\n" | |
376 | case $file in | |
377 | $fingerprint*) | |
378 | printf "\\t(correct fingerprint in filename)\\n" | |
379 | ;; | |
380 | *) | |
381 | printf "\\tfingerprint $fingerprint\\n" | |
382 | ;; | |
383 | esac | |
384 | } | |
385 | ||
386 | verify_fingerprint() { | |
387 | fingerprint "$@" | |
388 | if test $batch != yes; then | |
389 | echo "Does fingerprint match? (yes/no)" | |
390 | read answer | |
391 | if test "$answer" != yes; then | |
392 | echo "Match failure, aborting" >&2 | |
393 | exit 1 | |
394 | fi | |
395 | fi | |
396 | } | |
397 | ||
398 | check_type() { | |
399 | if test x = x"$1"; then | |
400 | type=switch | |
401 | elif test "$1" = switch || test "$1" = controller; then | |
402 | type=$1 | |
403 | else | |
404 | echo "$0: type argument must be 'switch' or 'controller'" >&2 | |
405 | exit 1 | |
406 | fi | |
407 | } | |
408 | ||
409 | parse_age() { | |
410 | number=$(echo $1 | sed 's/^\([0-9]\+\)\([[:alpha:]]\+\)/\1/') | |
411 | unit=$(echo $1 | sed 's/^\([0-9]\+\)\([[:alpha:]]\+\)/\2/') | |
412 | case $unit in | |
413 | s) | |
414 | factor=1 | |
415 | ;; | |
416 | min) | |
417 | factor=60 | |
418 | ;; | |
419 | h) | |
420 | factor=3600 | |
421 | ;; | |
422 | day) | |
423 | factor=86400 | |
424 | ;; | |
425 | *) | |
426 | echo "$1: age not in the form Ns, Nmin, Nh, Nday (e.g. 1day)" >&2 | |
427 | exit 1 | |
428 | ;; | |
429 | esac | |
430 | echo $(($number * $factor)) | |
431 | } | |
432 | ||
433 | must_exist() { | |
434 | if test ! -e "$1"; then | |
435 | echo "$0: $1 does not exist" >&2 | |
436 | exit 1 | |
437 | fi | |
438 | } | |
439 | ||
440 | pkidir_must_exist() { | |
441 | if test ! -e "$pkidir"; then | |
442 | echo "$0: $pkidir does not exist (need to run 'init' or use '--dir'?)" >&2 | |
443 | exit 1 | |
444 | elif test ! -d "$pkidir"; then | |
445 | echo "$0: $pkidir is not a directory" >&2 | |
446 | exit 1 | |
447 | fi | |
448 | } | |
449 | ||
450 | make_request() { | |
451 | must_not_exist "$arg1-privkey.pem" | |
452 | must_not_exist "$arg1-req.pem" | |
453 | make_tmpdir | |
454 | cat > "$TMP/req.cnf" <<EOF | |
455 | [ req ] | |
456 | prompt = no | |
457 | distinguished_name = req_distinguished_name | |
458 | ||
459 | [ req_distinguished_name ] | |
460 | C = US | |
461 | ST = CA | |
462 | L = Palo Alto | |
463 | O = Open vSwitch | |
464 | OU = Open vSwitch certifier | |
465 | CN = Open vSwitch certificate for $arg1 | |
466 | EOF | |
467 | if test $keytype = rsa; then | |
99e5e05d BP |
468 | (umask 077 && openssl genrsa -out "$1-privkey.pem" $bits) 1>&3 2>&3 \ |
469 | || exit $? | |
064af421 BP |
470 | else |
471 | must_exist "$dsaparam" | |
99e5e05d BP |
472 | (umask 077 && openssl gendsa -out "$1-privkey.pem" "$dsaparam") \ |
473 | 1>&3 2>&3 || exit $? | |
064af421 | 474 | fi |
99e5e05d BP |
475 | openssl req -config "$TMP/req.cnf" -new -text \ |
476 | -key "$1-privkey.pem" -out "$1-req.pem" 1>&3 2>&3 | |
064af421 BP |
477 | } |
478 | ||
479 | sign_request() { | |
480 | must_exist "$1" | |
481 | must_not_exist "$2" | |
482 | pkidir_must_exist | |
483 | ||
484 | (cd "$pkidir/${type}ca" && | |
485 | openssl ca -config ca.cnf -batch -in /dev/stdin) \ | |
486 | < "$1" > "$2.tmp$$" 2>&3 | |
487 | mv "$2.tmp$$" "$2" | |
488 | } | |
489 | ||
490 | glob() { | |
bb60fa74 | 491 | files=$(echo $1) |
064af421 BP |
492 | if test "$files" != "$1"; then |
493 | echo "$files" | |
494 | fi | |
495 | } | |
496 | ||
497 | exec 3>>$log || true | |
498 | if test "$command" = req; then | |
499 | one_arg | |
500 | ||
501 | make_request "$arg1" | |
502 | fingerprint "$arg1-req.pem" | |
503 | elif test "$command" = sign; then | |
504 | one_or_two_args | |
505 | check_type "$arg2" | |
506 | verify_fingerprint "$arg1-req.pem" | |
507 | ||
508 | sign_request "$arg1-req.pem" "$arg2-cert.pem" | |
509 | elif test "$command" = req+sign; then | |
510 | one_or_two_args | |
511 | check_type "$arg2" | |
512 | ||
513 | pkidir_must_exist | |
514 | make_request "$arg1" | |
515 | sign_request "$arg1-req.pem" "$arg1-cert.pem" | |
516 | fingerprint "$arg1-req.pem" | |
517 | elif test "$command" = verify; then | |
518 | one_or_two_args | |
519 | must_exist "$arg1-cert.pem" | |
520 | check_type "$arg2" | |
521 | ||
522 | pkidir_must_exist | |
523 | openssl verify -CAfile "$pkidir/${type}ca/cacert.pem" "$arg1-cert.pem" | |
524 | elif test "$command" = fingerprint; then | |
525 | one_arg | |
526 | ||
527 | fingerprint "$arg1" | |
528 | elif test "$command" = self-sign; then | |
529 | one_arg | |
530 | must_exist "$arg1-req.pem" | |
531 | must_exist "$arg1-privkey.pem" | |
532 | must_not_exist "$arg1-cert.pem" | |
533 | ||
99e5e05d BP |
534 | # Create both the private key and certificate with restricted permissions. |
535 | (umask 077 && \ | |
536 | openssl x509 -in "$arg1-req.pem" -out "$arg1-cert.pem.tmp" \ | |
537 | -signkey "$arg1-privkey.pem" -req -text) 2>&3 || exit $? | |
538 | ||
539 | # Reset the permissions on the certificate to the user's default. | |
540 | cat "$arg1-cert.pem.tmp" > "$arg1-cert.pem" | |
541 | rm -f "$arg1-cert.pem.tmp" | |
064af421 BP |
542 | elif test "$command" = ls; then |
543 | check_type "$arg2" | |
544 | ||
545 | cd "$pkidir/${type}ca/incoming" | |
546 | for file in $(glob "$arg1*-req.pem"); do | |
547 | fingerprint $file | |
548 | done | |
549 | elif test "$command" = flush; then | |
550 | check_type "$arg1" | |
551 | ||
552 | rm -f "$pkidir/${type}ca/incoming/"* | |
553 | elif test "$command" = reject; then | |
554 | one_or_two_args | |
555 | check_type "$arg2" | |
556 | resolve_prefix "$arg1" | |
557 | ||
558 | rm -f "$req" | |
559 | elif test "$command" = approve; then | |
560 | one_or_two_args | |
561 | check_type "$arg2" | |
562 | resolve_prefix "$arg1" | |
563 | ||
564 | make_tmpdir | |
565 | cp "$req" "$TMP/$req" | |
566 | verify_fingerprint "$TMP/$req" | |
567 | sign_request "$TMP/$req" | |
568 | rm -f "$req" "$TMP/$req" | |
569 | elif test "$command" = prompt; then | |
570 | zero_or_one_args | |
571 | check_type "$arg1" | |
572 | ||
573 | make_tmpdir | |
574 | cd "$pkidir/${type}ca/incoming" | |
575 | for req in $(glob "*-req.pem"); do | |
576 | cp "$req" "$TMP/$req" | |
577 | ||
578 | cert=$(echo "$pkidir/${type}ca/certs/$req" | | |
579 | sed 's/-req.pem/-cert.pem/') | |
580 | if test -f $cert; then | |
581 | echo "Request $req already approved--dropping duplicate request" | |
582 | rm -f "$req" "$TMP/$req" | |
583 | continue | |
584 | fi | |
585 | ||
586 | echo | |
587 | echo | |
588 | fingerprint "$TMP/$req" "$req" | |
589 | printf "Disposition for this request (skip/approve/reject)? " | |
590 | read answer | |
591 | case $answer in | |
592 | approve) | |
593 | echo "Approving $req" | |
594 | sign_request "$TMP/$req" "$cert" | |
595 | rm -f "$req" "$TMP/$req" | |
596 | ;; | |
597 | r*) | |
598 | echo "Rejecting $req" | |
599 | rm -f "$req" "$TMP/$req" | |
600 | ;; | |
601 | *) | |
602 | echo "Skipping $req" | |
603 | ;; | |
604 | esac | |
605 | done | |
606 | elif test "$command" = expire; then | |
607 | zero_or_one_args | |
608 | cutoff=$(($(date +%s) - $(parse_age ${arg1-1day}))) | |
609 | for type in switch controller; do | |
610 | cd "$pkidir/${type}ca/incoming" || exit 1 | |
611 | for file in $(glob "*"); do | |
612 | time=$(date -r "$file" +%s) | |
613 | if test "$time" -lt "$cutoff"; then | |
614 | rm -f "$file" | |
615 | fi | |
616 | done | |
617 | done | |
618 | else | |
619 | echo "$0: $command command unknown; use --help for help" >&2 | |
620 | exit 1 | |
621 | fi |