Ticket #107: unix_socket.patch

File unix_socket.patch, 11.3 kB (added by amatubu, 10 years ago)

Patch for supporting unix sockets

  • Proxy/Proxy.pm

    old new  
    111111    $self->config_( 'socks_server', '' ); 
    112112    $self->config_( 'socks_port',   1080 ); 
    113113 
     114    # The name of the unix socket used for proxy service 
     115    # If it is '', inet sockets are used. 
     116    # If it is not '', unix sockets are used. 
     117 
     118    $self->config_( 'unix_socket', '' ); 
     119 
    114120    return 1; 
    115121} 
    116122 
     
    128134{ 
    129135    my ( $self ) = @_; 
    130136 
    131     # Open the socket used to receive request for proxy service 
    132     $self->log_( 1, "Opening listening socket on port " . $self->config_('port') . '.' ); 
    133     $self->{server__} = IO::Socket::INET->new( Proto     => 'tcp', # PROFILE BLOCK START 
    134                                     ($self->config_( 'local' ) || 0) == 1 ? (LocalAddr => 'localhost') : (), 
    135                                     LocalPort => $self->config_( 'port' ), 
    136                                     Listen    => SOMAXCONN, 
    137                                     Reuse     => 1 ); # PROFILE BLOCK STOP 
    138  
    139137    my $name = $self->name(); 
     138    my $unix_socket = $self->config_( 'unix_socket' ); 
    140139 
    141     if ( !defined( $self->{server__} ) ) { 
     140    if ( !$unix_socket ) { 
     141 
    142142        my $port = $self->config_( 'port' ); 
    143         print STDERR <<EOM; # PROFILE BLOCK START 
     143        my $local = ( ( $self->config_( 'local' ) || 0 ) == 1 ); 
    144144 
    145 \nCouldn't start the $name proxy because POPFile could not bind to the 
     145        # Open the inet socket used to receive request for proxy service 
     146 
     147        $self->log_( 1, "Opening listening socket for $name proxy on port $port." ); 
     148 
     149        $self->{server__} = IO::Socket::INET->new(  # PROFILE BLOCK START 
     150                Proto     => 'tcp', 
     151                ( $local ? ( LocalAddr => 'localhost' ) : () ), 
     152                LocalPort => $port, 
     153                Listen    => SOMAXCONN, 
     154                Reuse     => 1 
     155        );                                          # PROFILE BLOCK STOP 
     156 
     157        if ( !defined( $self->{server__} ) ) { 
     158            print STDERR <<EOM; # PROFILE BLOCK START 
     159 
     160\nCouldn\'t start the $name proxy because POPFile could not bind to the 
    146161listen port $port. This could be because there is another service 
    147162using that port or because you do not have the right privileges on 
    148163your system (On Unix systems this can happen if you are not root 
    149164and the port you specified is less than 1024). 
     165The original error message: $! 
    150166 
    151167EOM 
    152168# PROFILE BLOCK STOP 
    153         return 0; 
     169            return 0; 
     170        } 
     171    } else { 
     172 
     173        unlink $unix_socket if ( -e $unix_socket ); 
     174 
     175        # Open the unix socket to receive request for proxy service 
     176 
     177        $self->log_( 1, "Opening listening socket for $name proxy on unix socket $unix_socket." ); 
     178 
     179        $self->{server__} = IO::Socket::UNIX->new(  # PROFILE BLOCK START 
     180                Type      => SOCK_STREAM, 
     181                Local     => $unix_socket, 
     182                Listen    => SOMAXCONN, 
     183        );                                          # PROFILE BLOCK STOP 
     184 
     185        if ( !defined( $self->{server__} ) ) { 
     186            print STDERR <<EOM; # PROFILE BLOCK START 
     187 
     188\nCouldn\'t start the $name proxy because POPFile could not bind to the 
     189unix socket $unix_socket. This could be because there is another 
     190service using that socket or because you do not have the right 
     191privileges on your system. 
     192The original error message: $! 
     193 
     194EOM 
     195# PROFILE BLOCK STOP 
     196            return 0; 
     197        } 
    154198    } 
    155199 
    156200    # This is used to perform select calls on the $server socket so that we can decide when there is 
     
    233277            # further processing.  We don't want to act as a proxy for 
    234278            # just anyone's email 
    235279 
    236             my ( $remote_port, $remote_host ) = sockaddr_in(                # PROFILE BLOCK START 
    237                                                     $client->peername() );  # PROFILE BLOCK STOP 
     280            my $acceptable = 0; 
    238281 
    239             if  ( ( ( $self->config_( 'local' ) || 0 ) == 0 ) ||        # PROFILE BLOCK START 
    240                     ( $remote_host eq inet_aton( "127.0.0.1" ) ) ) {    # PROFILE BLOCK STOP 
     282            if ( ref $client eq 'IO::Socket::UNIX' ) { 
    241283 
     284                # Connection to the unix socket is always acceptable 
     285                # because unix sockets are connected from localhost 
     286                # only 
     287 
     288                $acceptable = 1; 
     289            } else { 
     290 
     291                my ( $remote_port, $remote_host ) = sockaddr_in(           # PROFILE BLOCK START 
     292                                                    $client->peername() ); # PROFILE BLOCK STOP 
     293 
     294                $acceptable = ( ( ( $self->config_( 'local' ) || 0 ) == 0 ) ||  # PROFILE BLOCK START 
     295                                ( $remote_host eq inet_aton( "127.0.0.1" ) ) ); # PROFILE BLOCK STOP 
     296            } 
     297 
     298            if ( $acceptable ) { 
     299 
    242300                # If we have force_fork turned on then we will do a 
    243301                # fork, otherwise we will handle this inline, in the 
    244302                # inline case we need to create the two ends of a pipe 
     
    485543# $port        The port 
    486544# $ssl         If set to 1 then the connection to the remote is established  
    487545#              using SSL 
     546# $unix_socket If it is not '', connect to the unix socket 
    488547# 
    489548# Check that we are connected to $hostname on port $port putting the 
    490549# open handle in $mail.  Any messages need to be sent to $client 
     
    492551# ---------------------------------------------------------------------------- 
    493552sub verify_connected_ 
    494553{ 
    495     my ( $self, $mail, $client, $hostname, $port, $ssl ) = @_; 
     554    my ( $self, $mail, $client, $hostname, $port, $ssl, $unix_socket ) = @_; 
    496555 
    497556    $ssl = 0 if ( !defined( $ssl ) ); 
    498557 
    499558    # Check to see if we are already connected 
     559 
    500560    return $mail if ( $mail && $mail->connected ); 
    501561 
    502562    # Connect to the real mail server on the standard port, if we are using 
     
    506566        require IO::Socket::Socks; 
    507567        $self->log_( 0, "Attempting to connect to socks server at " # PROFILE BLOCK START 
    508568                    . $self->config_( 'socks_server' ) . ":" 
    509                     . ProxyPort => $self->config_( 'socks_port' ) ); # PROFILE BLOCK STOP 
     569                    . $self->config_( 'socks_port' ) );            # PROFILE BLOCK STOP 
    510570 
    511         $mail = IO::Socket::Socks->new( # PROFILE BLOCK START 
     571        $mail = IO::Socket::Socks->new(      # PROFILE BLOCK START 
    512572                    ProxyAddr => $self->config_( 'socks_server' ), 
    513573                    ProxyPort => $self->config_( 'socks_port' ), 
    514574                    ConnectAddr  => $hostname, 
     
    605665            } 
    606666 
    607667        } else { 
    608             $self->log_( 0, "Attempting to connect to POP server at " # PROFILE BLOCK START 
    609                         . "$hostname:$port" ); # PROFILE BLOCK STOP 
     668            if ( $unix_socket ) { 
    610669 
    611             $mail = IO::Socket::INET->new( # PROFILE BLOCK START 
     670                $self->log_( 0, "Attempting to connect to unix socket at $unix_socket" ); 
     671 
     672                $mail = IO::Socket::UNIX->new(  # PROFILE BLOCK START 
     673                        Type     => SOCK_STREAM, 
     674                        Peer     => $unix_socket, 
     675                        Timeout  => $self->global_config_( 'timeout' ), 
     676                );                              # PROFILE BLOCK STOP 
     677 
     678            } else { 
     679 
     680                $self->log_( 0, "Attempting to connect to POP server at " # PROFILE BLOCK START 
     681                            . "$hostname:$port" ); # PROFILE BLOCK STOP 
     682 
     683                $mail = IO::Socket::INET->new( # PROFILE BLOCK START 
    612684                        Proto    => "tcp", 
    613685                        PeerAddr => $hostname, 
    614686                        PeerPort => $port, 
    615687                        Timeout  => $self->global_config_( 'timeout' ), 
    616             ); # PROFILE BLOCK STOP 
     688                ); # PROFILE BLOCK STOP 
     689 
     690            } 
    617691        } 
    618692    } 
    619693 
     
    621695    if ( $mail ) { 
    622696        if ( $mail->connected )  { 
    623697 
    624             $self->log_( 0, "Connected to $hostname:$port timeout " . $self->global_config_( 'timeout' ) ); 
     698            if ( $unix_socket ) { 
     699                $self->log_( 0, "Connected to $unix_socket timeout " . $self->global_config_( 'timeout' ) ); 
     700            } else { 
     701                $self->log_( 0, "Connected to $hostname:$port timeout " . $self->global_config_( 'timeout' ) ); 
     702            } 
    625703 
    626704            # Set binmode on the socket so that no translation of CRLF 
    627705            # occurs 
     
    690768        } 
    691769    } 
    692770 
    693     $self->log_( 0, "IO::Socket::INET or IO::Socket::SSL gets an error: $!" ); 
     771    $self->log_( 0, "IO::Socket::* gets an error: $!" ); 
    694772 
    695773    # Tell the client we failed 
    696     $self->tee_(  $client, "$self->{connection_failed_error_} $hostname:$port$eol" ); 
     774    if ( $unix_socket ) { 
     775        $self->tee_( $client, "$self->{connection_failed_error_} $unix_socket$eol" ); 
     776    } else { 
     777        $self->tee_( $client, "$self->{connection_failed_error_} $hostname:$port$eol" ); 
     778    } 
    697779 
    698780    return undef; 
    699781} 
  • Proxy/SMTP.pm

    old new  
    7979    $self->config_( 'chain_server', '' ); 
    8080    $self->config_( 'chain_port', 25 ); 
    8181 
     82    # Forward on to unix socket 
     83    $self->config_( 'chain_unix_socket', '' ); 
     84 
    8285    # Only accept connections from the local machine for smtp 
    8386    $self->config_( 'local', 1 ); 
    8487 
     
    183186        $self->log_( 2, "Command: --$command--" ); 
    184187 
    185188        if ( $command =~ /HELO/i ) { 
    186             if ( $self->config_( 'chain_server' ) )  { 
    187                 if ( $mail = $self->verify_connected_( $mail, $client, $self->config_( 'chain_server' ),  $self->config_( 'chain_port' ) ) )  { 
     189            if ( $self->config_( 'chain_server' ) ||        # PROFILE BLOCK START 
     190                 $self->config_( 'chain_unix_socket' ) )  { # PROFILE BLOCK STOP 
     191                if ( $mail = $self->verify_connected_(               # PROFILE BLOCK START 
     192                        $mail, 
     193                        $client, 
     194                        $self->config_( 'chain_server' ), 
     195                        $self->config_( 'chain_port' ), 
     196                        0, 
     197                        $self->config_( 'chain_unix_socket' ) ) )  { # PROFILE BLOCK STOP 
    188198 
    189199                    $self->smtp_echo_response_( $mail, $client, $command ); 
    190200                } else { 
     
    200210        # Handle EHLO specially so we can control what ESMTP extensions are negotiated 
    201211 
    202212        if ( $command =~ /EHLO/i ) { 
    203             if ( $self->config_( 'chain_server' ) )  { 
    204                 if ( $mail = $self->verify_connected_( $mail, $client, $self->config_( 'chain_server' ),  $self->config_( 'chain_port' ) ) )  { 
     213            if ( $self->config_( 'chain_server' ) ||        # PROFILE BLOCK START 
     214                 $self->config_( 'chain_unix_socket' ) )  { # PROFILE BLOCK STOP 
     215                if ( $mail = $self->verify_connected_(               # PROFILE BLOCK START 
     216                        $mail, 
     217                        $client, 
     218                        $self->config_( 'chain_server' ), 
     219                        $self->config_( 'chain_port' ), 
     220                        0, 
     221                        $self->config_( 'chain_unix_socket' ) ) )  { # PROFILE BLOCK STOP 
    205222 
    206223                    # TODO: Make this user-configurable (-smtp_add_unsupported, -smtp_remove_unsupported) 
    207224