/*
* FIXME: Fix the build system to create definitions from names.
*/
-#define WIMAX2ATTR(x) ((24757 << 16) | (x))
+typedef struct rlm_wimax_t {
+ int delete_mppe_keys;
+} rlm_wimax_t;
+
+/*
+ * A mapping of configuration file names to internal variables.
+ *
+ * Note that the string is dynamically allocated, so it MUST
+ * be freed. When the configuration file parse re-reads the string,
+ * it free's the old one, and strdup's the new one, placing the pointer
+ * to the strdup'd string into 'config.string'. This gets around
+ * buffer over-flows.
+ */
+static const CONF_PARSER module_config[] = {
+ { "delete_mppe_keys", PW_TYPE_BOOLEAN,
+ offsetof(rlm_wimax_t,delete_mppe_keys), NULL, "no" },
+
+ { NULL, -1, 0, NULL, NULL } /* end the list */
+};
+
+
+/*
+ * Only free memory we allocated. The strings allocated via
+ * cf_section_parse() do not need to be freed.
+ */
+static int wimax_detach(void *instance)
+{
+ free(instance);
+ return 0;
+}
+
+/*
+ * Do any per-module initialization that is separate to each
+ * configured instance of the module. e.g. set up connections
+ * to external databases, read configuration files, set up
+ * dictionary entries, etc.
+ *
+ * If configuration information is given in the config section
+ * that must be referenced in later calls, store a handle to it
+ * in *instance otherwise put a null pointer there.
+ */
+static int wimax_instantiate(CONF_SECTION *conf, void **instance)
+{
+ rlm_wimax_t *inst;
+
+ /*
+ * Set up a storage area for instance data
+ */
+ inst = rad_malloc(sizeof(*inst));
+ if (!inst) {
+ return -1;
+ }
+ memset(inst, 0, sizeof(*inst));
+
+ /*
+ * If the configuration parameters can't be parsed, then
+ * fail.
+ */
+ if (cf_section_parse(conf, inst, module_config) < 0) {
+ wimax_detach(inst);
+ return -1;
+ }
+
+ *instance = inst;
+
+ return 0;
+}
/*
* Find the named user in this modules database. Create the set
/*
* Fix Calling-Station-Id. Damn you, WiMAX!
*/
- vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID);
+ vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0);
if (vp && (vp->length == 6)) {
int i;
uint8_t buffer[6];
vp->length = (5*3)+2;
DEBUG2("rlm_wimax: Fixing WiMAX binary Calling-Station-Id to %s",
- buffer);
+ vp->vp_strvalue);
}
return RLM_MODULE_OK;
/*
* Generate the keys after the user has been authenticated.
*/
-static int wimax_postauth(UNUSED void *instance, REQUEST *request)
+static int wimax_postauth(void *instance, REQUEST *request)
{
+ rlm_wimax_t *inst = instance;
VALUE_PAIR *msk, *emsk, *vp;
VALUE_PAIR *mn_nai, *ip, *fa_rk;
HMAC_CTX hmac;
uint8_t mip_rk_1[EVP_MAX_MD_SIZE], mip_rk_2[EVP_MAX_MD_SIZE];
uint8_t mip_rk[2 * EVP_MAX_MD_SIZE];
- msk = pairfind(request->reply->vps, 1129);
- emsk = pairfind(request->reply->vps, 1130);
+ msk = pairfind(request->reply->vps, 1129, 0);
+ emsk = pairfind(request->reply->vps, 1130, 0);
if (!msk || !emsk) {
RDEBUG("No EAP-MSK or EAP-EMSK. Cannot create WiMAX keys.");
return RLM_MODULE_NOOP;
}
/*
+ * If we delete the MS-MPPE-*-Key attributes, then add in
+ * the WiMAX-MSK so that the client has a key available.
+ */
+ if (inst->delete_mppe_keys) {
+ pairdelete(&request->reply->vps, 16, VENDORPEC_MICROSOFT);
+ pairdelete(&request->reply->vps, 17, VENDORPEC_MICROSOFT);
+
+ vp = radius_pairmake(request, &request->reply->vps, "WiMAX-MSK", "0x00", T_OP_EQ);
+ if (vp) {
+ memcpy(vp->vp_octets, msk->vp_octets, msk->length);
+ vp->length = msk->length;
+ }
+ }
+
+ /*
* Initialize usage data.
*/
memcpy(usage_data, "miprk@wimaxforum.org", 21); /* with trailing \0 */
/*
* MIP-RK-2 = HMAC-SSHA256(EMSK, MIP-RK-1 | usage-data | 0x01)
*/
- HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, emsk->vp_octets, emsk->length, EVP_sha256(), NULL);
HMAC_Update(&hmac, (const uint8_t *) &mip_rk_1, rk1_len);
HMAC_Update(&hmac, &usage_data[0], sizeof(usage_data));
HMAC_Final(&hmac, &mip_rk_2[0], &rk2_len);
- vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT);
+ vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT, 0);
if (vp) rk_lifetime = vp->vp_integer;
memcpy(mip_rk, mip_rk_1, rk1_len);
/*
* MIP-SPI = HMAC-SSHA256(MIP-RK, "SPI CMIP PMIP");
*/
- HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha256(), NULL);
HMAC_Update(&hmac, (const uint8_t *) "SPI CMIP PMIP", 12);
/*
* Calculate mobility keys
*/
- mn_nai = pairfind(request->packet->vps, 1900);
- if (!mn_nai) mn_nai = pairfind(request->reply->vps, 1900);
+ mn_nai = pairfind(request->packet->vps, 1900, 0);
+ if (!mn_nai) mn_nai = pairfind(request->reply->vps, 1900, 0);
if (!mn_nai) {
RDEBUG("WARNING: WiMAX-MN-NAI was not found in the request or in the reply.");
RDEBUG("WARNING: We cannot calculate MN-HA keys.");
* WiMAX-IP-Technology
*/
vp = NULL;
- if (mn_nai) vp = pairfind(request->reply->vps, WIMAX2ATTR(23));
+ if (mn_nai) vp = pairfind(request->reply->vps, 23, VENDORPEC_WIMAX);
if (!vp) {
RDEBUG("WARNING: WiMAX-IP-Technology not found in reply.");
RDEBUG("WARNING: Not calculating MN-HA keys");
/*
* Look for WiMAX-hHA-IP-MIP4
*/
- ip = pairfind(request->reply->vps, WIMAX2ATTR(6));
+ ip = pairfind(request->reply->vps, 6, VENDORPEC_WIMAX);
if (!ip) {
RDEBUG("WARNING: WiMAX-hHA-IP-MIP4 not found. Cannot calculate MN-HA-PMIP4 key");
break;
* MN-HA-PMIP4 =
* H(MIP-RK, "PMIP4 MN HA" | HA-IPv4 | MN-NAI);
*/
- HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);
HMAC_Update(&hmac, (const uint8_t *) "PMIP4 MN HA", 11);
/*
* Put MN-HA-PMIP4 into WiMAX-MN-hHA-MIP4-Key
*/
- vp = pairfind(request->reply->vps, WIMAX2ATTR(10));
+ vp = pairfind(request->reply->vps, 10, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(10), PW_TYPE_OCTETS);
+ 10, VENDORPEC_WIMAX, PW_TYPE_OCTETS);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-Key");
/*
* Put MN-HA-PMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI
*/
- vp = pairfind(request->reply->vps, WIMAX2ATTR(11));
+ vp = pairfind(request->reply->vps, 11, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(11), PW_TYPE_INTEGER);
+ 11, VENDORPEC_WIMAX, PW_TYPE_INTEGER);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-SPI");
/*
* Look for WiMAX-hHA-IP-MIP4
*/
- ip = pairfind(request->reply->vps, WIMAX2ATTR(6));
+ ip = pairfind(request->reply->vps, 6, VENDORPEC_WIMAX);
if (!ip) {
RDEBUG("WARNING: WiMAX-hHA-IP-MIP4 not found. Cannot calculate MN-HA-CMIP4 key");
break;
* MN-HA-CMIP4 =
* H(MIP-RK, "CMIP4 MN HA" | HA-IPv4 | MN-NAI);
*/
- HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);
HMAC_Update(&hmac, (const uint8_t *) "CMIP4 MN HA", 11);
/*
* Put MN-HA-CMIP4 into WiMAX-MN-hHA-MIP4-Key
*/
- vp = pairfind(request->reply->vps, WIMAX2ATTR(10));
+ vp = pairfind(request->reply->vps, 10, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(10), PW_TYPE_OCTETS);
+ 10, VENDORPEC_WIMAX, PW_TYPE_OCTETS);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-Key");
/*
* Put MN-HA-CMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI
*/
- vp = pairfind(request->reply->vps, WIMAX2ATTR(11));
+ vp = pairfind(request->reply->vps, 11, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(11), PW_TYPE_INTEGER);
+ 11, VENDORPEC_WIMAX, PW_TYPE_INTEGER);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-SPI");
/*
* Look for WiMAX-hHA-IP-MIP6
*/
- ip = pairfind(request->reply->vps, WIMAX2ATTR(7));
+ ip = pairfind(request->reply->vps, 7, VENDORPEC_WIMAX);
if (!ip) {
RDEBUG("WARNING: WiMAX-hHA-IP-MIP6 not found. Cannot calculate MN-HA-CMIP6 key");
break;
* MN-HA-CMIP6 =
* H(MIP-RK, "CMIP6 MN HA" | HA-IPv6 | MN-NAI);
*/
- HMAC_CTX_init(&hmac);
HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);
HMAC_Update(&hmac, (const uint8_t *) "CMIP6 MN HA", 11);
/*
* Put MN-HA-CMIP6 into WiMAX-MN-hHA-MIP6-Key
*/
- vp = pairfind(request->reply->vps, WIMAX2ATTR(12));
+ vp = pairfind(request->reply->vps, 12, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(12), PW_TYPE_OCTETS);
+ 12, VENDORPEC_WIMAX, PW_TYPE_OCTETS);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP6-Key");
/*
* Put MN-HA-CMIP6-SPI into WiMAX-MN-hHA-MIP6-SPI
*/
- vp = pairfind(request->reply->vps, WIMAX2ATTR(13));
+ vp = pairfind(request->reply->vps, 13, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(13), PW_TYPE_INTEGER);
+ 13, VENDORPEC_WIMAX, PW_TYPE_INTEGER);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP6-SPI");
*
* FA-RK= H(MIP-RK, "FA-RK")
*/
- fa_rk = pairfind(request->reply->vps, WIMAX2ATTR(14));
- if (fa_rk && (fa_rk->length == 0)) {
- HMAC_CTX_init(&hmac);
+ fa_rk = pairfind(request->reply->vps, 14, VENDORPEC_WIMAX);
+ if (fa_rk && (fa_rk->length <= 1)) {
HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);
HMAC_Update(&hmac, (const uint8_t *) "FA-RK", 5);
* really MIP-SPI. Clear? Of course. This is WiMAX.
*/
if (fa_rk) {
- vp = pairfind(request->reply->vps, WIMAX2ATTR(61));
+ vp = pairfind(request->reply->vps, 61, VENDORPEC_WIMAX);
if (!vp) {
vp = radius_paircreate(request, &request->reply->vps,
- WIMAX2ATTR(61), PW_TYPE_INTEGER);
+ 61, VENDORPEC_WIMAX, PW_TYPE_INTEGER);
}
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-FA-RK-SPI");
/*
* Generate MN-FA = H(FA-RK, "MN FA" | FA-IP | MN-NAI)
*/
- ip = pairfind(request->reply->vps, 1901);
+ ip = pairfind(request->reply->vps, 1901, 0);
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_Final(&hmac, &mip_rk_1[0], &rk1_len);
vp = radius_paircreate(request, &request->reply->vps,
- 1902, PW_TYPE_OCTETS);
+ 1902, 0, PW_TYPE_OCTETS);
if (!vp) {
RDEBUG("WARNING: Failed creating WiMAX-MN-FA");
} else {
*
* WiMAX-RRQ-MN-HA-SPI
*/
- vp = pairfind(request->packet->vps, WIMAX2ATTR(20));
+ vp = pairfind(request->packet->vps, 20, VENDORPEC_WIMAX);
if (vp) {
RDEBUG("Client requested MN-HA key: Should use SPI to look up key from storage.");
if (!mn_nai) {
/*
* WiMAX-RRQ-HA-IP
*/
- if (!pairfind(request->packet->vps, WIMAX2ATTR(18))) {
+ if (!pairfind(request->packet->vps, 18, VENDORPEC_WIMAX)) {
RDEBUG("WARNING: HA-IP was not found!");
}
/*
* WiMAX-HA-RK-Key-Requested
*/
- vp = pairfind(request->packet->vps, WIMAX2ATTR(58));
+ vp = pairfind(request->packet->vps, 58, VENDORPEC_WIMAX);
if (vp && (vp->vp_integer == 1)) {
RDEBUG("Client requested HA-RK: Should use IP to look it up from storage.");
}
RLM_MODULE_INIT,
"wimax",
RLM_TYPE_THREAD_SAFE, /* type */
- NULL, /* instantiation */
- NULL, /* detach */
+ wimax_instantiate, /* instantiation */
+ wimax_detach, /* detach */
{
NULL, /* authentication */
wimax_authorize, /* authorization */