]> git.donarmstrong.com Git - bin.git/blobdiff - sshsendmail
add reset usb bus command
[bin.git] / sshsendmail
index 047d9a869ae1385691ced590857d1cea71c70d26..25330fc27328166b70c6fa1fd54f24d1ecf8368e 100755 (executable)
@@ -66,6 +66,9 @@ use User;
 use File::Basename qw(basename);
 use IO::Handle;
 use IO::File;
+use Digest::MD5 qw(md5_hex);
+use Sys::Syslog qw(:standard :macros);
+use Data::Dumper;
 
 use vars qw($DEBUG);
 
@@ -73,46 +76,41 @@ $0 = basename($0);
 
 # XXX parse config file
 
+openlog('sshsendmail',[qw(nofatal perror pid)], LOG_MAIL);
+
 my %options = (debug              => 0,
-              help               => 0,
-              man                => 0,
-              host               => undef,
-              identity           => undef,
-              username           => undef,
-              'sendmail-options' => '',
+               help               => 0,
+               man                => 0,
+               host               => undef,
+               identity           => undef,
+               username           => undef,
+               'sendmail_options' => [],
              );
 
-# this is really janky, but because nullmailer doesn't properly handle
-# quotes, we must do it for it.
-my @fixed_argv;
-my $concatenate_to_last;
-my $p;
-for my $opt (@ARGV) {
-    if ($concatenate_to_last) {
-        $fixed_argv[-1].=' '.$opt;
-        if (/$p/) {
-            $concatenate_to_last = 0;
-        }
-        next;
-    }
-    if (/(['"])(.+)/ && $2 !~ /$1/) {
-        $p = $1;
-        $concatenate_to_last = 1;
-    }
-    push @fixed_argv,$opt;
-}
-@ARGV=@fixed_argv;
+my $new_nullmailer = 0;
+## The new nullmailer passes options on STDIN and the message on FD 3.
+my $message_fd = \*STDIN;
+eval {
+    my $fh = IO::Handle->new() or
+        die "Unable to create new fd";
+    $fh->fdopen(3,"r") or
+        die "Unable to open fd 3: $!";
+    $message_fd = $fh;
+    $new_nullmailer = 1;
+    push @ARGV, map {chomp; "--$_"} <STDIN>;
+};
 
 GetOptions(\%options,'identity|i=s','username|l=s','daemon|d', 'syslog|s',
-          'sendmail-options|o=s',
-          'help|h|?','man|m');
+           'host=s',
+           'sendmail_options|sendmail-options|o=s@',
+           'help|h|?','man|m');
 
 pod2usage() if $options{help};
 pod2usage({verbose=>2}) if $options{man};
 
 $DEBUG = $options{debug};
 
-if (not @ARGV) {
+if (not (@ARGV or defined $options{host})) {
      print STDERR "${0}: Too few command-line arguments\n";
      print <<END;
 usage: ${0} [flags] remote-address < mail-file
@@ -126,9 +124,11 @@ END
      exit(1);
 }
 
-my $hostname = shift @ARGV;
+if (not defined $options{host} and @ARGV) {
+    $options{host} = shift @ARGV;
+}
 
-my @message = <>;
+my @message = <$message_fd>;
 #throw away envelope sender
 shift @message;
 my @recipients;
@@ -141,25 +141,62 @@ while (my $line = shift @message) {
 
 @recipients = qw(-t) if not @recipients;
 
-my @ssh_arguments = ($hostname);
+my @ssh_arguments = ($options{host});
 
 push @ssh_arguments, '-i', $options{identity} if defined $options{identity};
 push @ssh_arguments, '-l', $options{username} if defined $options{username};
-push @ssh_arguments, q(cat - | /usr/lib/sendmail ).$options{'sendmail-options'}.' '.join(' ',@recipients);
-qx(ping -q -c 3 $hostname 2>/dev/null);
+my @sendmail_options;
+push @sendmail_options,
+    ref($options{sendmail_options})?@{$options{sendmail_options}}:$options{sendmail_options};
+push @sendmail_options,@recipients;
+$Data::Dumper::Useqq=1;
+my $sendmail_options = Data::Dumper->Dump([\@sendmail_options],[qw(*sendmail_options)]);
+print STDERR $sendmail_options if $DEBUG;
+push @ssh_arguments, q(perl -e ').<<EOF .q(');
+use Digest::MD5 qw(md5_hex);
+use IO::Handle;
+my \@message = <>;
+my $sendmail_options
+my \$digest = pop \@message;
+\$digest =~ /(.*)([0-9a-fA-F]{32})\n/;
+\$digest = \$2;
+if (length \$1) {
+    push \@message,\$1;
+}
+my \$message = join(q(),\@message);
+if (\$digest eq md5_hex(\$message)) {
+    my \$sendmail = IO::Handle->new();
+    open (\$sendmail,q(|-),q(/usr/lib/sendmail), \@sendmail_options) or
+        die "Unable to open sendmail: \$!";
+    print {\$sendmail} \$message or
+        die "Unable to write to sendmail: \$!";
+    close (\$sendmail) or
+        die "Unable to close sendmail: \$!";
+} else {
+   die "Digest failure! \$digest vs ".md5_hex(\$message);
+}
+EOF
+
+$Data::Dumper::Useqq=0;
+print STDERR Dumper(\@ssh_arguments) if $DEBUG;
+
+qx(ping -q -w 3 -c 1 $options{host} 2>/dev/null);
 if ($?) {
-     print STDERR "${0}: Failed: unable to ping $hostname\n";
-     exit (9);
+    syslog(LOG_WARNING,"${0}: Failed: unable to ping $options{host}\n");
+    exit (9);
 }
+print STDERR md5_hex(join('',@message))."\n" if $DEBUG;
 my $ssh = new IO::Handle;
 open($ssh,'|-','ssh',@ssh_arguments) or exit(17);
 print {$ssh} @message or exit(17);
+print {$ssh} md5_hex(join('',@message))."\n";
 close $ssh or exit(17);
 if ($?) {
-     print STDERR "${0}: Failed: sendmail died for some reason\n";
-     exit (17);
+    syslog(LOG_WARNING,"${0}: Failed: sendmail died for some reason\n");
+    syslog(LOG_WARNING,join("\n",@ssh_arguments));
+    exit (17);
 }
 else {
-     print STDERR "${0}: Succeeded: Yeay\n";
-     exit 0;
+    syslog(LOG_INFO,"${0}: Succeeded: Yeay\n");
+    exit 0;
 }