Allow password changes over NATs
authorGreg Hudson <ghudson@mit.edu>
Sat, 15 Oct 2011 16:56:30 +0000 (16:56 +0000)
committerGreg Hudson <ghudson@mit.edu>
Sat, 15 Oct 2011 16:56:30 +0000 (16:56 +0000)
In the kpasswd server code, don't set a remote address in the auth
context before calling krb5_rd_priv, since the kpasswd protocol is
well-protected against reflection attacks.  This allows password
changes to work in cases where a NAT has changed the client IP address
as it is seen by the server.

ticket: 6979

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25356 dc483132-0cff-0310-8789-dd5450dbe970

src/kadmin/server/schpw.c

index d46d43b15ccca657c63c01143a22ce281f052487..8e38cfd04304db86cd98bd660dabb6cd40396294 100644 (file)
@@ -137,29 +137,6 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
         goto chpwfail;
     }
 
-    /* mk_priv requires that the local address be set.
-       getsockname is used for this.  rd_priv requires that the
-       remote address be set.  recvfrom is used for this.  If
-       rd_priv is given a local address, and the message has the
-       recipient addr in it, this will be checked.  However, there
-       is simply no way to know ahead of time what address the
-       message will be delivered *to*.  Therefore, it is important
-       that either no recipient address is in the messages when
-       mk_priv is called, or that no local address is passed to
-       rd_priv.  Both is a better idea, and I have done that.  In
-       summary, when mk_priv is called, *only* a local address is
-       specified.  when rd_priv is called, *only* a remote address
-       is specified.  Are we having fun yet?  */
-
-    ret = krb5_auth_con_setaddrs(context, auth_context, NULL,
-                                 remote_faddr->address);
-    if (ret) {
-        numresult = KRB5_KPASSWD_HARDERROR;
-        strlcpy(strresult, "Failed storing client internet address",
-                sizeof(strresult));
-        goto chpwfail;
-    }
-
     /* construct the ap-rep */
 
     ret = krb5_mk_rep(context, auth_context, &ap_rep);
@@ -175,6 +152,14 @@ process_chpw_request(krb5_context context, void *server_handle, char *realm,
     cipher.length = (req->data + req->length) - ptr;
     cipher.data = ptr;
 
+    /*
+     * Don't set a remote address in auth_context before calling krb5_rd_priv,
+     * so that we can work against clients behind a NAT.  Reflection attacks
+     * aren't a concern since we use sequence numbers and since our requests
+     * don't look anything like our responses.  Also don't set a local address,
+     * since we don't know what interface the request was received on.
+     */
+
     ret = krb5_rd_priv(context, auth_context, &cipher, &clear, &replay);
     if (ret) {
         numresult = KRB5_KPASSWD_HARDERROR;