|
From: <jgr...@us...> - 2003-03-03 15:22:24
|
Update of /cvsroot/popfile/engine/Proxy
In directory sc8-pr-cvs1:/tmp/cvs-serv12042/Proxy
Modified Files:
POP3.pm SMTP.pm
Log Message:
Partial and broken work on POPFile refactoring; READ ONLY at this point; do not bother running unless you are very brave
Index: POP3.pm
===================================================================
RCS file: /cvsroot/popfile/engine/Proxy/POP3.pm,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -d -r1.40 -r1.41
*** POP3.pm 26 Feb 2003 04:35:12 -0000 1.40
--- POP3.pm 3 Mar 2003 15:21:46 -0000 1.41
***************
*** 2,8 ****
package Proxy::POP3;
# ---------------------------------------------------------------------------------------------
#
! # This module handles proxying the POP3 protocol for POPFile.
#
# Copyright (c) 2001-2003 John Graham-Cumming
--- 2,11 ----
package Proxy::POP3;
[...1052 lines suppressed...]
! while( 1 ) {
! last unless () = $selector->can_read(0.01);
! last unless ( my $n = sysread( $mail, $buf, $max_length, length $buf ) );
!
! tee( $self, $client, $buf ) if ( $discard != 1 );
! return $buf;
! }
! }
! }
! return '';
! }
--- 411,418 ----
close $client;
close $pipe;
! $self->log_( "POP3 forked child done" );
}
! # TODO echo_response_ that calls echo_response_ with the extra parameters
! # required et al.
Index: SMTP.pm
===================================================================
RCS file: /cvsroot/popfile/engine/Proxy/SMTP.pm,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** SMTP.pm 13 Feb 2003 21:24:17 -0000 1.3
--- SMTP.pm 3 Mar 2003 15:21:48 -0000 1.4
***************
*** 1,8 ****
! # POPFILE LOADABLE MODULE
package Proxy::SMTP;
# ---------------------------------------------------------------------------------------------
#
! # This module handles proxying the SMTP protocol for POPFile.
#
# Copyright (c) 2001-2003 John Graham-Cumming
--- 1,11 ----
! # DISABLED POPFILE LOADABLE MODULE
package Proxy::SMTP;
+ use Proxy::Proxy;
+ @ISA = ("Proxy::Proxy");
+
# ---------------------------------------------------------------------------------------------
#
! # This module handles proxying the SMTP protocol for POPFile.
#
# Copyright (c) 2001-2003 John Graham-Cumming
***************
*** 10,30 ****
# ---------------------------------------------------------------------------------------------
- use IO::Socket;
- use IO::Select;
-
use strict;
use warnings;
use locale;
! # This is used to get the hostname of the current machine
! # in a cross platform way
! use Sys::Hostname;
!
! # A handy variable containing the value of an EOL for Unix systems
my $eol = "\015\012";
- # Constant used by the log rotation code
- my $seconds_per_day = 60 * 60 * 24;
-
#----------------------------------------------------------------------------
# new
--- 13,23 ----
# ---------------------------------------------------------------------------------------------
use strict;
use warnings;
use locale;
! # A handy variable containing the value of an EOL for networks
my $eol = "\015\012";
#----------------------------------------------------------------------------
# new
***************
*** 32,59 ****
# Class new() function
#----------------------------------------------------------------------------
! sub new
{
my $type = shift;
my $self;
-
- # A reference to the POPFile::Configuration module
- $self->{configuration} = 0;
! # A reference to the classifier
! $self->{classifier} = 0;
!
! # The name of the debug file
! $self->{debug_filename} = '';
!
! # The name of the last user to pass through POPFile
! $self->{lastuser} = 'none';
! # Used to tell any loops to terminate
! $self->{alive} = 1;
!
! # Just our hostname
! $self->{hostname} = '';
!
! return bless $self, $type;
}
--- 25,40 ----
# Class new() function
#----------------------------------------------------------------------------
! sub new
{
my $type = shift;
my $self;
! # Must call bless before attempting to call any methods
! bless $self, $type;
!
! $self->name( 'smtp' );
!
! return $self;
}
***************
*** 69,78 ****
my ( $self ) = @_;
- # Start with debugging to file
- $self->{configuration}->{configuration}{debug} = 1;
-
# Default ports for SMTP
$self->{configuration}->{configuration}{smtp_port} = 25;
!
# Where to forward on to
$self->{configuration}->{configuration}{smtp_chain_server} = '';
--- 50,56 ----
my ( $self ) = @_;
# Default ports for SMTP
$self->{configuration}->{configuration}{smtp_port} = 25;
!
# Where to forward on to
$self->{configuration}->{configuration}{smtp_chain_server} = '';
***************
*** 80,187 ****
# Only accept connections from the local machine for smtp
! $self->{configuration}->{configuration}{localsmtp} = 1;
!
! return 1;
! }
!
! # ---------------------------------------------------------------------------------------------
! #
! # start
! #
! # Called when the SMTP interface is allowed to start up
! #
! # ---------------------------------------------------------------------------------------------
! sub start
! {
! my ( $self ) = @_;
!
! # Ensure that the messages subdirectory exists
! mkdir( 'messages' );
!
! # Get the hostname for use in the X-POPFile-Link header
! $self->{hostname} = hostname;
!
! # Open the socket used to receive request for SMTP service
! $self->{server} = IO::Socket::INET->new( Proto => 'tcp',
! $self->{configuration}->{configuration}{localsmtp} == 1 ? (LocalAddr => 'localhost') : (),
! LocalPort => $self->{configuration}->{configuration}{smtp_port},
! Listen => SOMAXCONN,
! Reuse => 1 ) or return 0;
!
! # This is used to perform select calls on the $server socket so that we can decide when there is
! # a call waiting an accept it without having to block
! $self->{selector} = new IO::Select( $self->{server} );
!
! return 1;
! }
!
! # ---------------------------------------------------------------------------------------------
! #
! # stop
! #
! # Called when the SMTP interface must terminate
! #
! # ---------------------------------------------------------------------------------------------
! sub stop
! {
! my ( $self ) = @_;
!
! close $self->{server} if ( defined( $self->{server} ) );
! }
!
! # ---------------------------------------------------------------------------------------------
! #
! # name
! #
! # Called to get the simple name for this module
! #
! # ---------------------------------------------------------------------------------------------
! sub name
! {
! my ( $self ) = @_;
!
! return 'smtp';
! }
!
! # ---------------------------------------------------------------------------------------------
! #
! # service
! #
! # Called to handle SMTP requests
! #
! # ---------------------------------------------------------------------------------------------
! sub service
! {
! my ( $self ) = @_;
!
! # Accept a connection from a client trying to use us as the mail server. We service one client at a time
! # and all others get queued up to be dealt with later. We check the alive boolean here to make sure we
! # are still allowed to operate. See if there's a connection waiting on the $server by getting the list of
! # handles with data to read, if the handle is the server then we're off.
! my ($ready) = $self->{selector}->can_read(0);
!
! # If the $server is ready then we can go ahead and accept the connection
! if ( ( defined($ready) ) && ( $ready == $self->{server} ) ) {
! if ( my $client = $self->{server}->accept() ) {
! # Check that this is a connection from the local machine, if it's not then we drop it immediately
! # without any further processing. We don't want to act as a proxy for just anyone's email
! my ( $remote_port, $remote_host ) = sockaddr_in( $client->peername() );
!
! if ( ( $self->{configuration}->{configuration}{localpop} == 0 ) || ( $remote_host eq inet_aton( "127.0.0.1" ) ) ) {
! # Now that we have a good connection to the client fork a subprocess to handle the communication
! $self->{configuration}->{configuration}{download_count} += 1;
! my $pid = &{$self->{forker}};
!
! # If we fail to fork, or are in the child process then process this request
! if ( !defined( $pid ) || ( $pid == 0 ) ) {
! child( $self, $client, $self->{configuration}->{configuration}{download_count} );
! exit(0) if ( defined( $pid ) );
! }
! }
- close $client;
- }
- }
-
return 1;
}
--- 58,63 ----
# Only accept connections from the local machine for smtp
! $self->{configuration}->{configuration}{smtp} = 1;
return 1;
}
***************
*** 189,218 ****
# ---------------------------------------------------------------------------------------------
#
- # forked
- #
- # Called when someone forks POPFile
- #
- # ---------------------------------------------------------------------------------------------
- sub forked
- {
- my ( $self ) = @_;
-
- close $self->{server};
- }
-
- # ---------------------------------------------------------------------------------------------
- #
- # reaper
- #
- # Called to reap our dead children
- #
- # ---------------------------------------------------------------------------------------------
- sub reaper
- {
- my ( $self ) = @_;
- }
-
- # ---------------------------------------------------------------------------------------------
- #
# child
#
--- 65,68 ----
***************
*** 232,236 ****
# The handle to the real mail server gets stored here
my $mail;
!
# Tell the client that we are ready for commands and identify our version number
tee( $self, $client, "220 SMTP POPFile (v$self->{configuration}->{major_version}.$self->{configuration}->{minor_version}.$self->{configuration}->{build_version}) server ready$eol" );
--- 82,86 ----
# The handle to the real mail server gets stored here
my $mail;
!
# Tell the client that we are ready for commands and identify our version number
tee( $self, $client, "220 SMTP POPFile (v$self->{configuration}->{major_version}.$self->{configuration}->{minor_version}.$self->{configuration}->{build_version}) server ready$eol" );
***************
*** 267,271 ****
}
! if ( ( $command =~ /MAIL FROM:/i ) ||
( $command =~ /RCPT TO:/i ) ||
( $command =~ /VRFY/i ) ||
--- 117,121 ----
}
! if ( ( $command =~ /MAIL FROM:/i ) ||
( $command =~ /RCPT TO:/i ) ||
( $command =~ /VRFY/i ) ||
***************
*** 320,376 ****
# ---------------------------------------------------------------------------------------------
#
- # debug
- #
- # $message A string containing a debug message that may or may not be printed
- #
- # Prints the passed string if the global $debug is true
- #
- # ---------------------------------------------------------------------------------------------
- sub debug
- {
- my ( $self, $message ) = @_;
-
- if ( $self->{configuration}->{configuration}{debug} > 0 ) {
- # Check to see if we are handling the USER/PASS command and if we are then obscure the
- # account information
- $message = "$`$1$3 XXXXXX$4" if ( $message =~ /((--)?)(USER|PASS)\s+\S*(\1)/ );
- chomp $message;
- $message .= "\n";
-
- my $now = localtime;
- my $msg = "$now ($$): $message";
-
- if ( $self->{configuration}->{configuration}{debug} & 1 ) {
- open DEBUG, ">>$self->{debug_filename}";
- binmode DEBUG;
- print DEBUG $msg;
- close DEBUG;
- }
-
- print $msg if ( $self->{configuration}->{configuration}{debug} & 2 );
- }
- }
-
- # ---------------------------------------------------------------------------------------------
- #
- # tee
- #
- # $socket The stream (created with IO::) to send the string to
- # $text The text to output
- #
- # Sends $text to $socket and sends $text to debug output
- #
- # ---------------------------------------------------------------------------------------------
- sub tee
- {
- my ( $self, $socket, $text ) = @_;
-
- # Send the message to the debug output and then send it to the appropriate socket
- debug( $self, $text );
- print $socket $text if $socket->connected;
- }
-
- # ---------------------------------------------------------------------------------------------
- #
# get_response
#
--- 170,173 ----
***************
*** 379,390 ****
# $command The text of the command to send (we add an EOL)
#
! # Send $command to $mail, receives the response and echoes it to the $client and the debug
# output. Returns the response
#
# ---------------------------------------------------------------------------------------------
! sub get_response
{
my ( $self, $mail, $client, $command ) = @_;
!
unless ( $mail ) {
# $mail is undefined - return an error intead of crashing
--- 176,187 ----
# $command The text of the command to send (we add an EOL)
#
! # Send $command to $mail, receives the response and echoes it to the $client and the debug
# output. Returns the response
#
# ---------------------------------------------------------------------------------------------
! sub get_response
{
my ( $self, $mail, $client, $command ) = @_;
!
unless ( $mail ) {
# $mail is undefined - return an error intead of crashing
***************
*** 395,405 ****
# Send the command (followed by the appropriate EOL) to the mail server
tee( $self, $mail, $command. $eol );
!
my $response;
!
# Retrieve a single string containing the response
if ( $mail->connected ) {
$response = <$mail>;
!
if ( $response ) {
# Echo the response up to the mail client
--- 192,202 ----
# Send the command (followed by the appropriate EOL) to the mail server
tee( $self, $mail, $command. $eol );
!
my $response;
!
# Retrieve a single string containing the response
if ( $mail->connected ) {
$response = <$mail>;
!
if ( $response ) {
# Echo the response up to the mail client
***************
*** 411,415 ****
}
}
!
return $response;
}
--- 208,212 ----
}
}
!
return $response;
}
***************
*** 423,434 ****
# $command The text of the command to send (we add an EOL)
#
! # Send $command to $mail, receives the response and echoes it to the $client and the debug
# output. Returns true if the response was +OK and false if not
#
# ---------------------------------------------------------------------------------------------
! sub echo_response
{
my ( $self, $mail, $client, $command ) = @_;
!
# Determine whether the response began with the string +OK. If it did then return 1
# else return 0
--- 220,231 ----
# $command The text of the command to send (we add an EOL)
#
! # Send $command to $mail, receives the response and echoes it to the $client and the debug
# output. Returns true if the response was +OK and false if not
#
# ---------------------------------------------------------------------------------------------
! sub echo_response
{
my ( $self, $mail, $client, $command ) = @_;
!
# Determine whether the response began with the string +OK. If it did then return 1
# else return 0
***************
*** 438,468 ****
# ---------------------------------------------------------------------------------------------
#
- # echo_to_dot
- #
- # $mail The stream (created with IO::) to send the message to (the remote mail server)
- # $client The local mail client (created with IO::) that needs the response
- #
- # echo all information from the $mail server until a single line with a . is seen
- #
- # ---------------------------------------------------------------------------------------------
- sub echo_to_dot
- {
- my ( $self, $mail, $client ) = @_;
-
- while ( <$mail> ) {
- # Check for an abort
- last if ( $self->{alive} == 0 );
-
- print $client $_;
-
- # The termination has to be a single line with exactly a dot on it and nothing
- # else other than line termination characters. This is vital so that we do
- # not mistake a line beginning with . as the end of the block
- last if ( /^\.(\r\n|\r|\n)$/ );
- }
- }
-
- # ---------------------------------------------------------------------------------------------
- #
# verify_connected
#
--- 235,238 ----
***************
*** 476,486 ****
#
# ---------------------------------------------------------------------------------------------
! sub verify_connected
{
my ( $self, $mail, $client, $hostname, $port ) = @_;
!
# Check to see if we are already connected
return $mail if ( $mail && $mail->connected );
!
# Connect to the real mail server on the standard port
$mail = IO::Socket::INET->new(
--- 246,256 ----
#
# ---------------------------------------------------------------------------------------------
! sub verify_connected
{
my ( $self, $mail, $client, $hostname, $port ) = @_;
!
# Check to see if we are already connected
return $mail if ( $mail && $mail->connected );
!
# Connect to the real mail server on the standard port
$mail = IO::Socket::INET->new(
***************
*** 490,505 ****
# Check that the connect succeeded for the remote server
! if ( $mail ) {
if ( $mail->connected ) {
! # Wait 10 seconds for a response from the remote server and if
# there isn't one then give up trying to connect
my $selector = new IO::Select( $mail );
last unless () = $selector->can_read($self->{configuration}->{configuration}{timeout});
!
# Read the response from the real server and say OK
my $buf = '';
my $max_length = 8192;
my $n = sysread( $mail, $buf, $max_length, length $buf );
!
debug( $self, "Connection returned: $buf" );
if ( !( $buf =~ /[\r\n]/ ) ) {
--- 260,275 ----
# Check that the connect succeeded for the remote server
! if ( $mail ) {
if ( $mail->connected ) {
! # Wait 10 seconds for a response from the remote server and if
# there isn't one then give up trying to connect
my $selector = new IO::Select( $mail );
last unless () = $selector->can_read($self->{configuration}->{configuration}{timeout});
!
# Read the response from the real server and say OK
my $buf = '';
my $max_length = 8192;
my $n = sysread( $mail, $buf, $max_length, length $buf );
!
debug( $self, "Connection returned: $buf" );
if ( !( $buf =~ /[\r\n]/ ) ) {
***************
*** 514,518 ****
# Tell the client we failed
tee( $self, $client, "554 Transaction failed failed to connect to $hostname:$port$eol" );
!
return undef;
}
--- 284,288 ----
# Tell the client we failed
tee( $self, $client, "554 Transaction failed failed to connect to $hostname:$port$eol" );
!
return undef;
}
***************
*** 529,536 ****
#
# ---------------------------------------------------------------------------------------------
! sub flush_extra
{
my ( $self, $mail, $client, $discard ) = @_;
!
if ( $mail ) {
if ( $mail->connected ) {
--- 299,306 ----
#
# ---------------------------------------------------------------------------------------------
! sub flush_extra
{
my ( $self, $mail, $client, $discard ) = @_;
!
if ( $mail ) {
if ( $mail->connected ) {
|