track TLS cache filename
[freeradius.git] / src / modules / rlm_eap / rlm_eap.c
index 1a2e614..38b6829 100644 (file)
@@ -30,14 +30,15 @@ RCSID("$Id$")
 
 #include "rlm_eap.h"
 
+#include <sys/stat.h>
+
 static const CONF_PARSER module_config[] = {
        { "default_eap_type", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_t, default_method_name), "md5" },
        { "timer_expire", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_t, timer_limit), "60" },
        { "ignore_unknown_eap_types", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, ignore_unknown_types), "no" },
        { "cisco_accounting_username_bug", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_t, mod_accounting_username_bug), "no" },
        { "max_sessions", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_t, max_sessions), "2048" },
-
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
+       CONF_PARSER_TERMINATOR
 };
 
 /*
@@ -114,12 +115,17 @@ static int mod_instantiate(CONF_SECTION *cs, void *instance)
        inst->xlat_name = cf_section_name2(cs);
        if (!inst->xlat_name) inst->xlat_name = "EAP";
 
+       if (!dict_valbyname(PW_AUTH_TYPE, 0, inst->xlat_name)) {
+               cf_log_err_cs(cs, "Failed to find 'Auth-Type %s' section.  Cannot authenticate users.",
+                             inst->xlat_name);
+               return -1;
+       }
+
        /* Load all the configured EAP-Types */
        num_methods = 0;
        for(scs = cf_subsection_find_next(cs, NULL, NULL);
            scs != NULL;
            scs = cf_subsection_find_next(cs, scs, NULL)) {
-
                char const *name;
 
                name = cf_section_name1(scs);
@@ -127,6 +133,12 @@ static int mod_instantiate(CONF_SECTION *cs, void *instance)
 
                if (!strcmp(name, TLS_CONFIG_SECTION))  continue;
 
+               /*
+                *      Easier sometimes than commenting out blocks,
+                *      or deleting blocks.
+                */
+               if (!strcmp(name, "disable")) continue;
+
                method = eap_name2type(name);
                if (method == PW_EAP_INVALID) {
                        cf_log_err_cs(cs, "No dictionary definition for EAP method %s", name);
@@ -151,12 +163,17 @@ static int mod_instantiate(CONF_SECTION *cs, void *instance)
                 *      etc. configurations from eap.conf in order to
                 *      have EAP without the TLS types.
                 */
-               if ((method == PW_EAP_TLS) ||
-                   (method == PW_EAP_TTLS) ||
-                   (method == PW_EAP_PEAP)) {
-                       DEBUG2("rlm_eap (%s): Ignoring EAP method %s because we do not have OpenSSL support",
-                              inst->xlat_name, name);
+               switch (method) {
+               case PW_EAP_TLS:
+               case PW_EAP_TTLS:
+               case PW_EAP_PEAP:
+               case PW_EAP_PWD:
+                       WARN("rlm_eap (%s): Ignoring EAP method %s because we don't have OpenSSL support",
+                            inst->xlat_name, name);
                        continue;
+
+               default:
+                       break;
                }
 #endif
 
@@ -239,8 +256,8 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *re
        inst = (rlm_eap_t *) instance;
 
        if (!fr_pair_find_by_num(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               REDEBUG("You set 'Auth-Type = EAP' for a request that does "
-                       "not contain an EAP-Message attribute!");
+               REDEBUG("You set 'Auth-Type = %s' for a request that does "
+                       "not contain an EAP-Message attribute!", inst->xlat_name);
                return RLM_MODULE_INVALID;
        }
 
@@ -342,7 +359,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *re
                 */
                fr_pair_delete_by_num(&request->proxy->vps, PW_FREERADIUS_PROXIED_TO, VENDORPEC_FREERADIUS, TAG_ANY);
 
-               RDEBUG2("Tunneled session will be proxied.  Not doing EAP");
+               RWDEBUG2("Tunneled session will be proxied.  Not doing EAP");
                return RLM_MODULE_HANDLED;
        }
 #endif
@@ -397,6 +414,26 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *re
        }
 
        /*
+        *      Enable the cached entry on success.
+        */
+       if (handler->eap_ds->request->code == PW_EAP_SUCCESS) {
+               VALUE_PAIR *vp;
+
+               vp = fr_pair_find_by_num(request->state, PW_TLS_CACHE_FILENAME, 0, TAG_ANY);
+               if (vp) (void) chmod(vp->vp_strvalue, S_IRUSR | S_IWUSR);
+       }
+
+       /*
+        *      Disable the cached entry on failure.
+        */
+       if (handler->eap_ds->request->code == PW_EAP_FAILURE) {
+               VALUE_PAIR *vp;
+
+               vp = fr_pair_find_by_num(request->state, PW_TLS_CACHE_FILENAME, 0, TAG_ANY);
+               if (vp) (void) unlink(vp->vp_strvalue);
+       }
+
+       /*
         *      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.
@@ -514,6 +551,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *inst, REQUEST *request)
 {
        size_t          i;
        size_t          len;
+       ssize_t         ret;
        char            *p;
        VALUE_PAIR      *vp;
        eap_handler_t   *handler;
@@ -656,18 +694,30 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *inst, REQUEST *request)
        i = 34;
        p = talloc_memdup(vp, vp->vp_strvalue, vp->vp_length + 1);
        talloc_set_type(p, uint8_t);
-       len = rad_tunnel_pwdecode((uint8_t *)p + 17, &i, request->home_server->secret, request->proxy->vector);
+       ret = rad_tunnel_pwdecode((uint8_t *)p + 17, &i, request->home_server->secret, request->proxy->vector);
+       if (ret < 0) {
+               REDEBUG("Decoding leap:session-key failed");
+               talloc_free(p);
+               return RLM_MODULE_FAIL;
+       }
+       len = i;
 
-       /*
-        *      FIXME: Assert that i == 16.
-        */
+       if (i != 16) {
+               REDEBUG("Decoded key length is incorrect, must be 16 bytes");
+               talloc_free(p);
+               return RLM_MODULE_FAIL;
+       }
 
        /*
         *      Encrypt the session key again, using the request data.
         */
-       rad_tunnel_pwencode(p + 17, &len,
-                           request->client->secret,
-                           request->packet->vector);
+       ret = rad_tunnel_pwencode(p + 17, &len, request->client->secret, request->packet->vector);
+       if (ret < 0) {
+               REDEBUG("Decoding leap:session-key failed");
+               talloc_free(p);
+               return RLM_MODULE_FAIL;
+       }
+
        fr_pair_value_strsteal(vp, p);
 
        return RLM_MODULE_UPDATED;
@@ -689,12 +739,12 @@ static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *reque
        if (!vp || (vp->vp_integer != PW_POST_AUTH_TYPE_REJECT)) return RLM_MODULE_NOOP;
 
        if (!fr_pair_find_by_num(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               RDEBUG2("Request didn't contain an EAP-Message, not inserting EAP-Failure");
+               RDEBUG3("Request didn't contain an EAP-Message, not inserting EAP-Failure");
                return RLM_MODULE_NOOP;
        }
 
        if (fr_pair_find_by_num(request->reply->vps, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               RDEBUG2("Reply already contained an EAP-Message, not inserting EAP-Failure");
+               RDEBUG3("Reply already contained an EAP-Message, not inserting EAP-Failure");
                return RLM_MODULE_NOOP;
        }