📄 rlm_eap.c
字号:
} } /* * Delete the "proxied to" attribute, as it's * set to 127.0.0.1 for tunneled requests, and * we don't want to tell the world that... */ pairdelete(&request->proxy->vps, PW_FREERADIUS_PROXIED_TO); DEBUG2(" Tunneled session will be proxied. Not doing EAP."); return RLM_MODULE_HANDLED; } /* * We are done, wrap the EAP-request in RADIUS to send * with all other required radius attributes */ rcode = eap_compose(handler); /* * Add to the list only if it is EAP-Request, OR if * it's LEAP, and a response. */ if ((handler->eap_ds->request->code == PW_EAP_REQUEST) && (handler->eap_ds->request->type.type >= PW_EAP_MD5)) { eaplist_add(inst, handler); /* * LEAP is a little different. At Stage 4, * it sends an EAP-Success message, but we still * need to keep the State attribute & session * data structure around for the AP Challenge. * * At stage 6, LEAP sends an EAP-Response, which * isn't put into the list. */ } else if ((handler->eap_ds->response->code == PW_EAP_RESPONSE) && (handler->eap_ds->response->type.type == PW_EAP_LEAP) && (handler->eap_ds->request->code == PW_EAP_SUCCESS) && (handler->eap_ds->request->type.type == 0)) { eaplist_add(inst, handler); } else { DEBUG2(" rlm_eap: Freeing handler"); /* handler is not required any more, free it now */ eap_handler_free(handler); } /* * If it's an Access-Accept, RFC 2869, Section 2.3.1 * says that we MUST include a User-Name attribute in the * Access-Accept. */ if ((request->reply->code == PW_AUTHENTICATION_ACK) && request->username) { VALUE_PAIR *vp; /* * Doesn't exist, add it in. */ vp = pairfind(request->reply->vps, PW_USER_NAME); if (!vp) { vp = pairmake("User-Name", request->username->strvalue, T_OP_EQ); rad_assert(vp != NULL); pairadd(&(request->reply->vps), vp); } /* * Cisco AP1230 has a bug and needs a zero * terminated string in Access-Accept. */ if ((inst->cisco_accounting_username_bug) && (vp->length < (int) sizeof(vp->strvalue))) { vp->strvalue[vp->length] = '\0'; vp->length++; } } return rcode;}/* * EAP authorization DEPENDS on other rlm authorizations, * to check for user existance & get their configured values. * It Handles EAP-START Messages, User-Name initilization. */static int eap_authorize(void *instance, REQUEST *request){ rlm_eap_t *inst; int status; VALUE_PAIR *vp; inst = (rlm_eap_t *)instance; /* * We don't do authorization again, once we've seen the * proxy reply (or the proxied packet) */ if (request->proxy != NULL) return RLM_MODULE_NOOP; /* * For EAP_START, send Access-Challenge with EAP Identity * request. even when we have to proxy this request * * RFC 2869, Section 2.3.1 notes that the "domain" of the * user, (i.e. where to proxy him) comes from the EAP-Identity, * so we CANNOT proxy the user, until we know his identity. * * We therefore send an EAP Identity request. */ status = eap_start(inst, request); switch(status) { case EAP_NOOP: return RLM_MODULE_NOOP; case EAP_FAIL: return RLM_MODULE_FAIL; case EAP_FOUND: return RLM_MODULE_HANDLED; case EAP_NOTFOUND: default: break; } /* * RFC 2869, Section 2.3.1. If a NAS sends an EAP-Identity, * it MUST copy the identity into the User-Name attribute. * * But we don't worry about that too much. We depend on * each EAP sub-module to look for handler->request->username, * and to get excited if it doesn't appear. */ vp = pairfind(request->config_items, PW_AUTH_TYPE); if ((!vp) || (vp->lvalue != PW_AUTHTYPE_REJECT)) { vp = pairmake("Auth-Type", "EAP", T_OP_EQ); if (!vp) { return RLM_MODULE_FAIL; } pairadd(&request->config_items, vp); } return RLM_MODULE_UPDATED;}/* * If we're proxying EAP, then there may be magic we need * to do. */static int eap_post_proxy(void *inst, REQUEST *request){ int i, len; VALUE_PAIR *vp; EAP_HANDLER *handler; /* * If there was a handler associated with this request, * then it's a tunneled request which was proxied... */ handler = request_data_get(request, inst, REQUEST_DATA_EAP_HANDLER); if (handler != NULL) { int rcode; eap_tunnel_data_t *data; /* * Grab the tunnel callbacks from the request. */ data = (eap_tunnel_data_t *) request_data_get(request, request->proxy, REQUEST_DATA_EAP_TUNNEL_CALLBACK); if (!data) { radlog(L_ERR, "rlm_eap: Failed to retrieve callback for tunneled session!"); eap_handler_free(handler); return RLM_MODULE_FAIL; } /* * Do the callback... */ rcode = data->callback(handler, data->tls_session); free(data); if (rcode == 0) { eap_fail(handler); eap_handler_free(handler); return RLM_MODULE_REJECT; } /* * We are done, wrap the EAP-request in RADIUS to send * with all other required radius attributes */ rcode = eap_compose(handler); /* * Add to the list only if it is EAP-Request, OR if * it's LEAP, and a response. */ if ((handler->eap_ds->request->code == PW_EAP_REQUEST) && (handler->eap_ds->request->type.type >= PW_EAP_MD5)) { eaplist_add(inst, handler); } else { /* couldn't have been LEAP, there's no tunnel */ DEBUG2(" rlm_eap: Freeing handler"); /* handler is not required any more, free it now */ eap_handler_free(handler); } /* * If it's an Access-Accept, RFC 2869, Section 2.3.1 * says that we MUST include a User-Name attribute in the * Access-Accept. */ if ((request->reply->code == PW_AUTHENTICATION_ACK) && request->username) { /* * Doesn't exist, add it in. */ vp = pairfind(request->reply->vps, PW_USER_NAME); if (!vp) { vp = pairmake("User-Name", request->username->strvalue, T_OP_EQ); rad_assert(vp != NULL); pairadd(&(request->reply->vps), vp); } } return RLM_MODULE_OK; } /* * There may be more than one Cisco-AVPair. * Ensure we find the one with the LEAP attribute. */ vp = request->proxy_reply->vps; for (;;) { /* * Hmm... there's got to be a better way to * discover codes for vendor attributes. * * This is vendor Cisco (9), Cisco-AVPair * attribute (1) */ vp = pairfind(vp, (9 << 16) | 1); if (!vp) { return RLM_MODULE_NOOP; } /* * If it's "leap:session-key", then stop. * * The format is VERY specific! */ if (strncasecmp(vp->strvalue, "leap:session-key=", 17) == 0) { break; } /* * Not this AV-pair. Go to the next one. */ vp = vp->next; } /* * The format is very specific. */ if (vp->length != 17 + 34) { DEBUG2(" rlm_eap: Cisco-AVPair with leap:session-key has incorrect length %d: Expected %d", vp->length, 17 + 34); return RLM_MODULE_NOOP; } /* * Decrypt the session key, using the proxy data. */ i = 34; /* starts off with 34 octets */ len = rad_tunnel_pwdecode(vp->strvalue + 17, &i, request->proxysecret, request->proxy->vector); /* * FIXME: Assert that i == 16. */ /* * Encrypt the session key again, using the request data. */ rad_tunnel_pwencode(vp->strvalue + 17, &len, request->secret, request->packet->vector); return RLM_MODULE_UPDATED;}/* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. */module_t rlm_eap = { "eap", RLM_TYPE_THREAD_SAFE, /* type */ NULL, /* initialization */ eap_instantiate, /* instantiation */ { eap_authenticate, /* authentication */ eap_authorize, /* authorization */ NULL, /* preaccounting */ NULL, /* accounting */ NULL, /* checksimul */ NULL, /* pre-proxy */ eap_post_proxy, /* post-proxy */ NULL /* post-auth */ }, eap_detach, /* detach */ NULL, /* destroy */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -