File: check-cert-expire.pl

package info (click to toggle)
libnet-ssl-expiredate-perl 1.25-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 216 kB
  • sloc: perl: 547; makefile: 10
file content (171 lines) | stat: -rwxr-xr-x 3,751 bytes parent folder | download
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
#!/usr/bin/env perl

use strict;
use warnings;
use Carp;
use Getopt::Long;
use Pod::Usage;
use Data::Dumper;

use Net::SSL::ExpireDate;
use Regexp::Common qw(net);
use YAML;
use URI::Escape;
# use Smart::Comments;

MAIN: {
    my %opt;
    Getopt::Long::Configure("bundling");
    GetOptions(\%opt,
               'duration|d=s',
               'file|f=s',
               'link|l',
               'help|h|?') or pod2usage(-verbose=>1);
    pod2usage(-verbose=>1) if exists $opt{'help'};
    pod2usage("missing option: --file") unless exists $opt{'file'};

    ### %opt
    open my $file, '<', $opt{'file'}
        or croak "$opt{'file'}: $!";
    chomp (my @testee = <$file>);
    close $file;
    ### @testee

    my $duration = exists $opt{'duration'} ? $opt{'duration'} : undef;
    ### $duration

    my $output = {
        title => 'Certificate Expire Date',
        entry => [],
    };

    for my $t (@testee) {
        next if $t =~ /^#/;
        next if $t =~ /^$/;
        ### testee: $t
        my $ed = Net::SSL::ExpireDate->new( build_arg($t) );
        if ($ed->is_expired($duration)) {
            ### expired: $ed->expire_date->iso8601
            push @{$output->{entry}}, {
                title => $t . ($duration ? " (expire within $duration)" : ''),
                date  => $ed->expire_date->iso8601,
            };
            ${ $output->{entry} }[-1]->{link} = mk_link($ed, $duration) if $opt{'link'};
        }
    }

    print YAML::Dump $output;

    exit 0;
}

sub build_arg {
    my ($v) = @_;
    if ($v =~ m{^(file)://(.+)}) {
        return $1 => $2;
    } elsif ($v =~ m{^(https)://([^/]+)}) {
        return $1 => $2;
    } elsif ($v =~ m{^$RE{net}{domain}{-nospace}{-keep}$}) {
        return 'https' => $1;
    } elsif (-r $v) {
        return 'file' => $v;
    } else {
        croak "$v: assume file. but cannot read.";
    }
}

sub mk_link {
    my ($ed, $duration) = @_;
    $ed->type . '://' . $ed->target . ($duration ? '#' . uri_escape($duration) : '');
}

__END__

=head1 NAME

B<check-cert-expire.pl> - check and list expired certificates

=head1 SYNOPSIS

B<check-cert-expire.pl> [ B<--help> ] [ B<--duration> DURATION ] B<--file> DATAFILE

  $ cat <<EOF > server-list.txt
  https://rt.cpan.org
  https://www.google.com
  EOF
  
  $ check-cert-expire.pl --duration '3 months' --file server-list.txt
  $ check-cert-expire.pl -d         '3 months' -f     server-list.txt
  ---
  entry:
    - date: 2015-04-14T05:12:17
      title: https://rt.cpan.org
  title: Certificate Expire Date

=head1 DESCRIPTION

Examine expire date of certificate and output name and expire date if expired.
Output format is YAML.

Examinee certificate is both OK via network (HTTPS) and local file.

=head1 OPTIONS

=over 4

=item B<--file> DATAFILE

=item B<-f> DATAFILE

DATAFILE is name of plain text file contains testee list.

Acceptable list format is the following.

  FORMAT        EXAMPLE
  ===============================
  https://FQDN  https://rt.cpan.org
  file://PATH   file:///etc/ssl/cert.pem
  FQDN          rt.cpan.org
  PATH          /etc/ssl/cert.pem

=item B<--duration> DURATION

=item B<-d> DURATION

Specify the furtur point to check expiration.
If omitted, check against just now.

DURATION accepts human readable text. See also L<Time::Duration::Parse|Time::Duration::Parse>.

  3 days
  4 months
  10 years
  4 months and 3days

=item B<--link>

=item B<-l>

Add dummy link attribute.

=back

=head1 SEE ALSO

L<Net::SSL::ExpireDate|Net::SSL::ExpireDate>,
L<Time::Duration::Parse|Time::Duration::Parse>

=head1 AUTHOR

HIROSE, Masaaki E<lt>hirose31@gmail.comE<gt>

=cut

# for Emacsen
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# indent-tabs-mode: nil
# End:

# vi: set ts=4 sw=4 sts=0 :