", method => "LOGIN PLAIN", required => 1};
# check if the logo file exists
if (-e $logofile)
{
# In emails, images need to be base64 encoded, we encode the logo here
$logo_img = b64encode_img($logofile);
# extract the image format from the file extension
$logo_type = ($logofile =~ m/([^.]+)$/)[0];
$logofile = basename($logofile);
}
else
{
# If the logo file cannot be found, we send a 1x1px empty logo image instead
$logo_img = $empty_img;
$logo_type = "gif";
}
create_boundary();
create_message_text();
create_message_html();
$mail{'content-type'} = qq(multipart/alternative; boundary="$boundary1");
# Here we define the mail content to be send
my $mail_content = "This is a multi-part message in MIME format.\n";
# create the first boundary start marker for the main message (text)
$mail_content = $mail_content . '--' . "$boundary1\n";
$mail_content = $mail_content . "Content-Type: text/plain; charset=utf-8\n";
$mail_content = $mail_content . "Content-Transfer-Encoding: 8bit\n\n";
$mail_content = $mail_content . "$text_msg\n";
$mail_content = $mail_content . '--' . "$boundary1\n";
# create the second boundary start marker for the main message (html)
$mail_content = $mail_content . "Content-Type: multipart/related; boundary=\"$boundary2\"\n\n";
$mail_content = $mail_content . '--' . "$boundary2\n";
$mail_content = $mail_content . "Content-Type: text/html; charset=utf-8\n";
$mail_content = $mail_content . "Content-Transfer-Encoding: 8bit\n\n";
$mail_content = $mail_content . "$html_msg\n";
# create the third boundary marker for the logo image
$mail_content = $mail_content . '--' . "$boundary2\n";
$mail_content = $mail_content . "Content-Type: image/$logo_type; name=\"$logofile\"\n";
$mail_content = $mail_content . "Content-Transfer-Encoding: base64\n";
$mail_content = $mail_content . "Content-ID: <$logo_id>\n";
$mail_content = $mail_content . "Content-Disposition: inline; filename=\"$logofile\"\n\n";
$mail_content = $mail_content . "$logo_img\n";
# create the final end boundary marker
$mail_content = $mail_content . '--' . $boundary2 . "--\n\n";
$mail_content = $mail_content . '--' . $boundary1 . "--\n";
# put the completed message body into the mail
$mail{body} = $mail_content ;
sendmail(%mail) or die $Mail::Sendmail::error;
exit 0;
#--- Begin subroutines ------------------------------------------------------
#########################################################################
# unique content ID are needed for multipart messages with inline logos
#########################################################################
sub create_content_id
{
my $unique_string;
my $content_id;
$unique_string = rand(100);
$unique_string = $unique_string . substr(md5_hex(time()),0,23);
$unique_string =~ s/(.{5})/$1\./g;
$content_id = qq(part.${unique_string}\@) . "MAIL";
$unique_string = undef;
return $content_id;
}
# create_boundary creates the S/MIME multipart boundary strings
sub create_boundary
{
my $unique_string;
$unique_string = substr(md5_hex(time()),0,24);
$boundary1 = '======Part1=' . $unique_string ;
$unique_string = undef;
$unique_string = substr(md5_hex(time()),0,24);
$boundary2 = '======Part2=' . $unique_string ;
$unique_string = undef;
}
sub unknown_arg
{
print_usage();
exit 2;
}
# Create a plaintext message -> $text_msg
sub create_message_text
{
$text_msg = "Nagios Monitoring System Notification\n" . "=====================================\n\n";
$text_msg =$text_msg . "Notification Type: $notificationtype\n";
$text_msg =$text_msg . "Host/Service Status: $state\n";
$text_msg =$text_msg . "Hostname: $hostname\n";
if (defined($hostalias))
{
$text_msg =$text_msg . "Hostalias: $hostalias\n";
}
$text_msg =$text_msg . "Host Address: $hostaddress\n";
if ((defined($servicedesc)) && ($servicedesc ne ""))
{
$servicedesc =~ s/
/\n/isog;
$servicedesc =~ s/<[^<>]*>//isog;
$text_msg =$text_msg . "Service Name: $servicedesc\n";
$text_msg =$text_msg . "Service Data: $serviceoutput\n\n";
}
# if author and comment data has been passed from Nagios
# and these variables have content, then we add two more columns
if (( defined($notificationauthor) && defined($notificationcmt)) && (($notificationauthor ne "") && ($notificationcmt ne "")))
{
$text_msg =$text_msg . "Author: $notificationauthor\n";
$text_msg =$text_msg . "Comment: $notificationcmt\n\n";
}
$text_msg =$text_msg . "Event Time: $datetime\n\n";
$text_msg =$text_msg . "-------------------------------------\n";
}
# Create a HTML message -> $html_msg, per flags include URL's and IMG's
sub create_message_html
{
my $cellcolor;
my $html_style;
# Start HTML message definition
$html_msg = "Nagios Monitoring System Notification\n";
$html_msg = $html_msg . "\n";
$logo_id = create_content_id();
$html_msg = $html_msg . "";
$html_msg = $html_msg . " | ";
$html_msg = $html_msg . "";
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Nagios Monitoring System Notification |
\n";
$cellcolor = $NOTIFICATIONCOLOR{$notificationtype};
if ($state eq "WARNING")
{
$cellcolor = $NOTIFICATIONCOLOR{PROBLEM_WARN};
}
$html_msg = $html_msg . "";
$html_msg = $html_msg . " Notification Type: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . " $notificationtype ";
$html_msg = $html_msg . " |
\n";
$cellcolor = $NOTIFICATIONCOLOR{$state};
$html_msg = $html_msg . "";
$html_msg = $html_msg . " Host/Service State: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . " $state ";
$html_msg = $html_msg . " |
\n";
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Hostname: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
# The Hostname URL http:///cgi-bin/status.cgi?host=$HOSTNAME$&style=detail
# this URL shows the host and all services underneath it
$html_msg = $html_msg . "$hostname
(Click to see host overview in Nagios) ";
$html_msg = $html_msg . " |
\n";
if ((defined($hostalias)) && ($hostalias ne ""))
{
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Hostalias: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . " $hostalias ";
$html_msg = $html_msg . " |
\n";
}
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Host Address: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . " $hostaddress ";
$html_msg = $html_msg . " |
\n";
# Print the service state, set the cell color based on the value CRITICAL, WARNING, OK, UNKNOWN
if ((defined($servicedesc)) && ($servicedesc ne ""))
{
$serviceoutput =~ s/\n/
/g;
$serviceoutput =~ s/\\n/
/g;
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Service Name: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . " $servicedesc ";
$html_msg = $html_msg . " |
\n";
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Service Output: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . "$serviceoutput
(Click to see detailed service info in Nagios) \n";
}
$html_msg = $html_msg . " |
\n";
# If the author and comment data has been passed from nagios
# and these variables have content, then we add two more columns
if ( ( defined($notificationauthor) && defined($notificationcmt) ) && ( ($notificationauthor ne "") && ($notificationcmt ne "") ) )
{
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Author: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . "$notificationauthor ";
$html_msg = $html_msg . " |
\n";
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Comment: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . "$notificationcmt ";
$html_msg = $html_msg . " |
\n";
}
$html_msg = $html_msg . "";
$html_msg = $html_msg . "Event Time: ";
$html_msg = $html_msg . " | \n";
$html_msg = $html_msg . "\n";
$html_msg = $html_msg . "$datetime ";
$html_msg = $html_msg . " |
\n";
$html_msg = $html_msg . "
\n";
# End HTML message definition
$html_msg = $html_msg . "\n";
}
# urlencode() URL encode a string
sub urlencode
{
my $urldata = $_[0];
my $MetaChars = quotemeta( '-;,/?\|=+)(*&^%$#@!~`:');
$urldata =~ s/([$MetaChars\"\'\x80-\xFF])/"%" . uc(sprintf("%2.2x", ord($1)))/eg;
$urldata =~ s/ /\+/g;
return $urldata;
}
# b64encode_image(filename) converts a existing binary source image file
# into a base64-image string.
sub b64encode_img
{
my($inputfile) = @_;
my $b64encoded_img;
open (IMG, $inputfile);
binmode IMG; undef $/;
$b64encoded_img = encode_base64();
close IMG;
return $b64encoded_img;
}
sub print_version
{
print "\nnmon_send_mail.pl version : $ProgVersion\n\n";
}
sub print_usage
{
print "\n";
print "Usage: $0 [-V|--version]\n";
print "or\n";
print "Usage: $0 [-h|--help]\n";
print "or\n";
print "Usage: $0 ";
print "[-c, --configuration=] \n";
print "[-S|--smtphost ] \n";
print " -N|--nagios \n";
print " -r|--recipients \n";
print " --notificationtype \n";
print " [--datetime ] \n";
print " [--hostaddress ] \n";
print " [--hostname ] \n";
print " [--hostalias ] \n";
print " [-t|--thruk] \n";
print " [-s|--ssl] \n";
print " [--notificationauthor ] \n";
print " [--notificationcmt ] \n";
print " [--servicedesc ] \n";
print " [--servicedispname ] \n";
print " [--serviceoutput ] \n";
print " [--longserviceoutput ]\n";
}
sub help
{
print "\nMonitor system mail notification script, version ",$ProgVersion,"\n";
print "GPL licence, (c)2012,2015 Frank Migge, (c)2017 Martin Fuerstenau\n";
print_usage();
print "\n";
print "This script takes over email notifications by receiving the monitor system state\n";
print "information, formatting the email and sending it out through an SMTP gateway.\n";
print "\n";
print "-V, --version Prints version number.\n";
print "-h, --help Print this help message.\n";
print "\n";
print "-c, --configuration= Path to configuration file\n";
print " Default will be path of the script\n";
print " and script name without .pl and .cfg\n";
print " instead.\n";
print "\n";
print " Example:\n";
print " foo.pl -> foo.cfg\n";
print "\n";
print "-S, -smtphost= Name or IP address of SMTP gateway.\n";
print "-N, --nagios= Name of the monitor host (i.e. monitor.mydomain.net)\n";
print "-r, --recipients Comma-separated list of all contact \n";
print " mail addresses that are being notified\n";
print " about the host or service.\n";
print "\n";
print " --notificationtype=notificationtype Nagios notificationtype.A string identifying\n";
print " the type of notification that is being sent:\n";
print " - PROBLEM\n";
print " - RECOVERY\n";
print " - ACKNOWLEDGEMENT\n";
print " - FLAPPINGSTART\n";
print " - FLAPPINGSTOP\n";
print " - FLAPPINGDISABLED\n";
print " - DOWNTIMESTART\n";
print " - DOWNTIMEEND\n";
print " - DOWNTIMECANCELLED\n";
print "\n";
print " --datetime= Nagios datetime (long or short as handed over).\n";
print " --hostaddress= Address of the host. This value is taken from the\n";
print " address directive in the host definition.\n";
print " --hostname= Short name for the host (i.e. \"biglinuxbox\").\n";
print " This value is taken from the host_name directive in\n";
print " the host definition.\n";
print " --hostalias= Nagios hostalias.Long name/description for the host.\n";
print " This value is taken from the alias directive in\n";
print " the host definition.\n";
print "\n";
print "-t | --thruk If set use Thruk for links to Nagios instead of\n";
print " classical view.\n";
print "-s | --ssl Use https instead of http.\n";
print "\n";
print " --notificationauthor=notificationauthor A string containing the name of the user who authored\n";
print " the notification. If the \$NOTIFICATIONTYPE\$ macro is\n";
print " set to \"DOWNTIMESTART\" or \"DOWNTIMEEND\", this will\n";
print " be the name of the user who scheduled downtime for the\n";
print " host or service. If the \$NOTIFICATIONTYPE\$ macro is\n";
print " \"ACKNOWLEDGEMENT\", this will be the name of the user\n";
print " who acknowledged the host or service problem. If the\n";
print " \$NOTIFICATIONTYPE\$ macro is \"CUSTOM\", this will be\n";
print " name of the user who initated the custom host or service\n";
print " notification.\n";
print " --notificationcmt=notificationcmt A string containing the comment that was entered by the\n";
print " notification author. If the \$NOTIFICATIONTYPE\$ macro\n";
print " is set to \"DOWNTIMESTART\" or \"DOWNTIMEEND\", this will\n";
print " be the comment entered by the user who scheduled downtime\n";
print " for the host or service. If the \$NOTIFICATIONTYPE\$ macro\n";
print " is \"ACKNOWLEDGEMENT\", this will be the comment entered\n";
print " by the user who acknowledged the host or service problem.\n";
print " If the \$NOTIFICATIONTYPE\$ macro is \"CUSTOM\", this will\n";
print " be comment entered by the user who initated the custom host\n";
print " or service notification.\n";
print " --servicedesc=servicedesc Nagios service description.The long name/description of\n";
print " the service (i.e. \"Main Website\"). This value is taken\n";
print " from the service_description directive of the service\n";
print " definition.\n";
print " --servicedispname=servicedisplayname An alternate display name for the service. This value is\n";
print " taken from the display_name directive in the service definition.\n";
print " --serviceoutput=serviceoutput The first line of text output from the last service check\n";
print " (i.e. \"Ping OK\").\n";
print " --longserviceoutput=longserviceoutput The full text output (aside from the first line) from the\n";
print " last service check.\n";
print " --state=state Nagios service state or host state.\n";
}