~ubuntu-branches/ubuntu/trusty/nagios-plugins-contrib/trusty-proposed

« back to all changes in this revision

Viewing changes to check_ssl_cert/check_ssl_cert-1.14.4/check_ssl_cert

  • Committer: Package Import Robot
  • Author(s): Bernd Zeimetz, Bernd Zeimetz, Jan Wagner, Evgeni Golov
  • Date: 2013-06-14 20:53:49 UTC
  • Revision ID: package-import@ubuntu.com-20130614205349-34xiy38pm1hzpjoi
Tags: 7.20130614
[ Bernd Zeimetz ]
* [036816ff] Merge pull request #15 from evgeni/master
  check_packages should find security updates on the official security mirror too
* [658a2e93] Add check_checksums nagios plugin.
* [9d5d2056] Updating check_raid.
* [e3ec1293] Updating check_ssl_cert to 1.14.6
* [779543ef] Updating check_hpasm to 4.6.3.2
* [0c838ee9] Updating check_multipath to 0.1.9
* [bec11251] Updating check_whois to 1.13
* [8e0a65d0] Refreshing patches.
* [c0b88cdb] Auto update of debian/copyright
* [59648a17] Fix src link for check_hpasm
* [8c242d0f] Support pre-Wheezy versions of coretutils in check_checksums.
* [7d3d2a06] Update release date in changelog (gah!).
* [768e463b] Merge pull request #16 from evgeni/master
  check_libs: ignore /var/lib/postgresql/ and /var/log/
* [2b9aace5] Bumping standards-Verison, no changes needed.

[ Jan Wagner ]
* [3bb873e4] disable epn for check_rbl

[ Evgeni Golov ]
* [2a7ab4b8] check_libs: ignore /var/spool/

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/bin/sh
2
 
#
3
 
# check_ssl_cert
4
 
#
5
 
# Checks an X.509 certificate:
6
 
# - checks if the server is running and delivers a valid certificate
7
 
# - checks if the CA matches a given pattern
8
 
# - checks the validity
9
 
#
10
 
# See  the INSTALL file for installation instructions
11
 
#
12
 
# Copyright (c) 2007-2012 ETH Zurich.
13
 
#
14
 
# This module is free software; you can redistribute it and/or modify it
15
 
# under the terms of GNU general public license (gpl) version 3.
16
 
# See the LICENSE file for details.
17
 
#
18
 
# RCS information
19
 
# enable substitution with:
20
 
#   $ svn propset svn:keywords "Id Revision HeadURL Source Date"
21
 
#
22
 
#   $Id: check_ssl_cert 1321 2012-12-07 07:24:19Z corti $
23
 
#   $Revision: 1321 $
24
 
#   $HeadURL: https://svn.id.ethz.ch/nagios_plugins/check_ssl_cert/check_ssl_cert $
25
 
#   $Date: 2012-12-07 08:24:19 +0100 (Fri, 07 Dec 2012) $
26
 
 
27
 
################################################################################
28
 
# Constants
29
 
 
30
 
VERSION=1.14.4
31
 
SHORTNAME="SSL_CERT"
32
 
 
33
 
VALID_ATTRIBUTES=",startdate,enddate,subject,issuer,modulus,serial,hash,email,ocsp_uri,fingerprint,"
34
 
 
35
 
################################################################################
36
 
# Functions
37
 
 
38
 
################################################################################
39
 
# Prints usage information
40
 
# Params
41
 
#   $1 error message (optional)
42
 
