13 |
11 |
14 sub print_help(); |
12 sub print_help(); |
15 sub print_usage(); |
13 sub print_usage(); |
16 |
14 |
17 my $ME = basename $0; |
15 my $ME = basename $0; |
18 my ($opt_w, $opt_c, $opt_V, $opt_h, $opt_b, $opt_s, @opt_certfiles); |
16 my ( $opt_w, $opt_c, $opt_V, $opt_h, $opt_b, $opt_s, @opt_certfiles ); |
19 my ($w_time, $c_time, $result, $message, %certs); |
17 my ( $w_time, $c_time, $result, $message, %certs ); |
20 my (@critical, @warning); |
18 my ( @critical, @warning, @ok ); |
21 |
19 |
22 $opt_w = "1month"; |
20 $opt_w = "1month"; |
23 $opt_c = "1week"; |
21 $opt_c = "1week"; |
24 $opt_b = "/usr/bin/openssl"; |
22 $opt_b = "/usr/bin/openssl"; |
25 $opt_s = "md5WithRSAEncryption"; |
23 $opt_s = "md5WithRSAEncryption"; |
26 |
24 |
27 Getopt::Long::Configure('bundling'); |
25 Getopt::Long::Configure('bundling'); |
28 GetOptions( |
26 GetOptions( |
29 "V" => \$opt_V, "version" => \$opt_V, |
27 "V" => \$opt_V, |
30 "h" => \$opt_h, "help" => \$opt_h, |
28 "version" => \$opt_V, |
31 "b=s" => \$opt_b, "binary" => \$opt_b, |
29 "h" => \$opt_h, |
32 "w=s" => \$opt_w, "warning=s" => \$opt_w, |
30 "help" => \$opt_h, |
33 "c=s" => \$opt_c, "critical=s" => \$opt_c, |
31 "b=s" => \$opt_b, |
34 "s=s" => \$opt_s, "signature=s" => \$opt_s, |
32 "binary" => \$opt_b, |
35 "f=s" => \@opt_certfiles, "certfile=s" => \@opt_certfiles); |
33 "w=s" => \$opt_w, |
|
34 "warning=s" => \$opt_w, |
|
35 "c=s" => \$opt_c, |
|
36 "critical=s" => \$opt_c, |
|
37 "s=s" => \$opt_s, |
|
38 "signature=s" => \$opt_s, |
|
39 "f=s" => \@opt_certfiles, |
|
40 "certfile=s" => \@opt_certfiles |
|
41 ); |
36 |
42 |
37 if ($opt_V) { |
43 if ($opt_V) { |
38 print_revision($ME, "0.3"); |
44 print_revision( $ME, "1.2" ); |
39 exit $ERRORS{"OK"}; |
45 exit $ERRORS{"OK"}; |
40 } |
46 } |
41 |
47 |
42 if ($opt_h) { |
48 if ($opt_h) { |
43 print_help(); |
49 print_help(); |
44 exit $ERRORS{"OK"}; |
50 exit $ERRORS{"OK"}; |
45 } |
51 } |
46 |
52 |
47 # check openssl binary |
53 # check openssl binary |
48 unless (-x $opt_b) { |
54 unless ( -x $opt_b ) { |
49 print "CERT CRITICAL: OpenSSL not found or not executable - $opt_b\n"; |
55 print "CERT CRITICAL: OpenSSL not found or not executable - $opt_b\n"; |
50 exit $ERRORS{"CRITICAL"}; |
56 exit $ERRORS{"CRITICAL"}; |
51 } |
57 } |
52 |
58 |
53 unless(@opt_certfiles) { |
59 unless (@opt_certfiles) { |
54 print "CERT WARNING: Not defined any certificate files\n"; |
60 print "CERT WARNING: Not defined any certificate files\n"; |
55 exit $ERRORS{"WARNING"}; |
61 exit $ERRORS{"WARNING"}; |
56 } |
62 } |
57 |
63 |
58 @opt_certfiles = split(/,/, join(',', @opt_certfiles)); |
64 @opt_certfiles = split( /,/, join( ',', @opt_certfiles ) ); |
59 |
65 |
60 # extract certificate data |
66 # extract certificate data |
61 foreach my $file (@opt_certfiles) { |
67 foreach my $file (@opt_certfiles) { |
62 unless (-r $file) { |
68 unless ( -r $file ) { |
63 print "CERT CRITICAL: $file - not exists or not read permission is granted\n"; |
69 print |
64 exit $ERRORS{"CRITICAL"}; |
70 "CERT CRITICAL: $file - not exists or not read permission is granted\n"; |
65 } |
71 exit $ERRORS{"CRITICAL"}; |
66 my $no_print = "no_header,no_version,no_serial,no_validity,no_subject,no_issuer,no_pubkey,no_sigdump,no_extensions"; |
72 } |
67 my @cmd_x509 = ($opt_b, "x509", "-in", $file, "-noout", "-text", "-certopt", $no_print, "-subject", "-enddate"); |
73 my $no_print = |
68 my @cmd_pkcs12 = ($opt_b, "pkcs12", "-in", $file, "-clcerts", "-nokeys", "-nomacver", "-passin", "pass:"); |
74 "no_header,no_version,no_serial,no_validity,no_subject,no_issuer,no_pubkey,no_sigdump,no_extensions"; |
69 my @cmd_pipe = ($opt_b, "x509", "-noout", "-text", "-certopt", $no_print, "-subject", "-enddate"); |
75 my @cmd_x509 = ( |
70 my ($temp, $sig, $cn, $enddate, $rc); |
76 $opt_b, "x509", "-in", $file, |
71 open(CERT, "-|") or do { |
77 "-noout", "-text", "-certopt", $no_print, |
72 open(STDERR, ">&STDOUT"); |
78 "-subject", "-enddate", "-purpose" |
73 exec(@cmd_x509); |
79 ); |
|
80 my @cmd_pkcs12 = ( |
|
81 $opt_b, "pkcs12", "-in", $file, |
|
82 "-clcerts", "-nokeys", "-nomacver", "-passin", |
|
83 "pass:" |
|
84 ); |
|
85 my @cmd_pipe = ( |
|
86 $opt_b, "x509", "-noout", "-text", |
|
87 "-certopt", $no_print, "-subject", "-enddate", |
|
88 "-purpose" |
|
89 ); |
|
90 my ( $temp, $sig, $cn, $enddate, $rc, $cert_type ); |
|
91 open( CERT, "-|" ) or do { |
|
92 open( STDERR, ">&STDOUT" ); |
|
93 exec(@cmd_x509); |
74 }; |
94 }; |
75 |
95 |
76 # check x509 certificates |
96 # check x509 certificates |
77 while(<CERT>) { |
97 while (<CERT>) { |
78 /unable to load certificate/ and $rc = 1 and last; |
98 /unable to load certificate/ and $rc = 1 and last; |
79 /Signature\sAlgorithm:\s($opt_s)\s+$/ and $sig = $1; |
99 /Signature\sAlgorithm:\s($opt_s)\s+$/ and $sig = $1; |
80 /^subject=\s.*CN=(.*)\s+$/ and $cn = $1; |
100 /^subject=\s.*CN=(.*)\s+$/ and $cn = $1; |
81 /^notAfter=(.*)\s+$/ and $enddate = $1; |
101 /^notAfter=(.*)\s+$/ and $enddate = $1; |
|
102 /^(SSL\sclient)\s:\sYes$/ and $cert_type = $1; |
|
103 /^(SSL\sserver)\s:\sYes$/ and $cert_type = $1; |
82 } |
104 } |
83 close(CERT); |
105 close(CERT); |
84 |
106 |
85 # check pkcs12 certificates |
107 # check pkcs12 certificates |
86 if ($rc) { |
108 if ($rc) { |
87 open(PKCS12, "@cmd_pkcs12 |"); |
109 open( PKCS12, "@cmd_pkcs12 |" ); |
88 |
110 |
89 while(<PKCS12>) { |
111 while (<PKCS12>) { |
90 $temp .= $_; |
112 $temp .= $_; |
91 } |
113 } |
92 close(PKCS12); |
114 close(PKCS12); |
93 |
115 |
94 local (*READ, *WRITE); |
116 local ( *READ, *WRITE ); |
95 open2(\*READ, \*WRITE, @cmd_pipe) or die "Can't fork: $!\n"; |
117 open2( \*READ, \*WRITE, @cmd_pipe ) or die "Can't fork: $!\n"; |
96 print WRITE $temp; |
118 print WRITE $temp; |
97 close(WRITE); |
119 close(WRITE); |
98 |
120 |
99 while(<READ>) { |
121 while (<READ>) { |
100 /unable to load certificate/ and print "CERT CRITICAL: unable to load certificate\n" and exit $ERRORS{"CRITICAL"}; |
122 /unable to load certificate/ |
101 /Signature\sAlgorithm:\s($opt_s)\s+$/ and $sig = $1; |
123 and print "CERT CRITICAL: unable to load certificate\n" |
102 /^subject=\s.*CN=(.*)\s+$/ and $cn = $1; |
124 and exit $ERRORS{"CRITICAL"}; |
103 /^notAfter=(.*)\s+$/ and $enddate = $1; |
125 /Signature\sAlgorithm:\s($opt_s)\s+$/ and $sig = $1; |
104 } |
126 /^subject=\s.*CN=(.*)\s+$/ and $cn = $1; |
105 close(READ); |
127 /^notAfter=(.*)\s+$/ and $enddate = $1; |
106 } |
128 /^(SSL\sclient)\s:\sYes$/ and $cert_type = $1; |
|
129 /^(SSL\sserver)\s:\sYes$/ and $cert_type = $1; |
|
130 } |
|
131 close(READ); |
|
132 } |
|
133 |
107 # fill the hash |
134 # fill the hash |
108 push ( @{$certs{$file}}, ($cn, $enddate, $sig) ); |
135 push( @{ $certs{$file} }, ( $cn, $enddate, $sig, $cert_type ) ); |
109 } |
136 } |
110 |
137 |
111 # calculate the time |
138 # calculate the time |
112 $w_time = DateCalc("today", "+ $opt_w"); |
139 $w_time = DateCalc( "today", "+ $opt_w" ); |
113 $c_time = DateCalc("today", "+ $opt_c"); |
140 $c_time = DateCalc( "today", "+ $opt_c" ); |
114 |
141 |
115 # check expire date |
142 # check expire date |
116 foreach (sort keys %certs) { |
143 foreach ( sort keys %certs ) { |
117 my $enddate; |
144 my $enddate; |
118 if (@{$certs{$_}}[1] =~ /(\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)/) { $enddate = $1; } |
145 if ( @{ $certs{$_} }[1] =~ /(\w+\s+\d+\s+\d+:\d+:\d+\s+\d+)/ ) { |
|
146 $enddate = $1; |
|
147 } |
119 $enddate = ParseDate($enddate); |
148 $enddate = ParseDate($enddate); |
120 unless ($enddate) { |
149 unless ($enddate) { |
121 print "CERT CRITICAL: Can't parse enddate\n"; |
150 print "CERT CRITICAL: Can't parse enddate\n"; |
122 exit $ERRORS{"CRITICAL"}; |
151 exit $ERRORS{"CRITICAL"}; |
123 } |
152 } |
124 |
153 |
125 &Date_Cmp($enddate, $w_time) > 0 and push (@{$certs{$_}}, "OK"), next; |
154 &Date_Cmp( $enddate, $w_time ) > 0 and push( @{ $certs{$_} }, "OK" ), next; |
126 &Date_Cmp($enddate, $c_time) > 0 and push (@{$certs{$_}}, "WARNING"), next; |
155 &Date_Cmp( $enddate, $c_time ) > 0 |
127 push (@{$certs{$_}}, "CRITICAL"); |
156 and push( @{ $certs{$_} }, "WARNING" ), next; |
|
157 push( @{ $certs{$_} }, "CRITICAL" ); |
128 } |
158 } |
129 |
159 |
130 # looking for stats |
160 # looking for stats |
131 foreach (sort keys %certs) { |
161 foreach ( sort keys %certs ) { |
132 if (@{$certs{$_}}[2]) { |
162 if ( @{ $certs{$_} }[2] ) { |
133 if (@{$certs{$_}}[2] eq "$opt_s") { |
163 if ( @{ $certs{$_} }[2] eq "$opt_s" ) { |
134 push (@warning, "file: $_, CN=@{$certs{$_}}[0] Signature Algorithm: @{$certs{$_}}[2]"); |
164 push( @warning, |
|
165 "file: $_, CN=@{$certs{$_}}[0] Signature Algorithm: @{$certs{$_}}[2]" |
|
166 ); |
135 } |
167 } |
136 } |
168 } |
137 |
169 |
138 if (@{$certs{$_}}[3] eq "WARNING") { |
170 if ( @{ $certs{$_} }[4] eq "WARNING" ) { |
139 push (@warning, "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1]"); |
171 push( @warning, |
140 } elsif (@{$certs{$_}}[3] eq "CRITICAL") { |
172 "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1] type: @{$certs{$_}}[3]" |
141 push (@critical, "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1]"); |
173 ); |
|
174 } |
|
175 elsif ( @{ $certs{$_} }[4] eq "CRITICAL" ) { |
|
176 push( @critical, |
|
177 "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1] type: @{$certs{$_}}[3]" |
|
178 ); |
|
179 } |
|
180 else { |
|
181 push( @ok, |
|
182 "file: $_, CN=@{$certs{$_}}[0] expires @{$certs{$_}}[1] type: @{$certs{$_}}[3]" |
|
183 ); |
142 } |
184 } |
143 } |
185 } |
144 |
186 |
145 # return the state |
187 # return the state |
146 if (@critical) { |
188 if (@critical) { |
147 print "CERT CRITICAL: @critical\n"; |
189 print "CERT CRITICAL: @critical\n"; |
148 exit $ERRORS{"CRITICAL"}; |
190 exit $ERRORS{"CRITICAL"}; |
149 } elsif (@warning) { |
191 } |
|
192 elsif (@warning) { |
150 print "CERT WARNING: @warning\n"; |
193 print "CERT WARNING: @warning\n"; |
151 exit $ERRORS{"WARNING"}; |
194 exit $ERRORS{"WARNING"}; |
152 } else { |
195 } |
153 print "CERT OK: all certificates in limit\n"; |
196 else { |
|
197 print "CERT OK: @ok\n"; |
154 exit $ERRORS{"OK"}; |
198 exit $ERRORS{"OK"}; |
155 } |
199 } |
156 |
200 |
157 sub print_usage() { |
201 sub print_usage() { |
158 print "Usage:\n"; |
202 print "Usage:\n"; |
159 print " $ME [-b <binary>] [-w <time>] [-c <time>] [-s <signature algorithm>] [-f <file,file,file,...>]\n"; |
203 print |
|
204 " $ME [-b <binary>] [-w <time>] [-c <time>] [-s <signature algorithm>] [-f <file,file,file,...>]\n"; |
160 print " $ME [-h | --help]\n"; |
205 print " $ME [-h | --help]\n"; |
161 print " $ME [-V | --version]\n"; |
206 print " $ME [-V | --version]\n"; |
162 } |
207 } |
163 |
208 |
164 sub print_help() { |
209 sub print_help() { |
165 print_revision($ME, "0.1"); |
210 print_revision( $ME, "1.2" ); |
166 print "Copyright (c) 2008 Christian Arnold\n\n"; |
211 print "Copyright (c) 2010 Christian Arnold\n\n"; |
167 print "This plugin checks the expire date for openssl certificates.\n\n"; |
212 print "This plugin checks the expire date for openssl certificates.\n\n"; |
168 print_usage(); |
213 print_usage(); |
169 print "\n"; |
214 print "\n"; |
170 print " -b, --binary <binary>\n"; |
215 print " -b, --binary <binary>\n"; |
171 print " Path of openssl binary (default: /usr/bin/openssl)\n"; |
216 print " Path of openssl binary (default: /usr/bin/openssl)\n"; |
172 print " -w, --warning <time>\n"; |
217 print " -w, --warning <time>\n"; |
173 print " Certificat should not be more than this time older (default: 1month)\n"; |
218 print |
174 print " For time can be used year, month, day, hour, minute, second and weeks.\n"; |
219 " Certificat should not be more than this time older (default: 1month)\n"; |
|
220 print |
|
221 " For time can be used year, month, day, hour, minute, second and weeks.\n"; |
175 print " -c, --critical <time>\n"; |
222 print " -c, --critical <time>\n"; |
176 print " Certificat should not be more than this time older (default: 1week)\n"; |
223 print |
177 print " For time can be used year, month, day, hour, minute, second and weeks.\n"; |
224 " Certificat should not be more than this time older (default: 1week)\n"; |
|
225 print |
|
226 " For time can be used year, month, day, hour, minute, second and weeks.\n"; |
178 print " -s, --signature <signature algorithm>\n"; |
227 print " -s, --signature <signature algorithm>\n"; |
179 print " Return WARNING status if <signature algorithm> is used (default: md5WithRSAEncryption).\n"; |
228 print |
|
229 " Return WARNING status if <signature algorithm> is used (default: md5WithRSAEncryption).\n"; |
180 print " -f, --certfile <file,file,file, ...>\n"; |
230 print " -f, --certfile <file,file,file, ...>\n"; |
181 print " Absolute path of x509 or pkcs12 openssl certificate files, use comma-separated lists for multiple files.\n"; |
231 print |
|
232 " Absolute path of x509 or pkcs12 openssl certificate files, use comma-separated lists for multiple files.\n"; |
182 print " -h, --help\n"; |
233 print " -h, --help\n"; |
183 print " Print detailed help screen\n"; |
234 print " Print detailed help screen\n"; |
184 print " -V, --version\n"; |
235 print " -V, --version\n"; |
185 print " Print version information\n"; |
236 print " Print version information\n"; |
186 print "\n"; |
237 print "\n"; |
187 support(); |
238 support(); |
188 } |
239 } |
189 |
240 |
190 |
|
191 exit; |
241 exit; |
192 |
242 |
193 # vim:sts=4 sw=4 aw ai sm: |
243 # vim:sts=4 sw=4 aw ai sm: |