#!/usr/bin/perl -wT
# ------------------------------------------------------------------------------
# File Name:    check_pop3.pl
# Author:    Richard Mayhew - South Africa
# Date:      2000/01/21
# Version:    1.0
# Description:    This script will check to see if an POP3 is running
#      and whether authentication can take place.
# Email:    netsaint@splash.co.za
# ------------------------------------------------------------------------------
# Copyright 1999 (c) Richard Mayhew
# Credits go to Ethan Galstad for coding Nagios
# If any changes are made to this script, please mail me a copy of the
# changes :)
# License GPL
# ------------------------------------------------------------------------------
# Date    Author    Reason
# ----    ------    ------
# 1999/09/20  RM    Creation
# 1999/09/20  TP    Changed script to use strict, more secure by
#        specifying $ENV variables. The bind command is
#        still insecure through.  Did most of my work
#        with perl -wT and 'use strict'
# 2000/01/20  RM    Corrected POP3 Exit State.
# 2000/01/21  RM    Fix Exit Codes Again!!
# 2003/12/30  CZ    Proper CRLF in communication w/server
#        Fixed infinite loop
#        Error checking on welcome banner, USER, PASS commands
#        Better error condition handling

# ------------------------------------------------------------------------------

# -----------------------------------------------------------------[ Require ]--
require 5.004;

# --------------------------------------------------------------------[ Uses ]--
use strict;
use lib utils.pm ;
use Plugin;
use Plugin::Parameter qw(:DEFAULT :standard $u_opt $P_opt $p_opt);

use Socket;

use vars qw($PROGNAME $remotehost $username $password $remoteport $opt_t);

use utils qw(%ERRORS);
# --------------------------------------------------------------[ Enviroment ]--
$ENV{PATH} = "/bin";
$ENV{BASH_ENV} = "";
$|=1;
# ------------------------------------------------------------------[ Global ]--
$H_opt->binding(\$remotehost);
$u_opt->binding(\$username);
$u_opt->optional("no");
$P_opt->binding(\$password);
$P_opt->flags([ 'P', 'password' ]);
$P_opt->optional("no");
$p_opt->binding(\$remoteport);
$p_opt->default(110);
$p_opt->description("Port that the pop3 daemon is running on");
my $plugin = new Plugin(-revision => '$Revision: 1.2 $',
			-copyright => "2000 Richard Mayhew, 2004 Howard Wilkinson <howard\@cohtech.com>",
			-shortcomment => "Perl Check POP3 plugin for Nagios",
			-parameterlists => [ [ $H_opt, $u_opt, $P_opt, $p_opt, $t_opt ], $h_opts, $V_opts ]);

# --------------------------------------------------------------[ bindRemote ]--
sub bindRemote
{
	my ($in_remotehost, $in_remoteport, $in_hostname, $proto) = @_;
	my $sockaddr;
	my $this;
	my $thisaddr = INADDR_ANY;
	my $that;
	my ($name, $aliases,$type,$len,$thataddr) = gethostbyname($in_remotehost);

	if (!socket(ClientSocket,AF_INET, SOCK_STREAM, $proto)) { die $!; }
	$sockaddr = 'S n a4 x8';
	$this = pack($sockaddr, AF_INET, 0, $thisaddr);
	$that = pack($sockaddr, AF_INET, $in_remoteport, $thataddr);
	if (!bind(ClientSocket, $this)) { print "Connection Refused\n"; exit 2; }
	if (!connect(ClientSocket, $that)) { print "Connection Refused\n"; exit 2; }
	select(ClientSocket); $| = 1; select(STDOUT);
	return \*ClientSocket;
}

# ====================================================================[ MAIN ]==
MAIN:
{
	my $hostname;

	$plugin->init();

	$plugin->start_timeout($opt_t, "Something is Taking a Long Time, Increase Your TIMEOUT (Currently Set At $opt_t Seconds)");

	chop($hostname = `hostname`);
	my ($name, $alias, $proto) = getprotobyname('tcp');
	my $ClientSocket = &bindRemote($remotehost,$remoteport,$hostname,$proto);
	
	$_ = <ClientSocket>;
	&err("no welcome banner\n") unless (defined $_ && $_);
	&err("bad welcome banner: " . $_) unless $_ =~ /^\+OK/;

	print ClientSocket "USER $username\r\n";

	$_ = <ClientSocket>;
	&err("no response to USER command\n") unless (defined $_ && $_);
	&err("bad response to USER: " . $_) unless $_ =~ /^\+OK/;

	print ClientSocket "PASS $password\r\n";

	$_ = <ClientSocket>;
	&err("no response to PASS command\n") unless (defined $_ && $_);
	&err("bad response to PASS: " . $_) unless $_ =~ /^\+OK/;

	print ClientSocket "LIST\r\n";

	my $bad = 1;
	my $msgs = 0;
	while (<ClientSocket>) {
		&err(($1||' UNKNOWN')."\n") if (m/\-ERR(.*)/);
		$bad = 0 if /^\+OK/;
		$msgs = $1 if /^(\d+)\s+/;
		last if /^\./;
	}

	&message("$msgs\n") unless $bad;

	&err("missing +OK to LIST command\n");
}

sub message 
{
	my $msg = shift;
	print ClientSocket "QUIT\r\n";
	close ClientSocket;
	$plugin->stop_timeout();
	print "$PROGNAME OK - Total Messages On Server: $msg";
	exit $ERRORS{'OK'};
}

sub err
{
	my $msg = shift;
	alarm(0);
	print ClientSocket "QUIT\r\n";
	print "$PROGNAME UNKNOWN: $msg";
	exit $ERRORS{'UNKNOWN'};
}