usage() {
43
 
 
44
 
    if [ -n "$1" ] ; then
45
 
        echo "Error: $1" 1>&2
46
 
    fi
47
 
 
48
 
    #### The following line is 80 characters long (helps to fit the help text in a standard terminal)
49
 
    ######--------------------------------------------------------------------------------
50
 
        
51
 
    echo
52
 
    echo "Usage: check_ssl_cert -H host [OPTIONS]"
53
 
    echo
54
 
    echo "Arguments:"
55
 
    echo "   -H,--host host         server"
56
 
    echo
57
 
    echo "Options:"
58
 
    echo "   -A,--noauth            ignore authority warnings (expiration only)"
59
 
    echo "      --altnames          matches the pattern specified in -n with alternate"
60
 
    echo "                          names too"
61
 
    echo "   -C,--clientcert path   use client certificate to authenticate"
62
 
    echo "      --clientpass phrase set passphrase for client certificate."
63
 
    echo "   -c,--critical days     minimum number of days a certificate has to be valid"
64
 
    echo "                          to issue a critical status"
65
 
    echo "   -e,--email address     pattern to match the email address contained in the"
66
 
    echo "                          certificate"
67
 
    echo "   -f,--file file         local file path (works with -H localhost only)"
68
 
    echo "   -h,--help,-?           this help message"
69
 
    echo "      --long-output list  append the specified comma separated (no spaces) list"
70
 
    echo "                          of attributes to the plugin output on additional lines."
71
 
    echo "                          Valid attributes are:"
72
 
    echo "                            enddate, startdate, subject, issuer, modulus, serial,"
73
 
    echo "                            hash, email, ocsp_uri and fingerprint."
74
 
    echo "                          'all' will include all the available attributes."
75
 
    echo "   -i,--issuer issuer     pattern to match the issuer of the certificate"
76
 
    echo "   -n,--cn name           pattern to match the CN of the certificate"
77
 
    echo "   -N,--host-cn           match CN with the host name"
78
 
    echo "   -o,--org org           pattern to match the organization of the certificate"
79
 
    echo "      --openssl path      path of the openssl binary to be used"
80
 
    echo "   -p,--port port         TCP port"
81
 
    echo "   -P,--protocol protocol use the specific protocol {http|smtp|pop3|imap|ftp}"
82
 
    echo "                          http:               default"
83
 
    echo "                          smtp,pop3,imap,ftp: switch to TLS"
84
 
    echo "   -s,--selfsigned        allows self-signed certificates"
85
 
    echo "   -r,--rootcert path     root certificate or directory to be used for"
86
 
    echo "                          certficate validation"
87
 
    echo "   -t,--timeout           seconds timeout after the specified time"
88
 
    echo "                          (defaults to 15 seconds)"
89
 
    echo "      --temp dir          directory where to store the temporary files"
90
 
    echo "   -v,--verbose           verbose output"
91
 
    echo "   -V,--version           version"
92
 
    echo "   -w,--warning days      minimum number of days a certificate has to be valid"
93
 
    echo "                          to issue a warning status"
94
 
    echo
95
 
    echo "Deprecated options:"
96
 
    echo "   -d,--days days         minimum number of days a certificate has to be valid"
97
 
    echo "                          (see --critical and --warning)"
98
 
    echo
99
 
    echo "Report bugs to: Matteo Corti <matteo.corti@id.ethz.ch>"
100
 
    echo
101
 
 
102
 
    exit 3
103
 
 
104
 
}
105
 
 
106
 
################################################################################
107
 
# Exits with a critical message
108
 
# Params
109
 
#   $1 error message
110
 
critical() {
111
 
    if [ -n "${CN}" ] ; then
112
 
        tmp=" ${CN}"
113
 
    fi
114
 
    printf "${SHORTNAME} CRITICAL$tmp: $1${PERFORMANCE_DATA}${LONG_OUTPUT}\n"
115
 
    exit 2
116
 
}
117
 
 
118
 
################################################################################
119
 
# Exits with a warning message
120
 
# Param
121
 
#   $1 warning message
122
 
warning() {
123
 
    if [ -n "${CN}" ] ; then
124
 
        tmp=" ${CN}"
125
 
    fi
126
 
    printf "${SHORTNAME} WARN$tmp: $1${PERFORMANCE_DATA}${LONG_OUTPUT}\n"
127
 
    exit 1
128
 
}
129
 
 
130
 
################################################################################
131
 
# Exits with an 'unkown' status
132
 
# Param
133
 
#   $1 message
134
 
unknown() {
135
 
    if [ -n "${CN}" ] ; then
136
 
        tmp=" ${CN}"
137
 
    fi
138
 
    printf "${SHORTNAME} UNKNOWN$tmp: $1\n"
139
 
    exit 3
140
 
}
141
 
 
142
 
################################################################################
143
 
# Executes command with a timeout
144
 
# Params:
145
 
#   $1 timeout in seconds
146
 
#   $2 command
147
 
# Returns 1 if timed out 0 otherwise
148
 
timeout() {
149
 
 
150
 
    time=$1
151
 
 
152
 
    # start the command in a subshell to avoid problem with pipes
153
 
    # (spawn accepts one command)
154
 
    command="/bin/sh -c \"$2\""
155
 
 
156
 
    if [ -n "${EXPECT}" ] ; then
157
 
        expect -c "set echo \"-noecho\"; set timeout $time; spawn -noecho $command; expect timeout { exit 1 } eof { exit 0 }"    
158
 
 
159
 
        if [ $? = 1 ] ; then
160
 
            critical "Timeout after ${time} seconds"
161
 
        fi
162
 
 
163
 
    else
164
 
        eval ${command}
165
 
    fi
166
 
            
167
 
}
168
 
 
169
 
################################################################################
170
 
# Checks if a given program is available and executable
171
 
# Params
172
 
#   $1 program name
173
 
# Returns 1 if the program exists and is executable
174
 
