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;
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,
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);
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,
}
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