head	1.15;
access;
symbols;
locks; strict;
comment	@# @;


1.15
date	97.03.18.03.49.17;	author david;	state Exp;
branches;
next	1.14;

1.14
date	97.03.18.03.29.24;	author david;	state Exp;
branches;
next	1.13;

1.13
date	96.12.16.18.44.45;	author david;	state Exp;
branches;
next	1.12;

1.12
date	96.12.11.03.05.03;	author david;	state Exp;
branches;
next	1.11;

1.11
date	96.12.11.02.59.04;	author david;	state Exp;
branches;
next	1.10;

1.10
date	96.12.09.04.32.05;	author david;	state Exp;
branches;
next	1.9;

1.9
date	96.12.08.02.56.38;	author david;	state Exp;
branches;
next	1.8;

1.8
date	96.12.08.02.55.19;	author david;	state Exp;
branches;
next	1.7;

1.7
date	96.12.08.02.54.01;	author david;	state Exp;
branches;
next	1.6;

1.6
date	96.12.08.02.43.11;	author david;	state Exp;
branches;
next	1.5;

1.5
date	96.11.25.23.50.50;	author david;	state Exp;
branches;
next	1.4;

1.4
date	96.11.25.16.36.23;	author david;	state Exp;
branches;
next	1.3;

1.3
date	96.11.25.16.32.26;	author david;	state Exp;
branches;
next	1.2;

1.2
date	96.11.23.05.21.22;	author david;	state Exp;
branches;
next	1.1;

1.1
date	96.09.01.12.14.08;	author david;	state Exp;
branches;
next	;


desc
@Initial Version.
@


1.15
log
@Fixed to use standard qmail control file rather than Linux-specific one.
@
text
@#! /usr/bin/perl
# QMAIL2SMTP server
#
# This program waits on the defined port and takes user name and md5 hash
# passwords similarly to the RFC-1725 APOP command. If it matches the password
# defined for the user in the apop password file then it starts up MAILDIR2SMTP
# to the calling IP address.
#
# $Log: qsmtpd,v $
# Revision 1.14  1997/03/18 03:29:24  david
# Fixed the security-by-obscurity bug where anyone that could read the
# encrypted password on the server side could freely download e-mail.
# Extended the password control file to include the Maildir being delivered
# out of.
#
# Revision 1.13  1996/12/16 18:44:45  david
# Fixed to automatically determine Linux vs. Solaris.
# Fixed to eliminate duplicate e-mail by waiting synchronously for
# maildir2smtp to finish.
# Fixed to clean up defunct(zombie) processes.
# Also now reports maildir2smtp messages to client side.
#
# Revision 1.12  1996/12/11 03:05:03  david
# Fixed to wait forever after initial handshake so big files can
# be transmitted.
#
# Revision 1.11  1996/12/11 02:59:04  david
# Fixed to not put maildir2smtp in the background as that can cause
# duplicate e-mail if the script is called again while the first one
# is sending e-mail.
#
# Revision 1.10  1996/12/09 04:32:05  david
# Fixed to work with both Linux and Solaris.
#
# Revision 1.9  1996/12/08 02:56:38  david
# Fixed name of program logged to logfile.
#
# Revision 1.8  1996/12/08 02:55:19  david
# Forgot to debug error line!!!
#
# Revision 1.7  1996/12/08 02:54:01  david
# Forgot to debug two print lines.
#
# Revision 1.6  1996/12/08 02:43:11  david
# Completely rewrote to use APOP RFC-1725 password hashes.
# Also simplified the protocol.
#
# Revision 1.5  1996/11/25 23:50:50  david
# Added logging.
#
# Revision 1.4  1996/11/25 16:36:23  david
# First server code that should work.
#
# Revision 1.3  1996/11/25 16:32:26  david
# First shot at portable PERL code.
#

use Socket;
#use Sys::Hostname;

$debug = 0;
$DEFAULT_PORT = 1234;

$mach = `uname -s`; chop $mach;
if ( $mach eq "Linux" )
   { # Linux
   $MD5SUM_PATH="/usr/bin/md5sum";
   $ECHO="/bin/echo -n"; # Linux
   }
 else
   {
   # Solaris
   $ECHO="/usr/ucb/echo -n";
   $MD5SUM_PATH="/usr/local/bin/md5sum";
   }

( $port, $passfile ) = @@ARGV;
$port = $DEFAULT_PORT unless $port;
$passfile = "/var/qmail/control/passwords" unless $passfile;

$myhost = `hostname`;
chop $myhost;
$sockaddr = 'S n a4 x8';

printf "System = $myhost\n" if $debug;

#($name, $aliases, $proto) = getprotobyname( 'tcp' );
#if ($port !~ /^\d_$/)
#   {
#   ($name, $aliases, $port) = getservbyport( $port, 'tcp' );
#   }

printf "Port = $port\n" if $debug;

$this = pack( $sockaddr, AF_INET, $port, "\0\0\0\0" );

select( NS ); $| = 1; select(STDOUT); # Unbuffered I/O

$proto = getprotobyname( 'tcp' );
socket( S, AF_INET, SOCK_STREAM, $proto) || die "socket: $!";
bind( S, $this) || die "bind: $!";
listen( S, 5 ) || die "connect: $!";

select( S ); $| = 1; select( STDOUT ); # Unbuffered I/O

for ( $con = 1; ; $con++ )
   {
   printf( "Listening for connection %d.....\n", $con ) if $debug; 
   ($addr = accept( NS, S ) ) || die $!;

   if ( ($child = fork()) == 0 )
      {
      ($af, $port, $inetaddr) = unpack( $sockaddr, $addr );
      @@inetaddr = unpack( 'C4', $inetaddr);
      $inetaddr = join( '.', @@inetaddr );
      printf "$con: $inetaddr\n" if $debug;

      $pid = $$;
      $time = time;
      printf "+OK <$pid.$time\@@$myhost> QSMTPD (APOP-RFC1725)\n" if $debug;
      printf NS "+OK <$pid.$time\@@$myhost> QSMTPD (APOP-RFC1725)\r\n";

      alarm( 180 );

      $_ = <NS>; chop; chop;
      printf "$_\n" if $debug;
      ($loginid, $inpass) = split( ' ' );
      #printf "Login ID = '$loginid' Input Pass='$inpass'\n" if $debug;

      #openlog( 'smtpsend', 'cons', 'user');
      #syslog( 'mail', "Connection from %s@@%s", $loginid, $inetaddr);
      #closelog();

      open( LOG, "|logger -p mail.info -t qsmtpd" ) || die "Can't start logger.";
      printf( LOG "Connect from $loginid\@@$inetaddr" );
      close LOG;

      if ( $loginid eq "" || $inpass eq "" )
         {
         printf NS "-ERR Bad Login\r\n";
         goto shut;
         }

      open( PASS, "<$passfile" ) || die "Can't open $passfile.";
      while ( ($_ = <PASS> ) && ($luser ne $loginid) )
         {
         chop;
         ($lhost, $luser, $lpass, $dir) = split ":";
         }
      close( PASS );

      if ( $luser ne $loginid )
         {
         printf NS "-ERR Bad Login\r\n";
         goto shut;
         }

      $md5clear = "<$pid.$time\@@$myhost>" . $lpass;
      $md5pass  = &md5sum( $md5clear );

      printf "Name = $loginid, Passwd = $lpass, Maildir = $dir\n" if $debug;
      printf "Md5clear = $md5clear\n" if $debug;
      printf "Md5pass = $md5pass\n" if $debug;


      if ( $md5pass ne $inpass )
         {
         printf NS "-ERR Bad Login\r\n";
         printf "-ERR Bad Login\n" if $debug;
         goto shut;
         }


      alarm( 0 ); # Now wait forever....

      printf NS "+OK /var/qmail/bin/maildir2smtp $dir $loginid- $inetaddr $myhost\r\n";
      printf "+OK /var/qmail/bin/maildir2smtp $dir $loginid- $inetaddr $myhost\n" if $debug;
      open( PIPE,  "/var/qmail/bin/maildir2smtp $dir $loginid- $inetaddr $myhost 2>&1 |" );
      while ( <PIPE> )
         {
         chop;
         printf NS "$_\r\n";
         printf "$_\n" if $debug;
         }

      close( PIPE );

      printf NS "+FINISHED\r\n";
      printf "+FINISHED\n" if $debug;

      shut:
         {
         close( NS );
         }
      exit;
      }
    else
      {
      waitpid( -1, WNOHANG );
      }
   }

