237 lines
6.2 KiB
Plaintext
237 lines
6.2 KiB
Plaintext
|
#!/usr/bin/perl
|
||
|
use strict;
|
||
|
my $VERSION = '0.1';
|
||
|
my $COPYRIGHT = 'Copyright (C) 2005-2011 Jonathan Buhacoff <jonathan@buhacoff.net>';
|
||
|
my $LICENSE = 'http://www.gnu.org/licenses/gpl.txt';
|
||
|
my %status = ( 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2, 'UNKNOWN' => 3 );
|
||
|
|
||
|
use Getopt::Long;
|
||
|
use Mail::IMAPClient;
|
||
|
use IO::Socket::SSL;
|
||
|
use Net::SSLeay;
|
||
|
|
||
|
# get options from command line
|
||
|
Getopt::Long::Configure("bundling");
|
||
|
my $verbose = 0;
|
||
|
my $help = "";
|
||
|
my $help_usage = "";
|
||
|
my $show_version = "";
|
||
|
my $imap_server = "";
|
||
|
my $default_imap_port = "143";
|
||
|
my $default_imap_ssl_port = "993";
|
||
|
my $imap_port = "";
|
||
|
my $timeout = 60;
|
||
|
my $ok;
|
||
|
$ok = Getopt::Long::GetOptions(
|
||
|
"V|version"=>\$show_version,
|
||
|
"v|verbose+"=>\$verbose,"h|help"=>\$help,"usage"=>\$help_usage,
|
||
|
# imap settings
|
||
|
"H|hostname=s"=>\$imap_server,"p|port=i"=>\$imap_port,
|
||
|
# time
|
||
|
"t|timeout=i"=>\$timeout
|
||
|
);
|
||
|
|
||
|
if( $show_version ) {
|
||
|
print "$VERSION\n";
|
||
|
exit $status{UNKNOWN};
|
||
|
}
|
||
|
|
||
|
if( $help ) {
|
||
|
exec "perldoc", $0 or print "Try `perldoc $0`\n";
|
||
|
exit $status{UNKNOWN};
|
||
|
}
|
||
|
|
||
|
if( $help_usage
|
||
|
||
|
||
|
( $imap_server eq "" )
|
||
|
) {
|
||
|
print "Usage: $0 -H host [-p port]\n";
|
||
|
exit $status{UNKNOWN};
|
||
|
}
|
||
|
|
||
|
my @certs = (); # we have to store the certs we get Net::SSLeay here so that we can output them in REVERSE order (server cert first, root cert last)
|
||
|
|
||
|
# connect to IMAP server
|
||
|
print "connecting to server $imap_server\n" if $verbose > 2;
|
||
|
my $imap;
|
||
|
eval {
|
||
|
local $SIG{ALRM} = sub { die "exceeded timeout $timeout seconds\n" }; # NB: \n required, see `perldoc -f alarm`
|
||
|
alarm $timeout;
|
||
|
|
||
|
$imap_port = $default_imap_ssl_port unless $imap_port;
|
||
|
my $socket = IO::Socket::SSL->new(
|
||
|
PeerAddr => "$imap_server:$imap_port",
|
||
|
SSL_verify_mode => 1,
|
||
|
SSL_ca_file => undef,
|
||
|
SSL_verifycn_scheme => 'imap',
|
||
|
SSL_verifycn_name => $imap_server,
|
||
|
SSL_verify_callback => \&ssl_printer
|
||
|
);
|
||
|
die IO::Socket::SSL::errstr() unless $socket;
|
||
|
$socket->autoflush(1);
|
||
|
$imap = Mail::IMAPClient->new(Socket=>$socket, Debug => 0 );
|
||
|
$imap->State(Mail::IMAPClient->Connected);
|
||
|
$imap->_read_line() if "$Mail::IMAPClient::VERSION" le "2.2.9"; # necessary to remove the server's "ready" line from the input buffer for old versions of Mail::IMAPClient. Using string comparison for the version check because the numeric didn't work on Darwin and for Mail::IMAPClient the next version is 2.3.0 and then 3.00 so string comparison works
|
||
|
# $imap->User($username);
|
||
|
# $imap->Password($password);
|
||
|
# $imap->login() or die "Cannot login: $@";
|
||
|
|
||
|
print join("\n",reverse(@certs));
|
||
|
alarm 0;
|
||
|
};
|
||
|
if( $@ ) {
|
||
|
chomp $@;
|
||
|
print "Could not connect to $imap_server port $imap_port: $@\n";
|
||
|
exit $status{CRITICAL};
|
||
|
}
|
||
|
unless( $imap ) {
|
||
|
print "Could not connect to $imap_server port $imap_port: $@\n";
|
||
|
exit $status{CRITICAL};
|
||
|
}
|
||
|
|
||
|
# deselect the mailbox
|
||
|
$imap->close();
|
||
|
|
||
|
# disconnect from IMAP server
|
||
|
print "disconnecting from server\n" if $verbose > 2;
|
||
|
$imap->logout();
|
||
|
|
||
|
|
||
|
exit $status{OK};
|
||
|
|
||
|
# see IO::Socket::SSL documentation for SSL_verify_callback:
|
||
|
sub ssl_printer {
|
||
|
my ($boolOpenSSLResult, $cmemCertificateStore, $strCertIssuerOwnerAttr, $strError, $cmemPeerCertificate) = @_;
|
||
|
warn "OpenSSL says certificate is " . ( $boolOpenSSLResult ? "valid" : "invalid" ) if $verbose > 0;
|
||
|
warn "Peer certificate: $strCertIssuerOwnerAttr" if $verbose > 0;
|
||
|
warn "Errors: $strError" if $verbose > 0;
|
||
|
#print Net::SSLeay::PEM_get_string_X509($cmemPeerCertificate);
|
||
|
push @certs, $strCertIssuerOwnerAttr . "\n" . Net::SSLeay::PEM_get_string_X509($cmemPeerCertificate);
|
||
|
}
|
||
|
|
||
|
package main;
|
||
|
1;
|
||
|
|
||
|
__END__
|
||
|
|
||
|
|
||
|
=pod
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
|
imap_ssl_cert - connects to an IMAP server using SSL and saves the server certificate into a .pem file
|
||
|
|
||
|
=head1 SYNOPSIS
|
||
|
|
||
|
imap_ssl_cert -H imap.server.com > server_ca_file.pem
|
||
|
imap_ssl_cert -?
|
||
|
imap_ssl_cert --help
|
||
|
|
||
|
=head1 DEPENDENCIES
|
||
|
|
||
|
This utility requires the following perl modules to be installed:
|
||
|
|
||
|
Getopt::Long
|
||
|
Mail::IMAPClient
|
||
|
IO::Socket::SSL
|
||
|
Net::SSLeay
|
||
|
|
||
|
=head1 OPTIONS
|
||
|
|
||
|
=over
|
||
|
|
||
|
=item --timeout <seconds>
|
||
|
|
||
|
Abort with critical status if it takes longer than <seconds> to connect to the IMAP server. Default is 60 seconds.
|
||
|
The difference between timeout and critical is that, with the default settings, if it takes 45 seconds to
|
||
|
connect to the server then the connection will succeed but the plugin will return CRITICAL because it took longer
|
||
|
than 30 seconds.
|
||
|
Also known as: -t <seconds>
|
||
|
|
||
|
=item --hostname <server>
|
||
|
|
||
|
Address or name of the IMAP server. Examples: mail.server.com, localhost, 192.168.1.100
|
||
|
Also known as: -H <server>
|
||
|
|
||
|
=item --port <number>
|
||
|
|
||
|
Service port on the IMAP server. Default is 143. If you use SSL, default is 993.
|
||
|
Also known as: -p <number>
|
||
|
|
||
|
=item --verbose
|
||
|
|
||
|
Display additional information. Useful for troubleshooting.
|
||
|
|
||
|
Also known as: -v
|
||
|
|
||
|
=item --version
|
||
|
|
||
|
Display plugin version and exit.
|
||
|
Also known as: -V
|
||
|
|
||
|
=item --help
|
||
|
|
||
|
Display this documentation and exit.
|
||
|
Also known as: -h
|
||
|
|
||
|
=item --usage
|
||
|
|
||
|
Display a short usage instruction and exit.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head1 EXAMPLES
|
||
|
|
||
|
=head2 Print the server's SSL certificate chain
|
||
|
|
||
|
$ perl imap_ssl_cert.pl -H imap.server.com > ca_file.pem
|
||
|
$ cat ca_file.pem
|
||
|
|
||
|
-----BEGIN CERTIFICATE-----
|
||
|
MIID1zCCAr+gAwIBAgIQPr3bVk0SkuXygjxgA7EVGDANBgkqhkiG9w0BAQUFADA8
|
||
|
[...snip...]
|
||
|
0FF4warjskrfqaVtWeIV58LJheaM4cPJkc2M
|
||
|
-----END CERTIFICATE-----
|
||
|
|
||
|
$ openssl x509 -in ca_file.pem -text
|
||
|
|
||
|
|
||
|
=head1 SEE ALSO
|
||
|
|
||
|
http://en.wikipedia.org/wiki/X.509
|
||
|
http://en.wikipedia.org/wiki/Privacy_Enhanced_Mail
|
||
|
http://tools.ietf.org/html/rfc1422
|
||
|
http://search.cpan.org/~mikem/Net-SSLeay-1.42/lib/Net/SSLeay.pm
|
||
|
http://search.cpan.org/~plobbes/Mail-IMAPClient-3.29/lib/Mail/IMAPClient.pod
|
||
|
|
||
|
=head1 CHANGES
|
||
|
|
||
|
Fri Nov 11 03:38:13 AST 2011
|
||
|
+ version 0.1
|
||
|
|
||
|
=head1 AUTHOR
|
||
|
|
||
|
Jonathan Buhacoff <jonathan@buhacoff.net>
|
||
|
|
||
|
=head1 COPYRIGHT AND LICENSE
|
||
|
|
||
|
Copyright (C) 2011 Jonathan Buhacoff
|
||
|
|
||
|
This program is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
http://www.gnu.org/licenses/gpl.txt
|
||
|
|
||
|
=cut
|
||
|
|