separate messages for separate error cases
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_fast / eap_fast.c
index 2f87dc2..244b460 100644 (file)
@@ -615,7 +615,7 @@ VALUE_PAIR *eap_fast_fast2vp(REQUEST *request, SSL *ssl, uint8_t const *data, si
        DICT_ATTR const *da;
 
        if (!fast_da)
-               fast_da = dict_attrbyvalue(PW_EAP_FAST_TLV, 0);
+               fast_da = dict_attrbyvalue(PW_FREERADIUS_EAP_FAST_TLV, VENDORPEC_FREERADIUS);
        rad_assert(fast_da != NULL);
 
        if (!out) {
@@ -1033,6 +1033,18 @@ static PW_CODE eap_fast_eap_payload(REQUEST *request, eap_handler_t *eap_session
                }
        }
 
+       if (t->copy_request_to_tunnel) {
+               eapfast_copy_request_to_tunnel(request, fake);
+       }
+
+       if ((vp = fr_pair_find_by_num(request->config, PW_VIRTUAL_SERVER, 0, TAG_ANY)) != NULL) {
+               fake->server = vp->vp_strvalue;
+
+       } else if (t->virtual_server) {
+               fake->server = t->virtual_server;
+
+       } /* else fake->server == request->server */
+
        /*
         * Call authentication recursively, which will
         * do PAP, CHAP, MS-CHAP, etc.
@@ -1166,9 +1178,9 @@ static PW_CODE eap_fast_crypto_binding(REQUEST *request, UNUSED eap_handler_t *e
        return PW_CODE_ACCESS_ACCEPT;
 }
 
-#define EAP_FAST_TLV_VENDOR_ID 0xa7000000
-#define EAP_FAST_TLV_SUB_ID(_id)    (EAP_FAST_TLV_VENDOR_ID | _id)
-#define EAP_FAST_PAC_SUB_ID(_id)    ( (_id << 0 ) | 0x0b)
+
+#define PW_EAP_FAST_TLV_PAC (PW_FREERADIUS_EAP_FAST_TLV | (EAP_FAST_TLV_PAC << 8))
+
 
 
 static PW_CODE eap_fast_process_tlvs(REQUEST *request, eap_handler_t *eap_session,
@@ -1182,21 +1194,19 @@ static PW_CODE eap_fast_process_tlvs(REQUEST *request, eap_handler_t *eap_sessio
        for (vp = fr_cursor_init(&cursor, &fast_vps); vp; vp = fr_cursor_next(&cursor)) {
                PW_CODE code = PW_CODE_ACCESS_REJECT;
                char *value;
-        unsigned int parent = vp->da->vendor;
-        if (parent != EAP_FAST_TLV_VENDOR_ID) {
-                       value = vp_aprints_value(request->packet, vp, '"');
+               DICT_ATTR const *parent_da = NULL;
+               parent_da = dict_parent(vp->da->attr, vp->da->vendor);
+               if (parent_da == NULL || vp->da->vendor != VENDORPEC_FREERADIUS ||
+                       ((vp->da->attr & 0xff) != PW_FREERADIUS_EAP_FAST_TLV)) {
+                       value = vp_aprints(request->packet, vp, '"');
                        RDEBUG2("ignoring non-EAP-FAST TLV %s", value);
                        talloc_free(value);
                        continue;
-        }
-        if (vp->da->attr & 0xff00) {
-            parent |= (vp->da->attr & 0xff);
-        }
-        RDEBUG("vp->da->vendor 0x%08x, vp->da->attr 0x%08x", vp->da->vendor, vp->da->attr);
+               }
 
-               switch (parent) {
-               case EAP_FAST_TLV_VENDOR_ID:
-                       switch (vp->da->attr) {
+               switch (parent_da->attr) {
+               case PW_FREERADIUS_EAP_FAST_TLV:
+                       switch (vp->da->attr >> 8) {
                        case EAP_FAST_TLV_EAP_PAYLOAD:
                                code = eap_fast_eap_payload(request, eap_session, tls_session, vp);
                                if (code == PW_CODE_ACCESS_ACCEPT)
@@ -1207,13 +1217,13 @@ static PW_CODE eap_fast_process_tlvs(REQUEST *request, eap_handler_t *eap_sessio
                                code = PW_CODE_ACCESS_ACCEPT;
                                t->stage = PROVISIONING;
                                break;
-            case EAP_FAST_TLV_CRYPTO_BINDING:
-                if (!binding) {
-                    binding = talloc_zero(request->packet, eap_tlv_crypto_binding_tlv_t);
-                    memcpy(binding, vp->vp_octets, sizeof(*binding));
-                    binding->tlv_type = htons(EAP_FAST_TLV_MANDATORY | EAP_FAST_TLV_CRYPTO_BINDING);
-                    binding->length = htons(sizeof(*binding) - 2 * sizeof(uint16_t));
-                }
+                       case EAP_FAST_TLV_CRYPTO_BINDING:
+                               if (!binding) {
+                                       binding = talloc_zero(request->packet, eap_tlv_crypto_binding_tlv_t);
+                                       memcpy(binding, vp->vp_octets, sizeof(*binding));
+                                       binding->tlv_type = htons(EAP_FAST_TLV_MANDATORY | EAP_FAST_TLV_CRYPTO_BINDING);
+                                       binding->length = htons(sizeof(*binding) - 2 * sizeof(uint16_t));
+                               }
                                continue;
                        default:
                                value = vp_aprints_value(request->packet, vp, '"');
@@ -1222,8 +1232,8 @@ static PW_CODE eap_fast_process_tlvs(REQUEST *request, eap_handler_t *eap_sessio
                                continue;
                        }
                        break;
-               case EAP_FAST_TLV_SUB_ID(EAP_FAST_TLV_PAC):
-                       switch ( ( vp->da->attr >> 8 )) {
+               case PW_EAP_FAST_TLV_PAC:
+                       switch ( ( vp->da->attr >> 16 )) {
                        case PAC_INFO_PAC_ACK:
                                if (vp->vp_integer == EAP_FAST_TLV_RESULT_SUCCESS) {
                                        code = PW_CODE_ACCESS_ACCEPT;
@@ -1240,15 +1250,15 @@ static PW_CODE eap_fast_process_tlvs(REQUEST *request, eap_handler_t *eap_sessio
                                t->pac.send = true;
                                continue;
                        default:
-                               value = vp_aprints_value(request->packet, vp, '"');
+                               value = vp_aprints(request->packet, vp, '"');
                                RDEBUG2("ignoring unknown EAP-FAST-PAC-TLV %s", value);
                                talloc_free(value);
                                continue;
                        }
                        break;
                default:
-                       value = vp_aprints_value(request->packet, vp, '"');
-                       RDEBUG2("ignoring non-EAP-FAST TLV %s", value);
+                       value = vp_aprints(request->packet, vp, '"');
+                       RDEBUG2("ignoring EAP-FAST TLV %s", value);
                        talloc_free(value);
                        continue;
                }
@@ -1374,8 +1384,14 @@ PW_CODE eap_fast_process(eap_handler_t *eap_session, tls_session_t *tls_session)
                /*
                 * RFC 5422 section 3.5 - Network Access after EAP-FAST Provisioning
                 */
-               if ((t->pac.type && t->pac.expired) || t->mode == EAP_FAST_PROVISIONING_ANON) {
-                       RDEBUG("Rejecting expired PAC or unauthenticated provisioning");
+               if (t->pac.type && t->pac.expired) {
+                       REDEBUG("Rejecting expired PAC.");
+                       code = PW_CODE_ACCESS_REJECT;
+                       break;
+               }
+
+               if (t->mode == EAP_FAST_PROVISIONING_ANON) {
+                       REDEBUG("Rejecting unauthenticated provisioning");
                        code = PW_CODE_ACCESS_REJECT;
                        break;
                }
@@ -1391,8 +1407,9 @@ PW_CODE eap_fast_process(eap_handler_t *eap_session, tls_session_t *tls_session)
                eap_add_reply(request, "EAP-EMSK", t->emsk, EAP_EMSK_LEN);
 
                break;
+
        default:
-               RERROR("no idea! %d", t->stage);
+               RERROR("Internal sanity check failed in EAP-FAST at %d", t->stage);
                code = PW_CODE_ACCESS_REJECT;
        }