--- ./src/modules/rlm_wimax/rlm_wimax.orig 2010-02-03 09:52:09.000000000 -0600 +++ ./src/modules/rlm_wimax/rlm_wimax.c 2010-02-03 10:02:08.000000000 -0600 @@ -485,58 +485,112 @@ } } - /* - * Generate MN-FA = H(FA-RK, "MN FA" | FA-IP | MN-NAI) - */ - ip = pairfind(request->reply->vps, 1901); - if (fa_rk && ip && mn_nai) { - HMAC_CTX_init(&hmac); - HMAC_Init_ex(&hmac, fa_rk->vp_octets, fa_rk->length, - EVP_sha1(), NULL); - - HMAC_Update(&hmac, (const uint8_t *) "MN FA", 5); - HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4); - HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length); - - HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len); - - vp = radius_paircreate(request, &request->reply->vps, - 1902, PW_TYPE_OCTETS); - if (!vp) { - RDEBUG("WARNING: Failed creating WiMAX-MN-FA"); - } else { - memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len); - vp->length = rk1_len; - } - } + /* + * Generate RRQ-MN-HA Key if requested. + * + * This is generated using the same method as the MN-HA keys above, + * however uses the RRQ-HA-IP instead of the actual HA-IP. This is used + * in cases where the MN does not know the IP address of the HA during + * network entry. + * + * Only valid with CMIP + */ + + /* + * Look for WiMAX-RRQ-HA-IP + */ + ip = pairfind(request->packet->vps, WIMAX2ATTR(18)); + if (ip) { + RDEBUG("WiMAX-RRQ-HA-IP found. Calculating RRQ-MN-HA key"); + + /* + * If not valid HA-IP address stop now... + */ + + /* + * WiMAX-RRQ-HA-IP can contain either an IPv4 address, an IPv6 + * address, or the ALL-ZERO-ONE-ADDR. It is assumed by the WMF that + * all networks will be homogeneous. + */ + + /* + * RRQ-MN-HA = + * For CMIP4: + * H(MIP-RK, "CMIP4 MN HA" | RRQ-HA-IP (IPv4) | MN-NAI); + * - or - + * For CMIP6: + * H(MIP-RK, "CMIP6 MN HA" | RRQ-HA-IP (IPv6) | MN-NAI ); + */ + HMAC_CTX_init(&hmac); + HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL); + + /* + * RRQ-HA-IP is an IPv4 address + */ + if ((ip->type == PW_TYPE_IPADDR) /* && valid IPv4 address */) { + HMAC_Update(&hmac, (const uint8_t *) "CMIP4 MN HA", 11); + HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4); + } + + /* + * RRQ-HA-IP is an IPv6 address + */ + if ((ip->type == PW_TYPE_IPV6ADDR) /* && valid IPv6 address */) { + HMAC_Update(&hmac, (const uint8_t *) "CMIP6 MN HA", 11); + HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipv6addr, 16); + } + + HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length); + HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len); + + /* + * Put key into WiMAX-RRQ-MN-HA-Key + */ + vp = pairfind(request->reply->vps, WIMAX2ATTR(19)); + if (!vp) { + vp = radius_paircreate(request, &request->reply->vps, + WIMAX2ATTR(19), PW_TYPE_OCTETS); + } + if (!vp) { + RDEBUG("WARNING: Failed creating WiMAX-RRQ-MN-HA-Key"); + } else { + memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len); + vp->length = rk1_len; + } + + /* + * If WiMAX-RRQ-HA-IP exists in request it must also be in + * the reply. Insert WiMAX-RRQ-HA-IP into reply list as well. + */ + vp = pairfind(request->reply->vps, WIMAX2ATTR(18)); + if (!vp) { + vp = radius_paircreate(request, &request->reply->vps, + WIMAX2ATTR(18), PW_TYPE_COMBO_IP); + } + if (!vp) { + RDEBUG("WARNING: Failed creating WiMAX-RRQ-HA-IP in reply list"); + } else { + if (ip->type == PW_TYPE_IPADDR) { + vp->vp_ipaddr = ip->vp_ipaddr; /* IPv4 */ + vp->type = PW_TYPE_IPADDR; + vp->length = 4; + } + if (ip->type == PW_TYPE_IPV6ADDR) { + vp->vp_ipv6addr = ip->vp_ipv6addr; /* IPv6 */ + vp->type = PW_TYPE_IPV6ADDR; + vp->length = 16; + } + } + } /* * Give additional information about requests && responses * - * WiMAX-RRQ-MN-HA-SPI + * WiMAX-HA-RK-Requested */ - vp = pairfind(request->packet->vps, WIMAX2ATTR(20)); - if (vp) { - RDEBUG("Client requested MN-HA key: Should use SPI to look up key from storage."); - if (!mn_nai) { - RDEBUG("WARNING: MN-NAI was not found!"); - } - - /* - * WiMAX-RRQ-HA-IP - */ - if (!pairfind(request->packet->vps, WIMAX2ATTR(18))) { - RDEBUG("WARNING: HA-IP was not found!"); - } - - - /* - * WiMAX-HA-RK-Key-Requested - */ - vp = pairfind(request->packet->vps, WIMAX2ATTR(58)); - if (vp && (vp->vp_integer == 1)) { - RDEBUG("Client requested HA-RK: Should use IP to look it up from storage."); - } + vp = pairfind(request->packet->vps, WIMAX2ATTR(58)); + if (vp && (vp->vp_integer == 1)) { + RDEBUG("Client requested HA-RK: Should use IP to look it up from storage."); } /*