sub md5sum
{
$_ = `$ECHO "$_[0]" | $MD5SUM_PATH`;
chop;
($_, $junk) = split ' ';
return $_;
}
@


1.14
log
@Fixed the security-by-obscurity bug where anyone that could read the
encrypted password on the server side could freely download e-mail.
Extended the password control file to include the Maildir being delivered
out of.
@
text
@d10 6
d79 1
a79 1
$passfile = "/etc/qmail/control/passwords" unless $passfile;
@


1.13
log
@Fixed to automatically determine Linux vs. Solaris.
Fixed to eliminate duplicate e-mail by waiting synchronously for
maildir2smtp to finish.
Fixed to clean up defunct(zombie) processes.
Also now reports maildir2smtp messages to client side.
@
text
@d5 3
a7 2
# passwords similarly to the RFC-1725 APOP command. If it matches then it
# starts up MAILDIR2SMTP to the calling IP address.
d10 7
d71 1
a71 1
($port) = @@ARGV;
d73 1
d134 1
a134 1
         printf NS "-ERR\r\n";
d138 7
a144 1
      ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell) = getpwnam( $loginid );
d146 1
a146 1
      if ( $name eq "" )
d148 1
a148 1
         printf NS "-ERR\r\n";
d152 1
a152 1
      $md5clear = "<$pid.$time\@@$myhost>" . $passwd;
d155 1
a155 1
      printf "Name = $name, Passwd = $passwd, Homedir = $dir\n" if $debug;
d162 2
a163 2
         printf NS "-ERR\r\n";
         printf "-ERR\n" if $debug;
d170 3
a172 3
      printf NS "+OK /var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost\r\n";
      printf "+OK /var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost\n" if $debug;
      open( PIPE,  "/var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost 2>&1 |" );
@


1.12
log
@Fixed to wait forever after initial handshake so big files can
be transmitted.
@
text
@d9 4
a46 8

# Linux
$MD5SUM_PATH="/usr/bin/md5sum";
$ECHO="/bin/echo -n"; # Linux
# Solaris
#$ECHO="/usr/ucb/echo -n";
#$MD5SUM_PATH="/usr/local/bin/md5sum";

d50 13
a65 1

d157 12
a168 1
      system "/var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost";
d175 4
@


1.11
log
@Fixed to not put maildir2smtp in the background as that can cause
duplicate e-mail if the script is called again while the first one
is sending e-mail.
@
text
@d9 5
d143 3
@


1.10
log
@Fixed to work with both Linux and Solaris.
@
text
@d1 1
a1 1
#! /usr/local/bin/perl
d9 3
a138 1
      system "/var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost &";
d141 1
@


1.9
log
@Fixed name of program logged to logfile.
@
text
@d9 3
d35 8
a44 2
$MD5SUM_PATH="/usr/bin/md5sum";
$ECHO="/bin/echo -n";
d152 1
@


1.8
log
@Forgot to debug error line!!!
@
text
@d9 3
d94 1
a94 1
      open( LOG, "|logger -p mail.info -t smtpsend" ) || die "Can't start logger.";
@


1.7
log
@Forgot to debug two print lines.
@
text
@d9 3
d120 1
a120 1
         printf "-ERR\n";
@