check_required_prog() {
175
 
 
176
 
    PROG=$(which $1 2> /dev/null)
177
 
 
178
 
    if [ -z "$PROG" ] ; then
179
 
        critical "cannot find $1"
180
 
    fi
181
 
 
182
 
    if [ ! -x "$PROG" ] ; then
183
 
        critical "$PROG is not executable"
184
 
    fi
185
 
 
186
 
}
187
 
 
188
 
################################################################################
189
 
# Tries to fetch the certificate
190
 
 
191
 
fetch_certificate() {
192
 
 
193
 
    # check if a protocol was specified (if not HTTP switch to TLS)
194
 
    if [ -n "${PROTOCOL}" -a "${PROTOCOL}" != "http" -a "${PROTOCOL}" != "https" ] ; then
195
 
        
196
 
        case "${PROTOCOL}" in
197
 
            
198
 
            smtp|pop3|imap|ftp)
199
 
 
200
 
timeout $TIMEOUT "echo 'Q' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -starttls ${PROTOCOL} -connect $HOST:$PORT ${SERVERNAME} -verify 6 ${ROOT_CA} 2> ${ERROR} 1> ${CERT}"
201
 
;;
202
 
 
203
 
*)
204
 
 
205
 
unknown "Error: unsupported protocol ${PROTOCOL}"
206
 
 
207
 
esac
208
 
 
209
 
elif [ -n "${FILE}" ] ; then
210
 
 
211
 
if [ "${HOST}" = "localhost" ] ; then
212
 
    
213
 
    timeout $TIMEOUT "/bin/cat '${FILE}' 2> ${ERROR} 1> ${CERT}"
214
 
    
215
 
else
216
 
    
217
 
    unknown "Error: option 'file' works with -H localhost only"
218
 
    
219
 
fi
220
 
 
221
 
else
222
 
 
223
 
timeout $TIMEOUT "echo 'Q' | $OPENSSL s_client ${CLIENT} ${CLIENTPASS} -connect $HOST:$PORT ${SERVERNAME} -verify 6 ${ROOT_CA} 2> ${ERROR} 1> ${CERT}"
224
 
 
225
 
fi
226
 
 
227
 
if [ $? -ne 0 ] ; then
228
 
    critical "Error: $(head -n 1 ${ERROR})"
229
 
fi
230
 
 
231
 
 
232
 
}
233
 
 
234
 
 
235
 
main() {
236
 
    
237
 
    ################################################################################
238
 
    # Main
239
 
    ################################################################################
240
 
 
241
 
    # default values
242
 
    PORT=443
243
 
    TIMEOUT=15
244
 
    VERBOSE=""
245
 
    OPENSSL=""
246
 
 
247
 
    # set the default temp dir if not set
248
 
    if [ -z "${TMPDIR}" ] ; then
249
 
        TMPDIR="/tmp"
250
 
    fi
251
 
 
252
 
    ################################################################################
253
 
    # process command line options
254
 
    #
255
 
    #   we do no use getopts since it is unable to process long options
256
 
 
257
 
    while true; do
258
 
 
259
 
        case "$1" in
260
 
 
261
 
            ########################################
262
 
            # options without arguments
263
 
 
264
 
            -A|--noauth)     NOAUTH=1;               shift  ;;
265
 
 
266
 
            --altnames)      ALTNAMES=1;             shift  ;;
267
 
 
268
 
            -h|--help|-\?)   usage;                  exit 0 ;;
269
 
 
270
 
            -N|--host-cn)    COMMON_NAME="__HOST__"; shift  ;;
271
 
 
272
 
            -s|--selfsigned) SELFSIGNED=1;           shift  ;;
273
 
                
274
 
            -v|--verbose)    VERBOSE=1;              shift  ;;
275
 
        
276
 
            -V|--version)    echo "check_ssl_cert version ${VERSION}"; exit 3; ;;
277
 
 
278
 
            ########################################
279
 
            # options with arguments
