beautiful, you were entirely right Chris... 

for those interested heres the solution i conjured. please excuse the
ugly / sloppy  coding technique. :)

does the following... 
for each request, takes source address, snmp queries a novell box on
the requesters lan to find what novell user is logged on at that box.
if its only one user (eg its not a citrix box with  10 different
users) then it looks that user up via ldap host to see if that user is
in the "internet" group. if so, throws "OK user=blah", if not throws
ERR. thus allowing novell users to authenticate and be logged in squid
logs.

finally i also threw in a ncsa_auth parm to give admins and others in
the know ability to get out thru the proxy even if they havent logged
into novell.



adding a user with command..
        htpasswd -c /etc/squid.htpasswd admin
                
in squid.conf
        external_acl_type ldap_lookup ttl=120 %SRC /tmp/ldap_lookup.pl
        acl group1 external ldap_lookup
        http_access allow group1

        auth_parm basic program /usr/sbin/ncsa_auth /etc/squid.htpasswd
        acl htpasswd_auth proxy_auth admin
        http_access allow htpasswd_auth

/tmp/ldap_lookup.pl contains....

#!/usr/bin/perl
use strict;
$|=1;
while ( 1 == 1 ) {
        my $sought_ip = <STDIN>;
        chomp($sought_ip);
        if ($sought_ip =~ /^172\.16\.\d{1,3}\.\d{1,3}$/){
                print &lookup_info('novell_box_w_snmp1',$sought_ip,'ldapbox');
        } elsif ($sought_ip =~ /^192\.168\.1\.\d{1,3}$/) {
                print &lookup_info('novell_box_w_snmp2',$sought_ip,'ldapbox');
        } elsif ($sought_ip =~ /^192\.168\.61\.\d{1,3}$/) {
                print &lookup_info('novell_box_w_snmp3',$sought_ip,'ldapbox');
        } else {
                print 'ERR 
error=no_idea_what_snmp_host_to_query_youre_not_at_novell
box 1 2 or 3'."\n";
        }
}
sub lookup_info {
        #get args...    
        (my $snmp_host,my $sought_ip,my $ldap_host)[EMAIL PROTECTED];
        #convert ip to hex
        my @hex_ip = split(/\./,$sought_ip);
        foreach (@hex_ip) {
                $_ = dec2hex($_);
        };
        my $hex_ip = join(' ',@hex_ip,);
        #get session_ids/users and session_ids/ips_in_hex_form
        my @users = `snmpwalk -v 1 -c public $snmp_host 
.1.3.6.1.4.1.23.2.28.3.8.1.2`;
        my @ips_in_hex = `snmpwalk -v 1 -c public $snmp_host
.1.3.6.1.4.1.23.2.28.3.8.1.4`;
        #print "ips\t\t::\tconnection id\n";
        # regex thru ips in hex form and find our specific ip then save that
session id in an array
        my @connection_ids;
        foreach (@ips_in_hex) {
                if (/^.*\.(\d{1,9}) = Hex-STRING: $hex_ip/i) {
                        #print $sought_ip."\t::\t".$1."\n";
                        push(@connection_ids,$1); 
                }
        }
        #for each unique connection id on an IP, look thru users and on
matching id #'s pull the user tied to that session
        my %users;
        my %connection_ids = map {$_ => 1} @connection_ids;
        foreach (sort keys %connection_ids) {
                my $connection_id = $_;
                foreach (@users){
                        if ( ($_ !~ /ou=workstations/i) and ($_ =~
/.*23\.2\.28\.3\.8\.1\.2\.($connection_id)\s=\s.*STRING:\s"(.*)"/)){
                                $users{$1}=$2;
                        }
                }
        }
        #print "there are ".scalar(keys %users)." users on that ip\n"; 
        return 'ERR error=not_just_1_user_on_this_ip'."\n" if (scalar(keys
%users) != 1);
        #print "\nconnection id\t::\t person at connection\t\tcan get on 
internet\n";
        # for each user on a session id
        open LDAPSEARCH, 'c:\openldap\ldapsearch -LLLxh '.'ldaphost'.'
"(cn=Internet)" member |' or die "Can't ldapsearch :$!";
        my @ldap_search;
        while (<LDAPSEARCH>) {
                push (@ldap_search, $_) if (/member:/i);
        }
        foreach (keys %users) {
                $users{$_} =~ s/\.T=.*//g;
                $users{$_} =~ s/\.CN=/CN=/g;
                $users{$_} =~ s/\./,/g;
                #print "$users{$_} :: $_";
                #print "$_ \t\t::\t $users{$_}\t" if (($_) and ($users{$_} !~
/[a-z,0-9,:]{17,17},ou=workstations/i ));
                my $fullusername = $users{$_};
                my $found = 0;
                foreach (@ldap_search) {
                        if ($_ =~ /$fullusername/i) {
                                $found = 1;
                                /member: (.*)/i;
                          last;
                        }                       
                }

                $fullusername =~ s/CN=//g;
                $fullusername =~ s/,OU=|,O=/./g;
                
                if ($found == 0){
                        return 'ERR error='.$fullusername."\n";
                } else {
                        return 'OK user='.$fullusername."\n";
                }
        }
}
sub hex2dec($) {
        eval "return sprintf(\"\%d\", 0x$_[0])";
}
sub dec2hex($) { 
        return sprintf("%02lX", $_[0]) 
}








