Current File : //usr/bin/b1sendmail |
#! /usr/bin/perl
use warnings;
use strict;
use Getopt::Long::Descriptive;
use POSIX;
use Text::Header;
use Net::SMTPS;
use Digest::SHA qw(sha1_hex);
use JSON;
my $debug = $ENV{DEBUG} || 0;
# Constants
my %config = (smtp_server => 'mailout.one.com',
smtp_port => 587,
ssl => 'starttls',
);
# Global variables
my @headers = ();
my @message = ();
my $reading_headers = 1;
my %headers_h;
my $line;
sub getjson(){
local $/;
open( my $fh, '<', '/run/mail.conf' );
my $json_text = <$fh>;
return decode_json( $json_text );
}
my ($opt, $usage) = describe_options(
'b1sendmail %o <some-arg>',
["i=i", "Set to 1 to continue beyond . + newline", { default => 0 }],
["f|r=s", "From address"],
["t=s", "To address"]
);
while (defined($line = <STDIN>) and ($opt->i or ($line ne ".\n"))) {
chomp $line;
if ($reading_headers) {
if ($line) {
push @headers, $line;
} else {
$reading_headers = 0;
}
} else {
push @message, $line;
}
}
%headers_h = unheader(@headers);
my $uid = getuid();
my $domain_name = getpwuid($uid);
my $envelope_from = "";
if (defined($headers_h{'from'})) {
my $env_from = $headers_h{'from'};
# Clean out comments
$env_from =~ s/^([^@]+@[^@]+?)\s+\(.*\)$/$1/;
if ($env_from =~ /.\@([a-z0-9-]+\.)+[a-z]{2,20}\s*>?\s*\r?$/i) {
$env_from = $1 if($env_from =~ /<([^\>]+)>/);
$envelope_from = $env_from;
} else {
exit 1 if ($config{b1sendmail_reject_bad_from});
$envelope_from = $env_from;
}
}
$envelope_from =~ s/^[\s\r\n<]+//gismo;
$envelope_from =~ s/[\s\r\n>]+$//gismo;
my $sasluser = $domain_name;
if (defined($opt->f)) {
if ($opt->f =~ /.\@[a-z0-9-]+\.[a-z]{2,20}$/i) {
$envelope_from = $opt->f;
} else {
exit 1 if ($config{b1sendmail_reject_bad_from});
$envelope_from = $opt->f;
}
}
my @envelope_to = ();
if (@ARGV) {
@envelope_to = @ARGV;
}
if (defined($opt->t)) {
if (defined($headers_h{'to'})) {
push @envelope_to, split /, ?/,$headers_h{'to'};
}
if (defined($headers_h{'cc'})) {
push @envelope_to, split /, ?/,$headers_h{'cc'};
}
if (defined($headers_h{'bcc'})) {
push @envelope_to, split /, ?/,$headers_h{'bcc'};
}
}
unless (defined($headers_h{'to'}) or
defined($headers_h{'cc'}) or
defined($headers_h{'bcc'})) {
$headers_h{'bcc'} = '';
}
my $smtp=Net::SMTPS->new($config{smtp_server}, Port => $config{smtp_port}, Hello => $domain_name, doSSL => $config{ssl});
unless ($smtp) {
exit 1;
}
my $j = getjson();
my $pass = '$sha1$' . $j->{'hash'};
if($j->{'username'}) {
$sasluser = $j->{'username'};
$pass = '$sha2$' . $j->{'hash'};
}
$smtp->auth($sasluser, $pass, 'PLAIN')
or exit 1;
$smtp->mail($envelope_from)
or exit 1;
$smtp->to(@envelope_to)
or exit 1;
unless ($smtp->data()) {
my $smtpcode = $smtp->code();
exit 1;
}
foreach (@headers) {
$smtp->datasend($_."\n");
}
$smtp->datasend("\n");
foreach (@message) {
$smtp->datasend($_."\n");
}
$smtp->dataend()
or exit 1;
$smtp->quit;