280
 
        
281
 
            -c|--critical) if [ $# -gt 1 ]; then
282
 
                    CRITICAL=$2; shift 2             
283
 
                else 
284
 
                    unknown "-c,--critical requires an argument"
285
 
                fi ;;
286
 
 
287
 
            # deprecated option: used to be as --warning
288
 
            -d|--days) if [ $# -gt 1 ]; then
289
 
                    WARNING=$2; shift 2             
290
 
                else 
291
 
                    unknown "-d,--days requires an argument"
292
 
                fi ;;
293
 
 
294
 
            -e|--email) if [ $# -gt 1 ]; then
295
 
                ADDR=$2; shift 2             
296
 
            else 
297
 
              unknown "-e,--email requires an argument"
298
 
            fi ;;
299
 
 
300
 
            -f|--file) if [ $# -gt 1 ]; then
301
 
                FILE=$2; shift 2
302
 
            else 
303
 
                unknown "-f,--file requires an argument"
304
 
            fi ;;
305
 
            
306
 
            -H|--host) if [ $# -gt 1 ]; then
307
 
                HOST=$2; shift 2
308
 
            else 
309
 
                unknown "-H,--host requires an argument"
310
 
            fi ;;
311
 
 
312
 
            -i|--issuer) if [ $# -gt 1 ]; then
313
 
                ISSUER=$2; shift 2
314
 
            else 
315
 
                unknown "-i,--issuer requires an argument"
316
 
            fi ;;
317
 
 
318
 
            --long-output) if [ $# -gt 1 ]; then
319
 
                LONG_OUTPUT_ATTR=$2; shift 2
320
 
            else
321
 
                unknown "--long-output requires an argument"
322
 
            fi ;;
323
 
 
324
 
            -n|--cn) if [ $# -gt 1 ]; then
325
 
                COMMON_NAME=$2; shift 2
326
 
            else 
327
 
                unknown "-n,--cn requires an argument"
328
 
            fi ;;
329
 
 
330
 
            -o|--org) if [ $# -gt 1 ]; then
331
 
                ORGANIZATION=$2; shift 2
332
 
            else 
333
 
                unknown "-o,--org requires an argument"
334
 
            fi ;;
335
 
 
336
 
            --openssl) if [ $# -gt 1 ]; then
337
 
                OPENSSL=$2; shift 2
338
 
            else
339
 
                unknown "--openssl requires an argument"
340
 
            fi ;;
341
 
 
342
 
            -p|--port) if [ $# -gt 1 ]; then
343
 
                PORT=$2; shift 2
344
 
            else 
345
 
                unknown "-p,--port requires an argument"
346
 
            fi ;;
347
 
 
348
 
            -P|--protocol) if [ $# -gt 1 ]; then
349
 
                PROTOCOL=$2; shift 2
350
 
            else 
351
 
                unknown "-P,--protocol requires an argument"
352
 
            fi ;;
353
 
 
354
 
            -r|--rootcert) if [ $# -gt 1 ]; then
355
 
                ROOT_CA=$2; shift 2
356
 
            else 
357
 
                unknown "-r,--rootcert requires an argument"
358
 
            fi ;;
359
 
 
360
 
            -C|--clientcert) if [ $# -gt 1 ]; then
361
 
                CLIENT_CERT=$2; shift 2
362
 
            else
363
 
                unknown "-c,--clientcert requires an argument"
364
 
            fi ;;
365
 
 
366
 
            --clientpass) if [ $# -gt 1 ]; then
367
 
                CLIENT_PASS=$2; shift 2
368
 
            else
369
 
                unknown "--clientpass requires an argument"
370
 
            fi ;;
371
 
 
372
 
            -t|--timeout) if [ $# -gt 1 ]; then
373
 
                TIMEOUT=$2; shift 2
374
 
            else 
375
 
              unknown "-t,--timeout requires an argument"
376
 
            fi ;;
377
 
 
378
 
            --temp) if [ $# -gt 1 ] ; then
379
 
                # override TMPDIR
380
 
                TMPDIR=$2; shift 2
381
 
            else
382
 
               unknown "--temp requires an argument"
383
 
            fi ;;
384
 
 
385
 
            -w|--warning) if [ $# -gt 1 ]; then
386
 
                WARNING=$2; shift 2             
387
 
            else 
388
 
                unknown "-w,--warning requires an argument"
389
 
            fi ;;
390
 
 
391
 
            ########################################
392
 
            # special
393
 
        
394
 
            --) shift; break;;
395
 
            -*) unknown "invalid option: $1" ;;
396
 
            *)  break;;
397
 
        
398
 
        esac
399
 
 
400
 
    done
401
 
 
402
 
    ################################################################################
403
 
    # Set COMMON_NAME to hostname if -N was given as argument
404
 
    if [ "$COMMON_NAME" = "__HOST__" ] ; then
405
 
        COMMON_NAME=${HOST}
406
 
    fi
407
 
 
408
 
    ################################################################################
409
 
    # sanity checks
410
 
 
411
 
    ###############
412
 
    # Check options
413
 
    if [ -z "${HOST}" ] ; then
414
 
        usage "No host specified"
415
 
    fi
416
 
 
417
 
    if [ -n "${ALTNAMES}" -a -z "${COMMON_NAME}" ] ; then
418
 
        unknown "--altnames requires a common name to match (--cn or --host-cn)"
419
 
    fi
420
 
 
421
 
    if [ -n "${ROOT_CA}" ] ; then
422
 
        if [ ! -r ${ROOT_CA} ] ; then
423
 
            unknown "Cannot read root certificate ${ROOT_CA}"
