File Coverage

blib/lib/Net/IdentServer.pm
Criterion Covered Total %
statement 18 91 19.7
branch 0 30 0.0
condition 0 3 0.0
subroutine 6 15 40.0
pod 5 7 71.4
total 29 146 19.8


line stmt bran cond sub pod time code
1              
2             package Net::IdentServer;
3              
4 5     5   198582 use strict;
  5         15  
  5         212  
5 5     5   32 use warnings;
  5         10  
  5         178  
6 5     5   5488 use POSIX;
  5         65051  
  5         34  
7 5     5   25814 use Carp;
  5         11  
  5         356  
8 5     5   32 use base qw(Net::Server::Fork);
  5         8  
  5         9933  
9              
10             our $VERSION = "0.604";
11              
12             1;
13              
14             # run {{{
15             sub run {
16 2     2 1 4579 my $this = shift;
17 2         169 $0 = ref $this;
18 2         200 $this->SUPER::run( @_ );
19             }
20             # }}}
21              
22             # print_error {{{
23             sub print_error {
24 0     0 0   my $this = shift;
25 0           my $type = lc(pop);
26 0           my @p = @_;
27 0 0         @p = (0, 0) unless @p == 2;
28              
29 0           my $txt;
30 0 0         unless( $txt = {'u'=> "UNKNOWN-ERROR", 'h' => "HIDDEN-USER", 'n' => "NO-USER", 'i' => "INVALID-PORT"}->{$type} ) {
31 0           die "bad type given to print_error";
32             }
33              
34 0           $this->print_response(@p, "ERROR", $txt);
35             }
36             # }}}
37             # print_response {{{
38             sub print_response {
39 0     0 1   my ($this, $port_on_server, $port_on_client, $os_name, $add_info) = @_;
40              
41 0 0         $os_name = "USERID : $os_name" unless $os_name eq "ERROR";
42              
43 0           printf '%d , %d : %s : %s'."\x0d\x0a", $port_on_server, $port_on_client, $os_name, $add_info;
44             }
45             # }}}
46             # do_lookup {{{
47             sub do_lookup {
48 0     0 0   my $this = shift;
49 0           my ($local_addr, $local_port, $rem_addr, $rem_port) = @_;
50              
51 0     0     my $translate_addr = sub { my $a = shift; my @a = (); push @a, $1 while $a =~ m/(..)/g; join(".", map(hex($_), reverse @a)) };
  0            
  0            
  0            
  0            
52 0     0     my $translate_port = sub { hex(shift) };
  0            
53              
54 0           my $found = $this->alt_lookup(@_);
55              
56 0 0         if( $found =~ m/^JP:(.+)/ ) {
57 0           my $name = $1;
58              
59 0           $this->log(1, "lookup from $rem_addr for $local_port, $rem_port: alt string found $name");
60 0           $this->print_response($local_port, $rem_port, "UNIX", $name);
61              
62 0           return;
63             }
64              
65 0 0         if( $found < 0 ) {
66 0 0         open my $tcp, "<", "/proc/net/tcp" or die "couldn't open proc/net/tcp for read: $!";
67 0           while(<$tcp>) {
68 0 0         if( m/^\s+\d+:\s+([A-F0-9]{8}):([A-F0-9]{4})\s+([A-F0-9]{8}):([A-F0-9]{4})\s+(\d+)\s+\S+\s+\S+\s+\S+\s+(\d+)/ ) {
69 0           my ($la, $lp, $ra, $rp, $state, $uid) = ($1, $2, $3, $4, $5, $6);
70              
71 0 0         if( $state == 1 ) {
72 0           $la = $translate_addr->($la); $lp = $translate_port->($lp);
  0            
73 0           $ra = $translate_addr->($ra); $rp = $translate_port->($rp);
  0            
74              
75 0 0 0       if( $local_port eq $lp and $rem_port eq $rp ) {
76 0           $found = $uid;
77 0           last;
78             }
79             }
80             }
81             }
82 0           close $tcp;
83             }
84              
85 0 0         if( $found < 0 ) {
86 0           $this->not_found(@_);
87              
88 0           return;
89             }
90              
91 0           my $name = getpwuid( $found );
92 0 0         unless( $name =~ m/\w/ ) {
93             # This can happen if a deleted user has a socket open. 'u' might be a better choice.
94             # I happen to think hidden user is a nice choice here.
95              
96 0           $this->log(2, "lookup from $rem_addr for $local_port, $rem_port: found uid, but no pwent");
97 0           $this->print_error($local_port, $rem_port, 'h');
98 0           return;
99             }
100              
101 0           $this->log(1, "lookup from $rem_addr for $local_port, $rem_port: found $name");
102 0           $this->print_response($local_port, $rem_port, "UNIX", $name);
103              
104 0           return 1;
105             }
106             # }}}
107             # not_found {{{
108             sub not_found {
109 0     0 1   my $this = shift;
110 0           my ($local_addr, $local_port, $rem_addr, $rem_port) = @_;
111              
112 0           $this->log(2, "lookup from $rem_addr for $local_port, $rem_port: not found");
113 0           $this->print_error($local_port, $rem_port, 'n'); # no user for when we find no sockets!
114             }
115             # }}}
116             # alt_lookup {{{
117             sub alt_lookup {
118 0     0 1   return -1;
119             }
120             # }}}
121              
122             # process_request {{{
123             sub process_request {
124 0     0 1   my $this = shift;
125              
126 0           my $master_alarm = alarm 10;
127 0     0     local $SIG{ALRM} = sub { die "\n" };
  0            
128 0           eval {
129 0           while( my $input = ) {
130 0 0         $input = "" unless $input; # to deal with stupid undef warning
131 0           $input =~ s/[\x0d\x0a]+\z//;
132              
133 0 0         unless( $input =~ m/^\s*(\d+)\s*,\s*(\d+)\s*$/ ) {
134 0           $this->log(3, "Malformated request from $this->{server}{peeraddr}");
135 0           $this->print_error("u");
136 0           return;
137             }
138 0           my ($s, $c) = ($1, $2);
139              
140 0           $this->do_lookup($this->{server}{sockaddr}, $s, $this->{server}{peeraddr}, $c);
141             }
142             };
143 0           alarm $master_alarm;
144              
145 0 0         if( $@ eq "\n" ) {
    0          
146             # print "500 too slow...\n";
147             # on timeout, ident just closes the connection ...
148              
149             } elsif( $@ ) {
150 0           $this->log(3, "ERROR during main while() { do_lookup() } eval: $@");
151              
152             }
153             }
154             # }}}
155              
156             __END__