#! /usr/bin/perl -w # # authinfo-kludge - AUTHINFO GENERIC helper # Copyright (C) 2000 Richard Kettlewell # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # See # http://www.greenend.org.uk/rjk/2000/08/29/authinfo.html # for further information about this script. # use strict; use integer; use Socket; use IO::Handle; use POSIX qw(dup2); # kludge! system("stty -icrnl >/dev/null 2>&1"); # connect to the real server my $nntpserver = shift || $ENV{'NNTPSWERVER'} || $ENV{'NNTPSERVER'} || 'news'; $^F = 9999; socket(S, PF_INET, SOCK_STREAM, 0) or die "socket: $!"; connect(S, sockaddr_in(119, inet_aton($nntpserver))) or die "connect $nntpserver: $!"; S->autoflush(1); # connect banner $_ = S->getline; /^2/ or die "$nntpserver: $_"; # request nnrp S->print("MODE READER\r\n") or die "writing to $nntpserver: $!"; $_ = S->getline; /^2/ or die "$nntpserver: $_"; # do the authorization S->print("AUTHINFO GENERIC $ENV{'NNTPAUTH'}\r\n") or die "writing to $nntpserver: $!"; defined (my $pid = fork) || die "fork: $!"; if(!$pid) { $ENV{'NNTP_AUTH_FDS'} = S->fileno . '.' . S->fileno; exec("sh", "-c", $ENV{'NNTPAUTH'}) or die "exec sh: $!"; die "exec returned unexpectedly"; } if(waitpid($pid, 0) != $pid) { die "waitpid: $!"; } if($?) { die "authinfo handler subprocess terminated with wstat $?"; } STDOUT->autoflush(1); print "200 Proxy NNRP service ready (posting ok)\r\n" or die "stdout: $!"; # forward everything read on S to stdout and everything read on stdin to S for(;;) { my $r = ''; vec($r, STDIN->fileno, 1) = 1; vec($r, S->fileno, 1) = 1; my $n = select($r, undef, undef, undef); die "select: $!\n" if ! defined $n; my $buffer; if(vec($r, STDIN->fileno, 1)) { my $n = sysread(STDIN, $buffer, 4096); die "stdin: $!" if ! defined $n; exit 0 if $n == 0; (S->print($buffer)) || die "writing to $nntpserver: $!"; } if(vec($r, S->fileno, 1)) { my $n = sysread(S, $buffer, 4096); die "reading from $nntpserver: $!" if ! defined $n; exit 0 if $n == 0; (print $buffer) || die "stdout: $!"; } }