424
 
        fi
425
 
        if [ -d ${ROOT_CA} ] ; then
426
 
            ROOT_CA="-CApath ${ROOT_CA}"
427
 
        elif [ -f ${ROOT_CA} ] ; then
428
 
            ROOT_CA="-CAfile ${ROOT_CA}"
429
 
        else
430
 
            unknown "Root certificate of unknown type $(file ${ROOT_CA} 2> /dev/null)"
431
 
        fi
432
 
    fi
433
 
    
434
 
    if [ -n "${CLIENT_CERT}" ] ; then
435
 
        if [ ! -r ${CLIENT_CERT} ] ; then
436
 
            unknown "Cannot read client certificate ${CLIENT_CERT}"
437
 
        fi
438
 
    fi
439
 
    
440
 
    if [ -n "${CRITICAL}" ] ; then
441
 
        if ! echo "${CRITICAL}" | grep -q '[0-9][0-9]*' ; then
442
 
            unknown "invalid number of days ${CRITICAL}"
443
 
        fi
444
 
    fi
445
 
    
446
 
    if [ -n "${WARNING}" ] ; then
447
 
        if ! echo ${WARNING} | grep -q '[0-9][0-9]*' ; then
448
 
            unknown "invalid number of days ${WARNING}"
449
 
        fi
450
 
    fi
451
 
    
452
 
    if [ -n "${CRITICAL}" -a -n "${WARNING}" ] ; then
453
 
        if [ ${WARNING} -le ${CRITICAL} ] ; then
454
 
            unknown "--warning (${WARNING}) is less than or equal to --critical (${CRITICAL})"
455
 
        fi
456
 
    fi
457
 
    
458
 
    if [ -n "${TMPDIR}" ] ; then
459
 
        if [ ! -d ${TMPDIR} ] ; then
460
 
            unknown "${TMPDIR} is not a directory";
461
 
        fi
462
 
        if [ ! -w ${TMPDIR} ] ; then
463
 
            unknown "${TMPDIR} is not writable";
464
 
        fi
465
 
    fi
466
 
    
467
 
    if [ -n "${OPENSSL}" ] ; then
468
 
        if [ ! -x ${OPENSSL} ] ; then
469
 
            unknown "${OPENSSL} ist not an executable"
470
 
        fi
471
 
        if [ $(basename ${OPENSSL}) != 'openssl' ] ; then
472
 
            unknown "${OPENSSL} ist not an openssl executable"
473
 
        fi
474
 
    fi
475
 
    
476
 
    #######################
477
 
    # Check needed programs
478
 
 
479
 
    # OpenSSL
480
 
    if [ -z "${OPENSSL}" ] ; then
481
 
        check_required_prog openssl
482
 
        OPENSSL=$PROG
483
 
    fi
484
 
 
485
 
    # Expect (optional)
486
 
    EXPECT=$(which expect 2> /dev/null)
487
 
    test -x "${EXPECT}" || EXPECT=""
488
 
    if [ -z "${EXPECT}" -a -n "${VERBOSE}" ] ; then
489
 
        echo "Expect not found: disabling timeouts"
490
 
    fi
491
 
 
492
 
    # Perl with Date::Parse (optional)
493
 
    PERL=$(which perl 2> /dev/null)
494
 
    test -x "${PERL}" || PERL=""
495
 
    if [ -z "${PERL}" -a -n "${VERBOSE}" ] ; then
496
 
        echo "Perl not found: disabling date computations"    
497
 
    fi
498
 
    if ! ${PERL} -e "use Date::Parse;" > /dev/null 2>&1 ; then
499
 
        if [ -n "${VERBOSE}" ] ; then
500
 
            echo "Perl module Date::Parse not installed: disabling date computations"
501
 
        fi
502
 
        PERL=        
503
 
    fi
504
 
    
505
 
    ################################################################################
506
 
    # check if openssl s_client supports the -servername option
507
 
    #
508
 
    #   openssl s_client does not have a -help option
509
 
    #   => we supply an invalid command line option to get the help
510
 
    #      on standard error
511
 
    #
512
 
    SERVERNAME=
513
 
    if ${OPENSSL} s_client not_a_real_option 2>&1 | grep -q -- -servername ; then
514
 
        SERVERNAME="-servername ${HOST}"
515
 
    else
516
 
        if [ -n "${VERBOSE}" ] ; then
517
 
            echo "'${OPENSSL} s_client' does not support '-servername': disabling virtual server support"
518
 
        fi
519
 
    fi
520
 
    
521
 
    ################################################################################
522
 
    # fetch the X.509 certificate
523
 
    
524
 
    # temporary storage for the certificate and the errors
525
 
    
526
 
    CERT=$(  mktemp -t "$( basename $0 )XXXXXX" 2> /dev/null )
