Description of problem:
As of version 1.4.2, Java defaults to using IPv6 sockets. When a
Java application connects to an IPv4 address, it creates an IPv6
connection to a "IPv4-mapped address" of the form ::ffff:w.x.y.z
If authd receives a query from an IPv4 program on the other end of
such a socket, it only searches /proc/net/tcp. Since the socket is
not listed there, it reports an error.
authd needs to be changed to also look for IPv4 sockets in
/proc/net/tcp6, using their IPv4-mapped addresses.
Version-Release number of selected component (if applicable):
I have created a very simple client/server program to demonstrate this
problem. I will attach three files:
* sockserv.c is the server
* sockcl.c is a C client
* SocketClient.java is a Java client
The server listens on port 9999, accepts a single connection, and
prints anything that is typed on the client. The Java client requires
a single parameter, the name or address of the server (the port is
hardcoded). Both the server address and the port are hardcoded in the
C client, so you'll probably need to edit it.
I recommend using two separate systems for testing; things can get a
little confusing when running both the server and the Java client on a
single system; you'll need to open port 9999 in the firewall on the
server system to do this.
Once you set everything up and connect with the C client, you'll be
able to see the socket in /proc/net/tcp (or 'netstat --inet') on both
systems, as you would expect. If you're running authd on the client
system, it will work as expected. You'll need to use Ctrl-C to exit
the client, at which point the server should also exit.
Now restart the server and connect with the Java client. Note that
the socket appears in /proc/net/tcp ('netstat --inet') on the server
system. On the client system, however, the socket shows up only in
/proc/net/tcp6 ('netstat --inet6'), so authd won't find it.
authd should search /proc/net/tcp6, using IPv4-mapped addresses, find
the socket, and return the appropriate user information.
Note that this doesn't just authd-based authentication over the
network. It also breaks it over the loopback adapter, which is the
only type of socket available to Java applications. (For example, a
JDBC connection to a PostgreSQL database.)
Created attachment 106994 [details]
Created attachment 106996 [details]
C client program
This uses GNU readline, so you will need to compile it with
'gcc -O2 -Wall -o sockcl sockcl.c -lreadline -lcurses'.
Created attachment 106997 [details]
Java client program
authd DOES support IPv4-mapped IPv6 addresses, using the documented
"--mapped=ipv6" which pairs the specified top 96 bits with the lower
32 bits to match.
Granted, this parameter is not enabled by default in the xinetd
config, but the capability is there.
When I try to use "--mapped=ipv6", I just get an error message.
[pilcher@home ~]$ rpm -q authd
[pilcher@home ~]$ netstat --inet
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address
tcp 0 0 home:9999 192.168.1.129:32773
tcp 0 0 localhost.localdomain:33596
udp 0 0 localhost.localdo:32771 localhost.localdo:32771
[pilcher@home ~]$ /usr/sbin/in.authd 33596,22
33596 , 22 : USERID : UNIX :pilcher
[pilcher@home ~]$ /usr/sbin/in.authd --verbose 33596,22
33596 , 22 : USERID : OTHER :pilcher:500,2004-11-19T20:35:54Z(Fri
02:35:54 PM -0600/CST),127.0.0.1|33596,127.0.0.1|22
[pilcher@home ~]$ /usr/sbin/in.authd --mapped=ipv6 33596,22
/usr/sbin/in.authd: invalid argument to --mapped: ipv6
comment 5: you're taking the help/docs too literally; substitute the
word "ipv6" with a valid (that glibc would understand-- because it
uses glibc ipv6 address parse routines to decode i)) ipv6 address that
contains the top 96 bit prefix you want to mask against.