On 6/1/05, Chris Robertson <[EMAIL PROTECTED]> wrote:
> > -----Original Message-----
> > From: Mike Brentlinger [mailto:[EMAIL PROTECTED]
> > Sent: Wednesday, June 01, 2005 1:57 PM
> > To: Chris Robertson
> > Cc: [email protected]
> > Subject: Re: [squid-users] external_acl_type ttl not working? or not as I
> understand?
> >
> > On 6/1/05, Chris Robertson <[EMAIL PROTECTED]> wrote:
> >>> -----Original Message-----
> >>> From: Mike Brentlinger [mailto:[EMAIL PROTECTED]
> >>> Sent: Wednesday, June 01, 2005 10:23 AM
> >>> To: [email protected]
> >>> Subject: [squid-users] external_acl_type ttl not working? or not as I
> >>> understand?
> >>>
> >>>
> >>> Im trying to conjure up a replacement to novell border manager +
> >>> client trust for transpartent  auth in a novell environment. there are
> >>> some squid proxy auth things it seems, however they require that the
> >>> user be prompted to enter a user+pass... not really ideal. instead
> >>> users should not have to think about logging on. i know ident can be
> >>> spoofed but for this test its not a huge issue so got the following to
> >>> work on squid 2.5 stable 5:
> >>>
> >>>   external_acl_type ldap_lookup ttl=120 %IDENT /tmp/ldaplookup.pl
> >>>   acl group1 external ldap_lookup
> >>>   http_access allow group1
> >>>
> >>> where /tmp/ldaplookup.pl is
> >>>   #!/usr/bin/perl
> >>>   $|=1;
> >>>   while ( 1 == 1 ) {
> >>>     $input = <STDIN>;
> >>>     chomp($input);
> >>>     open LDAPSEARCH, 'ldapsearch -LLLxh server "(cn=Internet)" member
> >>> |' or die "Can't ldapsearch :$!";
> >>>     $found = 0;
> >>>     $fullusername = '';
> >>>     while (<LDAPSEARCH>) {
> >>>       #print "$_";
> >>>       if ($_ =~ /cn=$input,/i) {
> >>>         $found = 1;
> >>>         /member: (.*)/i;
> >>>         $fullusername = $1;
> >>>         last;
> >>>       };
> >>>     }
> >>>     if ($found == 0){
> >>>       print 'ERR ERROR="'.$input.' not a valid internet user"'."\n";
> >>>     } else {
> >>>       print 'OK USER="'.$fullusername.' authorized internet user"'."\n";
> >>>     };
> >>>   };
> >>>
> >>>
> >>> and my client is running
> >>> http://ftp.tdcnorge.no/pub/windows/Identd/Identd-1.1.0.zip
> >>>
> >>>
> >>> everything works except the ttl isnt as I thought... eg: my client
> >>> tries to hit a page, squid ident requests my client, which responds,
> >>> then squid uses my script to see if that user name is in the
> >>> "internet" group as retured from my ldap search. if the users in the
> >>> group the page is served, if not, they get access denied.
> >>>
> >>> so my question is this... if i imediately shut down my identd on my
> >>> client, squid starts denying access immediately. a net sniff shows
> >>> that squid is doing an ident query for every access request. I would
> >>> have expected with the ttl=120 that squid wouldnt query until 2
> >>> minutes later. this seems like a lot of needless ident traffic and
> >>> when i start piling on users ill be doing more ident and ldap lookups
> >>> than web proxying.
> >>>
> >>> I suppose I just misunderstand the ttl option. is there anyway to get
> >>> squid to only ask for this ident auth at some specified timeout and
> >>> not for every page request?
> >>>
> >>> any help would be greatly appreciated.
> >>
> >> The TTL value specified is how long Squid caches the result for the
> external
> >> ACL.  So (as it stands now) if you authenticate, and then shut down the
> LDAP
> >> server (or revoke the account), you'll be able to continue surfing for
> two
> >> minutes.  Move the ident lookup to the Perl script, and you should see a
> >> reduction in network traffic.
> >>
> >> Chris
> >>
> > Chris,
> > Thanks for the reply. to make sure I understand correctly...... youre
> > saying something like the following would only do a single idnet query
> > and ldap lookup every 2 mins... and in-between squid would just
> > remember for the duration of the ttl that %SRC has access ?
> >
> >
> >  external_acl_type lookup ttl=120 %SRC /tmp/lookup.pl
> >  acl group1 external lookup
> >  http_access allow group1
> >
> >
> > where /tmp/lookup.pl is
> >
> >  #!/usr/bin/perl
> >   while ( 1 == 1 ) {
> >    $input = <STDIN>; #client ip from squid
> >    $ident_rtn_name = return of some func doing an ident query to
> > client for a username
> >    open LDAPSEARCH, 'ldapsearch -LLLxh server "(cn=Internet)" member|' ;
> >    $found = 0;
> >    $fullusername = '';
> >    while (<LDAPSEARCH>) {
> >      if ($_ =~ /cn=$ident_rtn_name,/i) {
> >        $found = 1;
> >        /member: (.*)/i;
> >        $fullusername = $1;
> >        last;
> >      };
> >    }
> >    if ($found == 0){
> >      print 'ERR ERROR="'.$ident_rtn_name.' not a valid internet
> user"'."\n";
> >    } else {
> >      print 'OK USER="'.$fullusername.' authorized internet user"'."\n";
> >    };
> >  };
> >
> >
> > --
> >  msb
> 
> That is what I am saying.  Whether I am correct or not is the big question.
> :o)  FWIW, I have a high level of confidence in my assertion.
> 
> Chris
> 


-- 
 msb

Reply via email to