+++ /dev/null
-#!/usr/bin/perl
-#--------------------------------------------------------------------------------#
-# PROGRAM: gmailsmtp.pl #
-# This program was designed to act as a proxy SMTP server on a #
-# linux system that relays its outbound mail through a gmail #
-# account via HTTPS. #
-# #
-# Copyright (C) 2005 Frederik Vanrenterghem #
-# #
-# 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; either version 2 #
-# of the License, or (at your option) any later version. #
-# #
-# 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.#
-# #
-# CREATED: 2005/05/21 by Frederik Vanrenterghem <frederik@vanrenterghem.biz> #
-# #
-# VERSION: 0.1.0 #
-# #
-# CREDITS: James C. Specht, Jr. <james.specht@gmail.com> #
-# For his gsr.pl v.0.8.0, which supplied the majority #
-# of the code for v.0.1.0 #
-# #
-#--------------------------------------------------------------------------------#
-
-use Mail::Webmail::Gmail;
-use Net::SMTP::Server;
-use Net::SMTP::Server::Client;
-use IO::Socket::INET;
-use IO::Socket::SSL;
-use Net::SSLeay;
-use Digest::HMAC_MD5 qw(hmac_md5_hex);
-use MIME::Base64 qw(encode_base64 decode_base64);
-use Getopt::Long;
-use Term::ReadKey;
-use Proc::Daemon;
-use Sys::Syslog;
-
-$SIG{CHLD} = 'IGNORE';
-
-my ($configfile,$ehlo_ok,$from,@to,$msgsrc,$dohelp,$sock,$code,$text,$more,
- %features,$server,$conn,$verbose,$version,$daemon,$relayfile,@relayIP,
- $pidfile,$client);
-
-$configfile="/usr/local/etc/gmailsmtp.conf";
-$relayfile="/usr/local/etc/gmailsmtp.relay";
-$pidfile="/usr/local/var/run/gmailsmtp.pid";
-$verbose=0;
-$daemon=0;
-$version="0.1.0";
-
-# Get command line options.
-GetOptions ('config-file=s' => \$configfile,
- 'relay-file=s' => \$relayfile,
- 'verbose:1' => \$verbose,
- 'daemon:1' => \$daemon,
- 'help:1' => \$dohelp );
-
-require "$configfile";
-
-if ($dohelp == 1 ) {&usage();}
-
-# Force this process out as a daemon.
-if ($daemon >= 1) {
- Proc::Daemon::Init;
- # Since we are a daemon process log to syslog facility.
- openlog('gmailsmtp','pid','mail');
- syslog('info','gmailsmtp.pl daemon process loading');
- $verbose=0;
- # Write our pid out.
- open(FPID, ">$pidfile");
- print FPID "$$";
- close(FPID);
-}
-
-$ehlo_ok = 1;
-
-if ($gmailserver =~ /^(.*):(.*)$/) {
- $gmailserver = $1;
- $gmailport = $2;
-}
-
-if ($daemon >= 1)
- { syslog('info',"Gmail relay set to $gmailserver:$gmailport"); }
-
-if (!defined ($gmailusername)) {
- dienice ("Missing \$gmailusername in $configfile!");
-}
-
-syslog('info',"Gmail user account is $gmailusername") if ($daemon >= 1);
-
-if ($gmailpassword eq "") {
- # We are a daemon so we can't asked for the gmail account password!
- if ($daemon >= 1) {
- syslog('info',"Missing \$gmailpassword in $configile!");
- syslog('info','Aborting startup!');
- exit;
- }
- printf ("Enter password for %s : ", $gmailusername);
- # Set echo off.
- ReadMode (2);
- $gmailpassword = <>;
- # Restore echo.
- ReadMode (0);
- printf ("\n");
-
- exit if (! defined ($gmailpassword));
- chop ($gmailpassword);
-}
-
-# Build the relayIP table
-BuildRelayIPTable();
-
-&StartSMTPServer();
-closelog();
-exit();
-
-sub StartSMTPServer
-{
- my $i, $IPaddr, $size, $nrcpt;
-
- $server = new Net::SMTP::Server($localserver,$localport) ||
- dienice ("Unable to start SMTP Server on $localserver:$localport!");
-
- while($conn = $server->accept()) {
- printf("\nNew connection!\n\n") if ($verbose >= 1);
-
- my $pid = fork();
-
- if ($pid) {undef($conn);} # this is the parent process
- dienice ("Can't create child process!") unless defined $pid;
- unless($pid) { # $pid == 0 means we're the child
-
- $client = new Net::SMTP::Server::Client($conn) ||
- dienice ("Unable to start SMTP client connection!");
-
- # Capture the IP address of our client.
- $IPaddr = $client->{SOCK}->peerhost();
-
- syslog('info',"Incoming connection from [$IPaddr]") if ($daemon >= 1);
- printf("\nConnection from [$IPaddr]\n") if ($verbose >= 1);
-
- # Do we allow this IP to relay through us?
- if (AllowRelay($IPaddr) == 0) {
- warnnice("Connection refused to [$IPaddr]");
- }
-
- if ($client->process) {
- if ($verbose >= 1 ) {
- printf("MAIL FROM: $client->{FROM}\n");
- for ($i=0; $i <= $#client->{TO}; $i++) {
- printf("RCPT TO: $client->{TO}[i]\n");
- }
- printf("DATA:\n\n$client->{MSG}\n");
- }
- # Now relay the msg on.
- $from = $client->{FROM};
- for ($i=0; $i <= $#client->{TO}; $i++)
- { $to[$i] = $client->{TO}[$i];}
- $msgsrc = $client->{MSG};
-
- if ($daemon >= 1) {
- $size = length($msgsrc);
- $nrcpt = $#to + 1;
- syslog('info',"from=$from, size=$size, nrcpt=$nrcpt");
- for ($i=0; $i <= $#to; $i++)
- { syslog('info',"to=$to[$i]"); }
- }
-
- printf("Relay via GMail account $gmailusername...\n") if ($verbose >= 1);
- if ($daemon >= 1)
- { syslog('info',"relay via GMail account $gmailusername"); }
-
- &RelayOurMSG();
- #$client->shutdown;
- exit 1;
- }
- }
- undef $client;
- }
-}
-
-sub RelayOurMSG
-{
-###nieuw vanaf hier
-if ($verbose >= 1)
- {printf("Connecting to GMail...\n");}
- my ( $gmail ) = Mail::Webmail::Gmail->new(
- username => $gmailusername, password => $gmailpassword, proxy_name=> $proxy_name, );
-
-if ($verbose >= 1)
- {printf("Connection to Gmail established.\n");}
-
-if ($verbose >= 1)
- {printf("Attempting to send message.\n");}
-
- my $msgid = $gmail->send_message
- ( to => $to[0],
- subject => time(),
- msgbody => $msgsrc );
- print "Msgid: $msgid\n";
- if ( $msgid ) {
- if ( $gmail->error() ) {
- if ($verbose >= 1)
- {printf("We ran into a problem. Attempting to display the problem...\n");}
- print $gmail->error_msg();
- } else {
- ### Create new label ###
- if ($verbose >= 1)
- {printf("Creating new label\n");}
- my $test_label = "tl_" . time();
- $gmail->edit_labels( label => $test_label, action => 'create' );
- if ( $gmail->error() ) {
- print $gmail->error_msg();
- } else {
- ### Add this label to our new message ###
- $gmail->edit_labels( label => $test_label, action => 'add', 'msgid' => $msgid );
- if ( $gmail->error() ) {
- print $gmail->error_msg();
- } else {
- print "Added label: $test_label to message $msgid\n";
- }
- }
- }
- }
-###tot hier
-
- # Good bye...
- if ($verbose >= 1)
- {printf("Message sent succesfully.\n");}
- if ($daemon >= 1) {
- syslog('info',"Message relay successful");
- }
-}
-
-# This is the main SMTP "engine".
-sub run_smtp
-{
-
-
- # We can do a relay-test now if a recipient was set.
- if ($#to >= 0) {
- if (!defined ($from)) {
- $from = "<$gmailusername>";
- if ($verbose >= 1)
- {printf("From: address not set. Using $gmailusername.\n");}
- if ($daemon >= 1)
- {syslog('info',"From: address not set. Using $gmailusername.");}
- }
- &send_line ($sock, "MAIL FROM: %s\n", $from);
- ($code, $text, $more) = &get_line ($sock);
- if ($code != 250) { warnnice ("MAIL FROM failed: '$code $text'\n"); }
-
- my $i;
- for ($i=0; $i <= $#to; $i++) {
- &send_line ($sock, "RCPT TO: %s\n", $to[$i]);
- ($code, $text, $more) = &get_line ($sock);
- if ($code != 250) {
- warnnice ("RCPT TO ".$to[$i]." "."failed: '$code $text'\n");
- }
- }
- }
-
- # Wow, we should even send something!
- if (defined ($msgsrc))
- {
- &send_line ($sock, "DATA\n");
- ($code, $text, $more) = &get_line ($sock);
- if ($code != 354) { warnnice ("DATA failed: '$code $text'\n"); }
-
- if ($verbose >= 1) {
- printf("Sending the following.\n\n");
- printf("$msgsrc\n");
- }
-
- $sock->printf ("$msgsrc\r\n.\r\n");
-
- ($code, $text, $more) = &get_line ($sock);
- if ($code != 250) { warnnice ("DATA not sent: '$code $text'\n"); }
- }
-
- # Perfect. Everything succeeded!
- return 1;
-}
-
-# Get one line of response from the server.
-sub get_line ($)
-{
- my $sock = shift;
- my ($code, $sep, $text) = ($sock->getline() =~ /(\d+)(.)([^\r]*)/);
- my $more;
- if ($sep eq "-") { $more = 1; } else { $more = 0; }
- printf ("[%d] '%s'\n", $code, $text) if ($verbose >= 1);
- return ($code, $text, $more);
-}
-
-# Send one line back to the server
-sub send_line ($@)
-{
- my $socket = shift;
- my @args = @_;
-
- printf ("> ") if ($verbose >= 1);
- printf (@args) if ($verbose >= 1);
- $socket->printf (@args);
-}
-
-# Helper function to encode CRAM-MD5 challenge
-sub encode_cram_md5 ($$$)
-{
- my ($ticket64, $username, $password) = @_;
- my $ticket = decode_base64($ticket64) or
- dienice ("Unable to decode Base64 encoded string '$ticket64'");
-
- my $password_md5 = hmac_md5_hex($ticket, $password);
- return encode_base64 ("$username $password_md5", "");
-}
-
-# Store all server's ESMTP features to a hash.
-sub say_hello ($$$$)
-{
- my ($sock, $ehlo_ok, $gmailhello, $featref) = @_;
- my ($feat, $param);
- my $hello_cmd = $ehlo_ok ? "EHLO" : "HELO";
-
- &send_line ($sock, "$hello_cmd $gmailhello\n");
- my ($code, $text, $more) = &get_line ($sock);
-
- if ($code != 250) { warnnice ("$hello_cmd failed: '$code $text'\n"); }
-
- # Empty the hash
- %{$featref} = ();
-
- ($feat, $param) = ($text =~ /^(\w+)[= ]*(.*)$/);
- $featref->{$feat} = $param;
-
- # Load all features presented by the server into the hash
- while ($more == 1) {
- ($code, $text, $more) = &get_line ($sock);
- ($feat, $param) = ($text =~ /^(\w+)[= ]*(.*)$/);
- $featref->{$feat} = $param;
- }
-
- return 1;
-}
-
-sub warnnice {
- my ($txt) = @_;
-
- if ( $daemon >= 1 ) {
- syslog('info', $txt);
- syslog('info', 'Connection terminated!');
- }
- else {
- printf("\n$txt\n");
- printf("Connection terminated!\n");
- }
- if ($sock) {
- printf("Shutdown!!!!!\n");
- &send_line ($sock, "QUIT\n");
- }
- if ($client) { $client->shutdown;}
- exit 1;
-}
-
-sub dienice {
- my ($txt) = @_;
-
- if ( $daemon >= 1 ) {
- syslog('info', $txt);
- syslog('info',"Aborting");
- }
- else {
- printf("\n$txt\n");
- printf("Aborting\n\n");
- }
- if ($client) {$client->shutdown;}
- exit 1;
-}
-
-sub AllowRelay($) {
-
- my $IP = shift;
- my $i;
-
- for ($i=0; $i <= $#relayIP; $i++) {
- if ($IP =~ /^$relayIP[$i]/) { return "1";}
- }
-
- # Did not find a match.
- return "0";
-}
-
-sub BuildRelayIPTable {
-
- my ($i);
-
- $i=0;
-
- if ($verbose >= 1) { printf("Loading relay table from $relayfile\n");}
- if ($daemon >= 1) { syslog('info',"Loading relay table from $relayfile");}
-
- open(INFILE, "$relayfile") || dienice("Cannot open relay file $relayfile!");
- while($line = <INFILE>) {
- $line =~ s/#.*//; # ignore comments by erasing them
- next if $line =~ /^(\s)*$/; # skip blank lines
- chomp($line);
- if ($verbose >= 1) { printf("Adding [$line] to relay table\n");}
- if ($daemon >= 1) {syslog('info',"Adding [$line] to relay table");}
-
- $relayIP[$i++] = $line;
- }
- close(INFILE);
-}
-
-sub usage ()
-{
- printf ("\nA simple SMTP server that relays local email through a gmail account via HTTPS.
-
-Author: Frederik Vanrenterghem <frederik\@vanrenterghem.biz>
- http://vanrenterghem.biz/
-
-Version: $version
-
-Usage: gmailsmtp.pl [--options]
-
- --config-file= The location of the gmailsmtp.conf file.
- (default: /usr/local/etc/gmailsmtp.conf)
- --relay-file= The location of the gmailsmtp.relay file.
- (default: /usr/local/etc/gmailsmtp.relay)
- --verbose Be verbose instead of silent.
- --daemon Start as daemon process.
- --help Shows you this output.
-
-Current Options:
-
- \$gmailserver = [$gmailserver]
- \$gmailport = [$gmailport]
- \$gmailusername = [$gmailusername]\n");
-
- if ($gmailpassword ne "") {
- printf (" \$gmailpassword = [is set]\n");
- } else {
- printf (" \$gmailpassword = [is NOT set]\n");
- }
-
- printf (" \$gmailhello = [$gmailhello]
- \$localserver = [$localserver]
- \$localport = [$localport]
-");
- exit (0);
-}
-
-
\ No newline at end of file