Apply old patch from me that handles client's behind NAT
authorLove Hornquist Astrand <lha@h5l.org>
Fri, 16 Dec 2011 06:00:00 +0000 (22:00 -0800)
committerLove Hornquist Astrand <lha@h5l.org>
Fri, 16 Dec 2011 06:00:00 +0000 (22:00 -0800)
Tested by Harald Barth and bugfix by Ragnar Sundblad

kpasswd/kpasswdd.c

index 21455e844aac0a79612f29f1ce27f9ff6a2fd216..97d39fc5d3791d006691285cdea732c4b28db9bc 100644 (file)
@@ -445,7 +445,8 @@ verify (krb5_auth_context *auth_context,
        struct sockaddr *sa,
        int sa_size,
        u_char *msg,
-       size_t len)
+       size_t len,
+       krb5_address *client_addr)
 {
     krb5_error_code ret;
     uint16_t pkt_len, pkt_ver, ap_req_len;
@@ -546,6 +547,21 @@ verify (krb5_auth_context *auth_context,
     krb_priv_data.data   = msg + 6 + ap_req_len;
     krb_priv_data.length = len - 6 - ap_req_len;
 
+    /*
+     * Only enforce client addresses on on tickets with addresses.  If
+     * its addressless, we are guessing its behind NAT and really
+     * can't know this information.
+     */
+
+    if ((*ticket)->ticket.caddr && (*ticket)->ticket.caddr->len > 0) {
+       ret = krb5_auth_con_setaddrs (context, *auth_context,
+                                     NULL, client_addr);
+       if (ret) {
+           krb5_warn (context, ret, "krb5_auth_con_setaddr(this)");
+           goto out;
+       }
+    }
+
     ret = krb5_rd_priv (context,
                        *auth_context,
                        &krb_priv_data,
@@ -582,7 +598,7 @@ process (krb5_realm *realms,
     krb5_address other_addr;
     uint16_t version;
 
-
+    memset(&other_addr, 0, sizeof(other_addr));
     krb5_data_zero (&out_data);
 
     ret = krb5_auth_con_init (context, &auth_context);
@@ -600,18 +616,27 @@ process (krb5_realm *realms,
        goto out;
     }
 
-    ret = krb5_auth_con_setaddrs (context,
-                                 auth_context,
-                                 this_addr,
-                                 &other_addr);
-    krb5_free_address (context, &other_addr);
+    ret = krb5_auth_con_setaddrs (context, auth_context, this_addr, NULL);
     if (ret) {
-       krb5_warn (context, ret, "krb5_auth_con_setaddr");
+       krb5_warn (context, ret, "krb5_auth_con_setaddr(this)");
        goto out;
     }
 
     if (verify (&auth_context, realms, keytab, &ticket, &out_data,
-               &version, s, sa, sa_size, msg, len) == 0) {
+               &version, s, sa, sa_size, msg, len, &other_addr) == 0)
+    {
+       /*
+        * We always set the client_addr, to assume that the client
+        * can ignore it if it choose to do so (just the server does
+        * so for addressless tickets).
+        */
+       ret = krb5_auth_con_setaddrs (context, auth_context, 
+                                     this_addr, &other_addr);
+       if (ret) {
+           krb5_warn (context, ret, "krb5_auth_con_setaddr(other)");
+           goto out;
+       }
+
        change (auth_context,
                ticket->client,
                version,
@@ -623,8 +648,9 @@ process (krb5_realm *realms,
     }
 
 out:
-    krb5_data_free (&out_data);
-    krb5_auth_con_free (context, auth_context);
+    krb5_free_address(context, &other_addr);
+    krb5_data_free(&out_data);
+    krb5_auth_con_free(context, auth_context);
 }
 
 static int