Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Potential bug using TCP for kinit to KDC communication

51 views
Skip to first unread message

Oli Mlist

unread,
Apr 2, 2012, 11:30:31 AM4/2/12
to kerb...@mit.edu
Hi,

I am experimenting kinit ticket requesting to KDC using TCP and see that
all attempts fall back to UDP. Looking at the code it seems there is a bug,
see below.

my setup:
- MIT Kerberos 1.10.1, built from source code and running this build
- kbr5.conf with udp_preference_limit=1
- kdc.conf with kdc_tcp_ports=88

Here is part of the flow in sendto_kdc.c:
- KDC hostname gets resolved (resolve_server()) and several connections are
attempted, first ones with TCP, and some UDP sockets are created too.
- each connection is attempted by a start_connection() call, they all
succeed.
- at the end of start_connection(), there is an ssflags local variable into
which the SSF_READ flag is being set (among others), and this state is
saved through cm_add_fd().
- for TCP sockets, the service_tcp_fd() function is called, running a state
machine.
- inside service_tcp_fd(), for the CONNECTING state, a check is made for
the SSF_READ flag. If this flag is set, a comment tells the KDC is sending
data to us, which is interpreted as an error, so the TCP socket is
disconnected by the client. As seen above, this SSF_READ flag had been
explicitly set at the end of start_connection().
- consequently, all the TCP sockets are closed along the same scenario,
then Kerberos falls back to UDP sockets, which do succeed in contacting the
KDC.

So I think there is a bug there, either start_connection() should not set
the SSF_READ flag by default, or service_tcp_fd() should't check
the SSF_READ during the CONNECTING phase and fall into error there.

Thanks to let me know if this is indeed a but or whether I am missing
something,

-- oli.

Greg Hudson

unread,
Apr 2, 2012, 12:23:24 PM4/2/12
to Oli Mlist, kerb...@mit.edu
On 04/02/2012 11:30 AM, Oli Mlist wrote:
> - at the end of start_connection(), there is an ssflags local variable into
> which the SSF_READ flag is being set (among others), and this state is
> saved through cm_add_fd().
> - for TCP sockets, the service_tcp_fd() function is called, running a state
> machine.
> - inside service_tcp_fd(), for the CONNECTING state, a check is made for
> the SSF_READ flag. If this flag is set, a comment tells the KDC is sending
> data to us, which is interpreted as an error, so the TCP socket is
> disconnected by the client. As seen above, this SSF_READ flag had been
> explicitly set at the end of start_connection().

The flags to service_tcp_fd() come from cm_get_ssflags(), which
processes the revents member of the pollfd, not the events member which
was set in cm_add_fd(). So, poll() is saying that a read on the TCP
socket wouldn't block, implying that there is either data to be read or
a socket error to be processed, neither of which happens during a
successful exchange.

> Thanks to let me know if this is indeed a but or whether I am missing
> something,

I put together a simple test case and was able to communicate with a KDC
over TCP.

Oli Mlist

unread,
Apr 2, 2012, 3:09:45 PM4/2/12
to kerb...@mit.edu
Greg,

Thanks, you are right, in the case of service_tcp_fd(), the state is
re-analyzed after a poll() and set up as new with cm_get_ssflags(). I
double checked my setup and found out a port configuration issue with my
KDC. I fixed it and TCP is working fine now.

-- Oli.

Carson Gaspar

unread,
Apr 3, 2012, 4:50:59 PM4/3/12
to kerb...@mit.edu
On 4/2/12 9:23 AM, Greg Hudson wrote:

> was set in cm_add_fd(). So, poll() is saying that a read on the TCP
> socket wouldn't block, implying that there is either data to be read or
> a socket error to be processed, neither of which happens during a
> successful exchange.

While the KDC may never send initial data, in general the correct test
for an async TCP connect error is (readable and (not writable)).
Otherwise you have a race condition (assuming the server may ever write
data before the client does).

--
Carson

sowm...@gmail.com

unread,
Feb 28, 2014, 12:07:37 PM2/28/14
to
I did disable all of the isatap, teredo, 6to4 interfaces on Windows and still the same issue. I can always without any delay "telnet <ipv6 address> 445". So, through wireshark, I found that the destination port to which the connection fails is 445. There is not a problem connecting using the hostname as well.

And, in fact, I did a wireshark tracing on the AD server. I see the "TCP syn, syn-ack and then ack" all going through, a second later I see a RST from the server but that is exactly after I see "abandoning connection : Operation now in progress". This print out seems to be coming from kill_conn function in sendto_kdc.c file which is called from the goto kill_conn: section which is called from handle_exception section from case READING: of the service_tcp_fd file. The error is always consistent. My guess is that it is taking longer to connect. However, I have added a check for "get_so_error(fd)" inside the for loop inside service_fds function. When it calls service_tcp_fd after connect was called from maybe_send, get_so_error is returning a 0 indicating no error but after writing, when it gets to case READING , I see that error and read is never invoked. Instead the kill_conn is invoked.

My only guess now is that connect or write is taking much longer for ipv6. Is there a way to wait for the Operation now in progress to go away when we hit that. Just putting a return out in kill_conn if we see this error seems to be causing the program to loop for 16 times when it gives up with the error Looping detected and gives up any way.

Thanks for your help again. I really appreciate it.

-Sowmya.
0 new messages