From 05217c29179100b69a32562202b302ae60b4b36c Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Tue, 1 Oct 2013 14:54:15 -0500 Subject: [PATCH] rx: Ignore responses to nonexistent challenges Consider the following situation: - A client sends a data packet to a server, using a security class that requires a challenge - The server responds with a challenge - The server is restarted - The client responds to the challenge with a response In that situation, the server will process the response, but since the server was restarted, it has no knowledge of the challenge that was sent. This generally means that we error the connection, since the given response is not valid. For rxkad with modern endpoints, this results in an RXKADPACKETSHORT error, since we interpret the response as an 'old' response, but it's actually a 'v2' response, so we interpret the fields in the response as garbage. This means that the client gets a connection error when the client did nothing wrong, and there's no way for the client to distinguish this from a real connection error. One way to solve this would be to send a Challenge packet to the client immediately when we detect that this situation has occurred. However, if we do that, then we never see a data packet with a checksum, so we fall back to using "old" challenges and responses. And in general, that would cause the server side to never see a data packet during the connection negotiation, which is unusual and I am concerned there may be other niggles of odd behavior that may occur in that scenario. So instead, to fix this, make the server ignore responses in this situation (that is, if we haven't sent out any challenges yet). Clients will eventually resend the data packet, and we will go through negotiating the connection security like normal. This should never cause any new problems, since dropping a challenge packet must be handled anyway (sometimes packets just get dropped). And a client will never hang on sending the same response over and over again; clients only ever send a Response in response to a Challenge packet. Change-Id: Id3fae425addb2ac8ab60965213b3ebca2e64ba5d Reviewed-on: http://gerrit.openafs.org/10315 Reviewed-by: Daria Brashear Reviewed-by: Mark Vitale Tested-by: BuildBot Reviewed-by: Benjamin Kaduk --- src/rx/rx.c | 11 +++++++++++ src/rx/rx_conn.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/rx/rx.c b/src/rx/rx.c index ce815a41d..6c713687c 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -4806,6 +4806,16 @@ rxi_ReceiveResponsePacket(struct rx_connection *conn, if (RXS_CheckAuthentication(conn->securityObject, conn) == 0) return np; + if (!conn->securityChallengeSent) { + /* We've never sent out a challenge for this connection, so this + * response cannot possibly be correct; ignore it. This can happen + * if we sent a challenge to the client, then we were restarted, and + * then the client sent us a response. If we ignore the response, the + * client will eventually resend a data packet, causing us to send a + * new challenge and the client to send a new response. */ + return np; + } + /* Otherwise, have the security object evaluate the response packet */ error = RXS_CheckResponse(conn->securityObject, conn, np); if (error) { @@ -6868,6 +6878,7 @@ rxi_ChallengeEvent(struct rxevent *event, rxi_SendSpecial((struct rx_call *)0, conn, packet, RX_PACKET_TYPE_CHALLENGE, NULL, -1, 0); rxi_FreePacket(packet); + conn->securityChallengeSent = 1; } clock_GetTime(&now); when = now; diff --git a/src/rx/rx_conn.h b/src/rx/rx_conn.h index a54bb34e1..2f3a16e78 100644 --- a/src/rx/rx_conn.h +++ b/src/rx/rx_conn.h @@ -63,6 +63,7 @@ struct rx_connection { void *securityData; /* Private data for this conn's security class */ u_short securityHeaderSize; /* Length of security module's packet header data */ u_short securityMaxTrailerSize; /* Length of security module's packet trailer data */ + int securityChallengeSent; /* Have we ever sent a challenge? */ int timeout; /* Overall timeout per call (seconds) for this conn */ int lastSendTime; /* Last send time for this connection */ -- 2.39.5