527
 
    if [ -z "${CERT}" ] || [ ! -w "${CERT}" ] ; then
528
 
        unknown 'temporary file creation failure.'
529
 
    fi
530
 
    
531
 
    ERROR=$( mktemp -t "$( basename $0 )XXXXXX" 2> /dev/null )
532
 
    if [ -z "${ERROR}" ] || [ ! -w "${ERROR}" ] ; then
533
 
        unknown 'temporary file creation failure.'
534
 
    fi
535
 
    
536
 
    if [ -n "${VERBOSE}" ] ; then
537
 
        echo "downloading certificate to ${TMPDIR}"
538
 
    fi
539
 
    
540
 
    CLIENT=""
541
 
    if [ -n "${CLIENT_CERT}" ] ; then
542
 
        CLIENT="-cert ${CLIENT_CERT}"
543
 
    fi
544
 
    
545
 
    CLIENTPASS=""
546
 
    if [ -n "${CLIENT_PASS}" ] ; then
547
 
        CLIENTPASS="-pass pass:${CLIENT_PASS}"
548
 
    fi
549
 
    
550
 
    # cleanup before program termination
551
 
    # using named signals to be POSIX compliant
552
 
    trap "rm -f $CERT $ERROR" EXIT HUP INT QUIT TERM
553
 
    
554
 
    fetch_certificate
555
 
    
556
 
    if grep -q 'sslv3\ alert\ unexpected\ message' ${ERROR} ; then
557
 
    
558
 
        if [ -n "${SERVERNAME}" ] ; then
559
 
    
560
 
            # some OpenSSL versions have problems with the -servername option
561
 
            # we try without
562
 
            if [ -n "${VERBOSE}" ] ; then
563
 
                echo "'${OPENSSL} s_client' returned an error: trying without '-servername'"
564
 
            fi
565
 
            
566
 
            SERVERNAME=
567
 
            fetch_certificate
568
 
    
569
 
        fi
570
 
    
571
 
        if grep -q 'sslv3\ alert\ unexpected\ message' ${ERROR} ; then
572
 
    
573
 
            critical "cannot fetch certificate: OpenSSL got an unexpected message"
574
 
    
575
 
        fi
576
 
    
577
 
    fi
578
 
    
579
 
    if ! grep -q "CERTIFICATE" ${CERT} ; then
580
 
        if [ -n "${FILE}" ] ; then
581
 
            critical "'${FILE}' is not a valid certificate file"
582
 
        else
583
 
    
584
 
            # See
585
 
            # http://stackoverflow.com/questions/1251999/sed-how-can-i-replace-a-newline-n
586
 
            # 
587
 
            # - create a branch label via :a
588
 
            # - the N command appends a newline and and the next line of the input
589
 
            #   file to the pattern space
590
 
            # - if we are before the last line, branch to the created label $!ba
591
 
            #   ($! means not to do it on the last line (as there should be one final newline))
592
 
            # - finally the substitution replaces every newline with a space on
593
 
            #   the pattern space 
