2 # sshsendmail uses ssh to send a mail message to a different machine,
3 # and is released under the terms of the GPL version 2, or any later
4 # version, at your option. See the file README and COPYING for more
6 # Copyright 2005-10 by Don Armstrong <don@donarmstrong.com>.
8 # parse command line options
20 sshsendmail - Uses ssh to send a mail message to a different machine's copy of sendmail.
24 Stick this command in /usr/lib/nullmailer/sshsendmail.
28 foohost.com sshsendmail --identity=/var/mail/.ssh/id_rsa --username remotemail --sendmail-options='-baruser@foohost.com'
30 to /etc/nullmailer/remotes.
33 --identity, -i ssh identity to use to connect to the server
34 --username, -l remote username
35 --sendmail-options, -o options to pass to sendmail
36 --debug, -d debugging level (Default 0)
37 --help, -h display this help
38 --man, -m display manual
44 =item B<--identity, -i>
46 ssh identity to send to the server we're connecting to
50 Debug verbosity. (Default 0)
54 Display brief useage information.
66 use File::Basename qw(basename);
69 use Digest::MD5 qw(md5_hex);
70 use Sys::Syslog qw(:standard :macros);
77 # XXX parse config file
79 openlog('sshsendmail',[qw(nofatal perror pid)], LOG_MAIL);
81 my %options = (debug => 0,
87 'sendmail_options' => [],
90 GetOptions(\%options,'identity|i=s','username|l=s','daemon|d', 'syslog|s',
91 'sendmail_options|sendmail-options|o=s@',
94 pod2usage() if $options{help};
95 pod2usage({verbose=>2}) if $options{man};
97 $DEBUG = $options{debug};
100 print STDERR "${0}: Too few command-line arguments\n";
102 usage: ${0} [flags] remote-address < mail-file
103 Send an email message via ssh+sendmail
104 -p, --port=INT Set the port number on the remote host to connect to
105 -d, --daemon use syslog exclusively (Debian only)
106 -s, --syslog use syslog additionally (Debian only)
108 -h, --help Display this help and exit
113 my $hostname = shift @ARGV;
116 #throw away envelope sender
120 while (my $line = shift @message) {
121 last if $line eq "\n";
123 push @recipients,$line;
126 @recipients = qw(-t) if not @recipients;
128 my @ssh_arguments = ($hostname);
130 push @ssh_arguments, '-i', $options{identity} if defined $options{identity};
131 push @ssh_arguments, '-l', $options{username} if defined $options{username};
132 my @sendmail_options;
133 push @sendmail_options,
134 ref($options{sendmail_options})?@{$options{sendmail_options}}:$options{sendmail_options};
135 push @sendmail_options,@recipients;
136 $Data::Dumper::Useqq=1;
137 my $sendmail_options = Data::Dumper->Dump([\@sendmail_options],[qw(*sendmail_options)]);
138 print STDERR $sendmail_options;
139 push @ssh_arguments, q(perl -e ').<<EOF .q(');
140 use Digest::MD5 qw(md5_hex);
144 my \$digest = pop \@message;
145 \$digest =~ /(.*)([0-9a-fA-F]{32})\n/;
150 my \$message = join(q(),\@message);
151 if (\$digest eq md5_hex(\$message)) {
152 my \$sendmail = IO::Handle->new();
153 open (\$sendmail,q(|-),q(/usr/lib/sendmail), \@sendmail_options) or
154 die "Unable to open sendmail: \$!";
155 print {\$sendmail} \$message or
156 die "Unable to write to sendmail: \$!";
157 close (\$sendmail) or
158 die "Unable to close sendmail: \$!";
160 die "Digest failure! \$digest vs ".md5_hex(\$message);
164 $Data::Dumper::Useqq=0;
165 print STDERR Dumper(\@ssh_arguments);
167 qx(ping -q -c 3 $hostname 2>/dev/null);
169 syslog(LOG_WARNING,"${0}: Failed: unable to ping $hostname\n");
172 print STDERR md5_hex(join('',@message))."\n";
173 my $ssh = new IO::Handle;
174 open($ssh,'|-','ssh',@ssh_arguments) or exit(17);
175 print {$ssh} @message or exit(17);
176 print {$ssh} md5_hex(join('',@message))."\n";
177 close $ssh or exit(17);
179 syslog(LOG_WARNING,"${0}: Failed: sendmail died for some reason\n");
180 syslog(LOG_WARNING,join("\n",@ssh_arguments));
184 syslog(LOG_INFO,"${0}: Succeeded: Yeay\n");