1.6
log
@Completely rewrote to use APOP RFC-1725 password hashes.
Also simplified the protocol.
@
text
@d8 5
a12 1
# $Log$
d74 1
a74 1
      printf "+OK <$pid.$time\@@$myhost> QSMTPD (APOP-RFC1725)\n";
d80 1
a80 1
      printf "$_\n";
@


1.5
log
@Added logging.
@
text
@d4 8
a11 1
# $Log: smtpsend,v $
d20 1
a20 1
use Sys::Hostname;
d22 1
d24 2
a25 1
$debug = 0;
d31 2
a32 1
$myhost = hostname();
d35 1
a35 1
print "System = $myhost\n" if $debug;
d43 1
a43 1
print "Port = $port\n" if $debug;
d47 1
a47 1
select( NS); $| = 1; select(STDOUT);
d54 1
a54 1
select( S ); $| = 1; select( STDOUT );
a62 2
      printf "accept ok\n" if $debug;

d66 1
a66 1
      print "$con: $inetaddr\n" if $debug;
d68 11
a78 6
      printf NS "Login: ";
      $loginid = <NS>; chop $loginid; chop $loginid;
      print "Login ID = '$loginid'\n" if $debug;

      printf NS "Password: ";
      $pass = <NS>; chop $pass; chop $pass;
a83 1

d88 1
a88 1
      if ( $loginid eq "" && $pass eq "" )
d90 1
a90 1
         printf NS "finished\n";
d98 1
a98 1
         printf NS "finished\n";
d102 2
a103 1
      $salt = substr( $passwd, 0, 2 );
d106 2
d109 2
a110 1
      if ( $passwd ne crypt( $pass, $salt ) )
d112 2
a113 1
         printf NS "finished\n";
d117 3
a119 6
      printf NS "ACCEPTED\n";
      printf "ACCEPTED\n" if $debug;
      printf NS "/var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost\n";
      printf "/var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost\n" if $debug;
      system "/var/qmail/bin/maildir2smtp $dir $name- $inetaddr $myhost";
      printf NS "finished\n";
d128 7
@


1.4
log
@First server code that should work.
@
text
@d5 3
d13 1
d21 2
a22 1
$myhost = `hostname`;
d27 1
a27 1
#($name, $aliases, $prot) = getprotobyname( 'tcp' );
d66 9
@


1.3
log
@First shot at portable PERL code.
@
text
@d4 6
a9 1
# $Log$
a16 2
$AF_INET = 2;
$SOCK_STREAM = 1;
d30 1
a30 1
$this = pack( $sockaddr, $AF_INET, $port, "\0\0\0\0" );
d32 1
a32 1
select( NS); $| = 1; select(stdout);
d34 2
a35 1
socket( S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!";
d39 1
a39 1
select( S ); $| = 1; select( stdout );
d64 1
a64 1
         printf NS "Invalid\n";
d72 1
a72 1
         printf NS "Invalid\n";
d82 1
a82 1
         printf NS "Invalid\n";
@


1.2
log
@Fixed to user remoteip instead of shell hackery.
@
text
@d1 95
a95 7
#! /bin/sh
# $Id: smtpsend,v 1.1 1996/09/01 12:14:08 david Exp david $
cd
host=`/usr/local/bin/remoteip`
echo $HOME "$USER"- $host `hostname`
/var/qmail/bin/maildir2smtp $HOME "$USER"- $host `hostname`
echo finished
@


1.1
log
@Initial revision
@
text
@d2 1
a2 1
# $Id$
d4 3
a6 6
u=`who -m | (read user j2; echo $user)`
h1=`who -m | (read j1 j2 j3 j4 j5 host j7; echo $host)`
h2=`echo $h1 | sed -e 's/(//' -e 's/)//'`
h3=`/usr/local/bin/host $h2 | (read j1 j2 j3 ip j5; echo $ip)`
echo $HOME "$u"- $h3 `hostname`
/var/qmail/bin/maildir2smtp $HOME "$u"- $h3 `hostname`
@
