diff --git a/extras/ChangeLog b/extras/ChangeLog index c47067e7e4..60d3c9b56d 100644 --- a/extras/ChangeLog +++ b/extras/ChangeLog @@ -1,3 +1,8 @@ +2011-05-04 Sancho Lerena + + * scripts/mail_transfer: Added new script to send/receive XML data + files by SMTP/POP3. + 2011-02-22 Ramon Novoa * build_src.sh: Updated to work with the current directory structure. diff --git a/extras/scripts/mail_transfer/PandoraFMS_mail_transfer.es.odt b/extras/scripts/mail_transfer/PandoraFMS_mail_transfer.es.odt new file mode 100644 index 0000000000..6460a512b7 Binary files /dev/null and b/extras/scripts/mail_transfer/PandoraFMS_mail_transfer.es.odt differ diff --git a/extras/scripts/mail_transfer/config_file.conf b/extras/scripts/mail_transfer/config_file.conf new file mode 100644 index 0000000000..6169ee2a77 --- /dev/null +++ b/extras/scripts/mail_transfer/config_file.conf @@ -0,0 +1,33 @@ +########################################### +### SMTP DATA +########################################### + +smtp_user devtest@artica.es +smtp_pass pass1212 +smtp_hostname mail.artica.es + +########################################### +### POP3 DATA +########################################### + +pop3_user devtest@artica.es +pop3_pass pass1212 +pop3_hostname mail.artica.es + +# Enable or disable SSL. 1 means Enabled, 0 Disabled +pop3_ssl 0 + +# SSL port +pop3_ssl_port 995 + +########################################### +### TO SEND INFO +########################################### +# Email receiver where to send the email +receiver_email devtest@artica.es + +########################################### +### PATH TO SAVE THE ATTACHED FILE +########################################### +# Desired path where the attached file will be stored +pathtosave /tmp/ diff --git a/extras/scripts/mail_transfer/mail_transfer.pl b/extras/scripts/mail_transfer/mail_transfer.pl new file mode 100755 index 0000000000..0efa048508 --- /dev/null +++ b/extras/scripts/mail_transfer/mail_transfer.pl @@ -0,0 +1,318 @@ +#!/usr/bin/perl +########################################################################## +# Pandora FMS Mail Transfer +# This is a tool for transfering Pandora FMS data files by mail (SMTP/POP) +########################################################################## +# Copyright (c) 2011 Artica Soluciones Tecnologicas S.L +# +# 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; version 2 +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +########################################################################## + +use strict; +use warnings; +use Net::SMTP; +use Mail::POP3Client; +use MIME::Parser; +$| = 1; + +# GLOBAL VARIABLES + +my $boundary='frontier'; + +####### FUNCTIONS ####### + +######################################################################## +## SUB check_args +## Checks the command line arguments given at the function call. +######################################################################## +sub check_args(){ + my $num_args = $#ARGV + 1; + my $action = $ARGV[0]; + my $conf_file = $ARGV[1]; + my $filename = $ARGV[2]; + my $error = "Usage: mail_transfer.pl {send|receive conf_file [FILE]}\n"; + my $error_conf_file = "conf_file does not exist or is not readable\n"; + my $error_filename = "File to send does not exist or is not readable\n"; + + if (($num_args < 2) || (($action ne "send") && ($action ne "receive"))) { + die $error; + } elsif ((!(-e $conf_file)) || (!(-r $conf_file))) { + die $error_conf_file; + } elsif (($action eq "send") && ((!(-e $filename)) || (!(-r $filename)))) { + die $error_filename; + } +} + +######################################################################## +## SUB parse_conf +## Reads the entire conf file and stores all the information given +######################################################################## +sub parse_conf ($$) { + + my $conf_file = $_[0]; + my $conf_hash = $_[1]; + + open (CONF, $conf_file); + my $line; + + while () + { + $line = $_; + # Get the smtp user + if ($line =~ /^smtp_user\s([a-zA-Z0-9\.\_\-\@]+)/) { + $conf_hash -> {smtp_user} = $1; + } + # Get the smtp pass + elsif ($line =~ /^smtp_pass\s(.+)/) { + $conf_hash -> {smtp_pass} = $1; + } + # Get the smtp hostname + elsif ($line =~ /^smtp_hostname\s([a-zA-Z0-9\.\_\-\@]+)/) { + $conf_hash -> {smtp_hostname} = $1; + } + # Get the pop3 user + elsif ($line =~ /^pop3_user\s([a-zA-Z0-9\.\_\-\@]+)/) { + $conf_hash -> {pop3_user} = $1; + } + # Get the pop3 pass + elsif ($line =~ /^pop3_pass\s(.+)/) { + $conf_hash -> {pop3_pass} = $1; + } + # Get the pop3 hostname + elsif ($line =~ /^pop3_hostname\s([a-zA-Z0-9\.\_\-\@]+)/) { + $conf_hash -> {pop3_hostname} = $1; + } + # Get the pop3 ssl flag to know if it's enabled or not + elsif ($line =~ /^pop3_ssl\s(0|1)/) { + $conf_hash -> {pop3_ssl} = $1; + } + # Get the pop3 ssl port + elsif ($line =~ /^pop3_ssl_port\s([0-9]{1,5})/) { + $conf_hash -> {pop3_ssl_port} = $1; + } + # Get the path where to save the attached file + elsif ($line =~ /^pathtosave\s(.+)/) { + $conf_hash -> {pathtosave} = $1; + } + # Get the receiver's email where to send the attached file + elsif ($line =~ /^receiver_email\s([a-zA-Z0-9\.\_\-\@]+)/) { + $conf_hash -> {receiver_email} = $1; + } + } + close CONF; +} + +######################################################################## +## SUB send_mail +## Sends an attachement file via email using smtp +######################################################################## +sub send_mail($) { + + my $conf_hash = $_[0]; + my $smtp; + my $attachment = $conf_hash -> {filename}; + + # Get the filename in case the full path was given + # Split the full path with '/', the last item will be the filename + my @file_path = split ('/', $attachment); + + # Get the array's last position with '-1' index + my $attach_file = $file_path[-1]; + + my $host = $conf_hash -> {smtp_hostname}; + my $from = $conf_hash -> {smtp_user}; + my $password = $conf_hash -> {smtp_pass}; + my $to = $conf_hash -> {receiver_email}; + + open(DATA, $attachment) || die("mail_transfer.pl: ERROR: Could not open the file $attach_file"); + my @xml = ; + close(DATA); + + $smtp = Net::SMTP->new($host, + Hello => $host, + Timeout => 30, + Debug => 0, + ) || die("mail_trasfer.pl: ERROR: Could not connect to $host"); + + $smtp->auth($from, $password); + $smtp->mail($from); + $smtp->to($to); + $smtp->data(); + $smtp->datasend("To: $to\n"); + $smtp->datasend("From: $from\n"); + $smtp->datasend("Subject: Pandora mail transfer\n"); + $smtp->datasend("MIME-Version: 1.0\n"); + $smtp->datasend("Content-Type: application/text; name=" . $attach_file . "\n"); + $smtp->datasend("Content-Disposition: attachment; filename=" . $attach_file . "\n"); + $smtp->datasend("Content-type: multipart/mixed boundary=" . $boundary . "\n"); + $smtp->datasend("\n"); + $smtp->datasend("@xml\n"); + $smtp->dataend() || print "mail_transfer.pl: ERROR: Data end failed: $!"; + $smtp->quit; +} + +######################################################################## +## SUB receive_mail +## Fetch the last email with 'Pandora mail transfer' as subject and +## download the attached file into the specified folder +######################################################################## +sub receive_mail ($) { + + my $conf_hash = $_[0]; + my $user = $conf_hash -> {pop3_user}; + my $password = $conf_hash -> {pop3_pass}; + my $host = $conf_hash -> {pop3_hostname}; + my $ssl = $conf_hash -> {pop3_ssl}; + my $ssl_port = $conf_hash -> {pop3_ssl_port}; + my $pathtosave = $conf_hash -> {pathtosave}; + my $pop3; + + if ($ssl == 1){ + $pop3 = new Mail::POP3Client( + USER => $user, + PASSWORD => $password, + HOST => $host, + USESSL => 1, + PORT => $ssl_port, + DEBUG => 0 + ) or die "mail_transfer.pl: Connection failed\n"; + } else { + $pop3 = new Mail::POP3Client( + USER => $user, + PASSWORD => $password, + HOST => $host, + USESSL => 0, + PORT => 110, + DEBUG => 0 + ) or die "mail_transfer.pl: Connection failed\n"; + } + + my $tot_msg = $pop3->Count(); + + if ($tot_msg == 0){ + print "No more emails avalaible\n"; + return (0); # End program + } + elsif ($tot_msg eq '0E0'){ + print "No new emails available\n"; + return (0); + } + else{ + printf "There are $tot_msg messages \n\n"; + } + + # the list of valid file extensions. we do extensions, not + # mime-types, because they're easier to understand from + # an end-user perspective (no research is required). + + my $valid_exts = "txt xml data"; + my %msg_ids; # used to keep track of seen emails. + + # create a subdirectory if does not exist + #print "Using directory '$pathtosave' for newly downloaded files.\n"; + if (!(-d $pathtosave)) { + mkdir($pathtosave, 0777) or die "mail_transfer.pl: Error creating output directory\n"; + } + + # get the message to feed to MIME::Parser. + my $msg = $pop3->HeadAndBody($tot_msg); + my $header = $pop3->Head($tot_msg); + + if (($header !~ /Subject:\sPandora\smail\stransfer/) || ($header !~ /boundary=$boundary/)) { + print "Deleting message not valid\n"; + + # delete current email + $pop3->Delete($tot_msg); + + # clean up and close the connection. + $pop3->Close; + + return -1; + + } + + # create a MIME::Parser object to + # extract any attachments found within. + my $parser = new MIME::Parser; + + $parser->output_dir($pathtosave); + my $entity = $parser->parse_data($msg); + + # extract our mime parts and go through each one. + my @parts = $entity->parts; + + foreach my $part (@parts) { + + # determine the path to the file in question. + my $path = ($part->bodyhandle) ? $part->bodyhandle->path : undef; + + # move on if it's not defined, + # else figure out the extension. + next unless $path; + $path =~ /\w+\.([^.]+)$/; + my $ext = $1; + next unless $ext; + + # we continue only if our extension is correct. + my $continue; $continue++ if $valid_exts =~ /$ext/i; + + # delete the blasted thing. + unless ($valid_exts =~ /$ext/) { + print " Removing unwanted filetype ($ext): $path\n"; + unlink $path or print " > Error removing file at $path: $!."; + next; # move on to the next attachment or message. + } + + # a valid file type. yummy! + print " Keeping valid file: $path.\n"; + } + + # delete current email + $pop3->Delete($tot_msg); + + # clean up and close the connection. + $pop3->Close; +} + + +####### MAIN ####### + +# Check the given command line arguments +check_args(); + +# Once checked store them +my $action = $ARGV[0]; +my $conf_file = $ARGV[1]; +my $filename = $ARGV[2]; + +# If the action is 'send', store the 'file_to_send' +my %conf_hash; +if ($action eq "send") { + $conf_hash {filename} = $filename; +} + +# Parse the config file +parse_conf($conf_file, \%conf_hash); + +# Call 'send_mail' function in its case +if ($action eq "send") { + send_mail(\%conf_hash); +} + +# Or call the 'receive_mail' function. +my $returncode = 1; + +if ($action eq "receive") { + while ($returncode != 0) { + $returncode = receive_mail(\%conf_hash); + } +}