594
 
        
595
 
            ERROR_MESSAGE=$(sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/; /g' ${ERROR})
596
 
            if [ -n "${VERBOSE}" ] ; then
597
 
                echo "Error: ${ERROR_MESSAGE}"
598
 
            fi
599
 
            critical "No certificate returned (${ERROR_MESSAGE})"
600
 
        fi
601
 
    fi
602
 
    
603
 
    ################################################################################
604
 
    # parse the X.509 certificate
605
 
    
606
 
    DATE=$($OPENSSL x509 -in ${CERT} -enddate -noout | sed -e "s/^notAfter=//")
607
 
    CN=$($OPENSSL x509 -in ${CERT} -subject -noout | sed -e "s/^.*\/CN=//" -e "s/\/[A-Za-z][A-Za-z]*=.*$//")
608
 
    
609
 
    CA_O=$($OPENSSL x509 -in ${CERT} -issuer -noout | sed -e "s/^.*\/O=//" -e "s/\/[A-Z][A-Z]*=.*$//")
610
 
    CA_CN=$($OPENSSL x509 -in ${CERT} -issuer -noout  | sed -e "s/^.*\/CN=//" -e "s/\/[A-Za-z][A-Za-z]*=.*$//")
611
 
    
612
 
    
613
 
    ################################################################################
614
 
    # Generate the long output
615
 
    if [ -n "${LONG_OUTPUT_ATTR}" ] ; then
616
 
    
617
 
        check_attr() {
618
 
            ATTR=$1
619
 
            if ! echo "${VALID_ATTRIBUTES}" | grep -q ",${ATTR}," ; then
620
 
                unknown "Invalid certificate attribute: ${ATTR}"
621
 
            else       
622
 
                value=$(${OPENSSL} x509 -in ${CERT} -noout -${ATTR} | sed -e "s/.*=//")
623
 
                LONG_OUTPUT="${LONG_OUTPUT}\n${ATTR}: ${value}"
624
 
           fi
625
 
           
626
 
        }
627
 
        
628
 
        # split on comma
629
 
        if [ "${LONG_OUTPUT_ATTR}" = "all" ] ; then
630
 
            LONG_OUTPUT_ATTR=${VALID_ATTRIBUTES}
631
 
        fi
632
 
        attributes=$( echo ${LONG_OUTPUT_ATTR} | tr ',' "\n" )
633
 
        for attribute in $attributes ; do
634
 
            check_attr ${attribute}
635
 
        done
636
 
    
637
 
    fi
638
 
    
639
 
    ################################################################################
640
 
    # compute for how many days the certificate will be valid
641
 
    
642
 
    if [ -n "${PERL}" ] ; then
643
 
    
644
 
        CERT_END_DATE=$($OPENSSL x509 -in ${CERT} -noout -enddate | sed -e "s/.*=//")
645
 
    
646
 
        DAYS_VALID=$( perl - "${CERT_END_DATE}" <<-"EOF"
647
 
        
648
 
use strict;
649
 
use warnings;
650
 
    
651
 
use Date::Parse;
652
 
    
653
 
my $cert_date = str2time( $ARGV[0] );
654
 
    
655
 
my $days = int (( $cert_date - time ) / 86400 + 0.5);
656
 
    
657
 
print "$days\n";
658
 
        
659
 
EOF
660
 
 
661
 
        )
662
 
    
663
 
        if [ -n "${VERBOSE}" ] ; then
664
 
            if [ ${DAYS_VALID} -ge 0 ] ; then
665
 
                echo "The certificate will expire in ${DAYS_VALID} day(s)"
666
 
            else
667
 
                echo "The certificate expired "$((- DAYS_VALID))" day(s) ago"
668
 
            fi
669
 
            
670
 
        fi
671
 
        
672
 
        PERFORMANCE_DATA="|days=$DAYS_VALID;${WARNING};${CRITICAL};;"
673
 
    
674
 
    fi
675
 
    
676
 
    
677
 
    
678
 
    ################################################################################
679
 
    # check the CN (this will not work as expected with wildcard certificates)
680
 
    
681
 
    if [ -n "$COMMON_NAME" ] ; then
682
 
    
683
 
        ok=''
684
 
    
685
 
        case $COMMON_NAME in
686
 
            $CN) ok='true' ;;
687
 
        esac
688
 
    
689
 
        # check alterante names
690
 
        if [ -n "${ALTNAMES}" ] ; then
691
 
            for alt_name in $( $OPENSSL x509 -in ${CERT} -text | \
692
 
                grep --after-context=1 '509v3 Subject Alternative Name:' | \
693
 
                tail -n 1 | sed -e "s/DNS://g" | sed -e "s/,//g" ) ; do
694
 
                case $COMMON_NAME in
695
 
                    $alt_name) ok='true' ;;
696
 
                esac
697
 
            done
698
 
        fi
699
 
    
700
 
        if [ -z "$ok" ] ; then
701
 
            critical "invalid CN ('$CN' does not match '$COMMON_NAME')"
702
 
        fi
703
 
        
704
 
    fi
705
 
    
706
 
    ################################################################################
707
 
    # check the issuer
708
 
    
709
 
    if [ -n "$ISSUER" ] ; then
710
 
    
711
 
        ok=''
712
 
        CA_ISSUER_MATCHED=''
713
 
    
714
 
        if echo $CA_CN | grep -q "^$ISSUER$" ; then
715
 
            ok='true'
716
 
            CA_ISSUER_MATCHED="${CA_CN}"
717
 
        fi
718
 
    
719
 
        if echo $CA_O | grep -q "^$ISSUER$" ; then
720
 
            ok='true'
721
 
            CA_ISSUER_MATCHED="${CA_O}"
722
 
        fi
723
 
    
724
 
        if [ -z "$ok" ] ; then
725
 
            critical "invalid CA ('$ISSUER' does not match '$CA_O' or '$CA_CN')"
726
 
        fi
727
 
        
728
 
    else
729
 
    
730
 
        CA_ISSUER_MATCHED="${CA_CN}"
731
 
    
732
 
    fi
733
 
    
734
 
    ################################################################################
735
 
    # check the validity
736
 
    
737
 
    # we always check expired certificates
738
 
    if ! $OPENSSL x509 -in ${CERT} -noout -checkend 0 ; then
739
 
        critical "certificate is expired (was valid until $DATE)"
740
 
    fi
741
 
    
742
 
    if [ -n "${CRITICAL}" ] ; then
