While testing the implementation of delayed initialization of
NSPR/NSS/SASL within libpcp, I ran across a bug in which the first
secure connection of a client via pmproxy would succeed, but a second
secure connection (and all subsequent secure connection attempts) would
fail. I spent a bit of time trying to figure out how my code was causing
the apparent regression with no success. I then, in an act of
desperation, tried the scenario with the previous version of the code
and experienced the same results.
I spent some time this week debugging the situation and discovered that,
within pmproxy, AcceptNewClient() was not initializing the
status.allowed bit when setting up the table entry for a new client.
Thus, if a previous client had already used the same table entry, the
'allowed' bit was already set.
This bit, when unset, triggers a call to VerifyClient() for the first
pdu received from that client, which should be the client's credentials
pdu. When this bit has not been re-initialized and remains set for the
next client, the call to VerifyClient() is bypassed.
If the connection attempt is for a secure connection, this causes the
observed connection failure, because the secure connection handshake
between the client and pmproxy never occurs.
For an insecure connection, things still succeed, because the
credentials pdu gets passed on to pmcd, which VerifyClient() would have
done anyway. My concern is that pmproxy's call to __pmDecodeCreds(),
which happens in VerifyClient() is skipped. Is there any potential
security problem exposed by this?
The one line fix has been pushed to brolley/dev in pcpfans.
Dave
--------------------------------------------------------------------------------------------
commit 6899ab979e66da6422c9eb23abd6880fc8048387
Author: Dave Brolley <brolley@xxxxxxxxxx>
Date: Tue Sep 16 11:34:44 2014 -0400
pmproxy: Initialize status.allowed for new clients
In AcceptNewClient(), client[i].status.allowed must be initialized
to zero, otherwise the next client for which the same client table
entry is assigned never calls VerifyClient(). If that client happens
to want a secure connection, this causes the connection to fail
because the secure handshake is never performed.
|