743
 
    
744
 
        if ! $OPENSSL x509 -in ${CERT} -noout -checkend $(( ${CRITICAL} * 86400 )) ; then
745
 
            critical "certificate will expire on $DATE"
746
 
        fi
747
 
    
748
 
    fi
749
 
    
750
 
    if [ -n "${WARNING}" ] ; then
751
 
    
752
 
        if ! $OPENSSL x509 -in ${CERT} -noout -checkend $(( ${WARNING} * 86400 )) ; then
753
 
            warning "certificate will expire on $DATE"
754
 
        fi
755
 
    
756
 
    fi
757
 
    
758
 
    ################################################################################
759
 
    # check the organization
760
 
    
761
 
    if [ -n "$ORGANIZATION" ] ; then
762
 
    
763
 
        ORG=$($OPENSSL x509 -in ${CERT} -subject -noout | sed -e "s/.*\/O=//" -e "s/\/.*//")
764
 
    
765
 
        if ! echo $ORG | grep -q "^$ORGANIZATION" ; then
766
 
            critical "invalid organization ('$ORGANIZATION' does not match '$ORG')"
767
 
        fi
768
 
    
769
 
    fi
770
 
    
771
 
    ################################################################################
772
 
    # check the organization
773
 
    
774
 
    if [ -n "$ADDR" ] ; then
775
 
    
776
 
        EMAIL=$($OPENSSL x509 -in ${CERT} -email -noout)
777
 
    
778
 
        if [ -n "${VERBOSE}" ] ; then
779
 
            echo "checking email (${ADDR}): ${EMAIL}"
780
 
        fi
781
 
    
782
 
        if [ -z "${EMAIL}" ] ; then
783
 
            critical "the certficate does not contain an email address"
784
 
        fi
785
 
    
786
 
        if ! echo $EMAIL | grep -q "^$ADDR" ; then
787
 
            critical "invalid email ($ADDR does not match $EMAIL)"
788
 
        fi
789
 
    
790
 
    fi
791
 
    
792
 
    ################################################################################
793
 
    # Check if the certificate was verified
794
 
    
795
 
    if [ -z "${NOAUTH}" ] && grep -q '^verify\ error:' ${ERROR} ; then
796
 
    
797
 
        if grep -q '^verify\ error:num=[0-9][0-9]*:self\ signed\ certificate' ${ERROR} ; then
798
 
    
799
 
            if [ -z "${SELFSIGNED}" ] ; then
800
 
                critical "Cannot verify certificate\nself signed certificate"
801
 
            else
802
 
                SELFSIGNEDCERT="self signed "
803
 
            fi
804
 
    
805
 
        else 
806
 
    
807
 
            # process errors
808
 
            details=$(grep  '^verify\ error:' ${ERROR} | sed -e "s/verify\ error:num=[0-9]*:/verification error: /" )
809
 
    
810
 
            critical "Cannot verify certificate\n${details}"
811
 
    
812
 
        fi
813
 
        
814
 
    fi
815
 
    
816
 
    ################################################################################
817
 
    # If we get this far, assume all is well. :)
818
 
    
819
 
    # if --altnames was specified we show the specified CN instead of
820
 
    # the certificate CN
821
 
    if [ -n "${ALTNAMES}" -a -n "${COMMON_NAME}" ] ; then
822
 
        CN=${COMMON_NAME}
823
 
    fi
824
 
    
825
 
    if [ -n "${DAYS_VALID}" ] ; then
826
 
        # nicer formatting
827
 
        if [ ${DAYS_VALID} -gt 1 ] ; then
828
 
            DAYS_VALID=" (expires in ${DAYS_VALID} days)"
829
 
        elif [ ${DAYS_VALID} -eq 1 ] ; then
830
 
            DAYS_VALID=" (expires tomorrow)"
831
 
        elif [ ${DAYS_VALID} -eq 0 ] ; then
832
 
            DAYS_VALID=" (expires today)"
833
 
        elif [ ${DAYS_VALID} -eq -1 ] ; then
834
 
            DAYS_VALID=" (expired yesterday)"
835
 
        else
836
 
            DAYS_VALID=" (expired ${DAYS_VALID} days ago)"
837
 
        fi
838
 
    fi
839
 
    
840
 
    echo "${SHORTNAME} OK - X.509 ${SELFSIGNEDCERT}certificate for '${CN}' from '${CA_ISSUER_MATCHED}' valid until ${DATE}${DAYS_VALID}${PERFORMANCE_DATA}${LONG_OUTPUT}"
841
 
    
842
 
    exit 0
843
 
    
844
 
}
845
 
    
846
 
if [ "${1}" != "--source-only" ]; then
847
 
    main "${@}"
848
 
fi