Remove rlm_eap2
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 4 Jun 2013 13:16:02 +0000 (09:16 -0400)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 4 Jun 2013 13:17:39 +0000 (09:17 -0400)
The name confuses people and requires a special build of hostapd to work.

Any required EAP methods should be implemented by the rlm_eap module.

raddb/experimental.conf
src/modules/rlm_eap2/all.mk [deleted file]
src/modules/rlm_eap2/rlm_eap2.c [deleted file]

index 4e89c89..3c6a957 100644 (file)
                hash_reload = 600
        }
 
-       # Another implementation of the EAP module.
-       #
-       #  This module requires the libeap.so file from the hostap
-       #  software (http://hostap.epitest.fi/hostapd/).  It has been
-       #  tested on the development version of hostapd (0.6.1) ONLY.
-       #
-       #  In order to use it, you MUST build a "libeap.so" in hostapd,
-       #  which is not done by default.
-       #
-       #  You MUST also edit the file: src/modules/rlm_eap2/Makefile
-       #  to point to the location of the hostap include files.
-       #
-       #  This module CANNOT be used in the same way as the current
-       #  FreeRADIUS "eap" module.  There is NO way to look inside of
-       #  a tunneled request.  There is NO way to proxy a tunneled
-       #  request.  There is NO way to even look at the user name inside
-       #  of the tunneled request.  There is NO way to control the
-       #  choice of EAP types inside of the tunnel.  You MUST force
-       #  the server to choose "eap2" for authentication, because this
-       #  module has no "authorize" section.
-       #
-       #  If you want to use this module for experimentation, please
-       #  post your comments to the freeradius-devel list:
-       #
-       #    http://lists.freeradius.org/mailman/listinfo/freeradius-devel
-       #
-       #  If you want to use this module in a production (i.e. real-world)
-       #  environment:
-       #
-       #       !!! DO NOT USE IT IN A PRODUCTION ENVIRONMENT !!!
-       #
-       #  The module needs additional work to make it ready for
-       #  production use..  Please supply patches, or sponsor the
-       #  work by hiring a developer.  Do NOT ask when the work will
-       #  be done, because there is no plan to finish this module
-       #  unless there is demand for it.
-       #
-       eap2 {
-               #  EAP types are chosen in the order that they are
-               #  listed in this section.  There is no "default_eap_type"
-               #  as with rlm_eap.  Instead, the *first* EAP type is
-               #  used as the default type.
-               #
-               peap {
-               }
-
-               ttls {
-               }
-
-               #  This is the ONLY EAP type that has any configuration.
-               #  All other EAP types have no configuration.
-               #
-               tls {
-                       ca_cert = ${confdir}/certs/ca.pem
-                       server_cert = ${confdir}/certs/server.pem
-                       private_key_file = ${confdir}/certs/server.pem
-                       private_key_password = whatever
-               }
-
-               #
-               #  These next two methods do not supply keying material.
-               #
-               md5 {
-               }
-
-               mschapv2 {
-               }
-
-               fast { 
-                       pac_opaque_encr_key = 000102030405060708090a0b0c0d0e0f 
-                       eap_fast_a_id = xxxxxx 
-                       eap_fast_a_id_info = my_server 
-                       eap_fast_prov = 3
-                       pac_key_lifetime = 604800 # 7 days
-                       pac_key_refresh_tim = 86400
-               } 
-
-               #  LEAP is NOT supported by this module.
-               #  Use the "eap" module instead.
-
-               #  For other methods that MIGHT work, see the
-               #  configuration of hostap.  The methods are statically
-               #  linked in at compile time, and cannot be controlled
-               #  here.
-       }
-
-       #  Configuration for experimental EAP types.  The sub-sections
-       #  can be copied into eap.conf.
-       eap {
-               ikev2 {
-
-               # Server auth type 
-               # Allowed values are:
-               #  cert   - for certificate based server authentication,
-               #           other required settings for this type are
-               #           'private_key_file' and 'certificate_file'
-               #  secret - for shared secret based server authentication, 
-               #           other required settings for this type is 'id'
-               # Default value of this option is 'secret'
-       #     server_authtype=cert
-
-               # Allowed default client auth types
-               # Allowed values are:
-               #   secret - for shared secret based client     authentication
-               #   cert   - for certificate based client authentication
-               #   both   - shared secret and certificate is allowed
-               #   none   - authentication will always fail
-               # Default value for this option is 'both'. This option could
-               #  be overwritten within 'usersfile' file by EAP-IKEv2-Auth
-               #  option. 
-       #   default_authtype = both
-
-               # path to trusted CA certificate file
-               CA_file="/path/to/CA/cacert.pem"
-
-               # path to CRL file, if not set, then there will be no
-               #  checks against CRL
-       #   crl_file="/path/to/crl.pem"
-
-               # path to file with user settings 
-               #
-               #  Note that this file is read ONLY on module initialization!
-               #
-               # default ${confdir}/eap_ikev2_users
-       #   usersfile=${confdir}/eap_ikev2_users
-
-#
-#  Sample "eap_ikev2_users" file entry:
-#
-#username  EAP-IKEv2-IDType := KEY_ID,  EAP-IKEv2-Secret := "tajne"
-
-## where:
-## username           - client user name from IKE-AUTH (IDr)  or CommonName
-##                      from x509 certificate
-## EAP-IKEv2-IDType   - ID Type - same as in expected IDType payload
-##                     allowable attributes for EAP-IKEv2-IDType:
-##                     IPV4_ADDR FQDN RFC822_ADDR IPV6_ADDR DER_ASN1_DN
-##                     DER_ASN1_GN KEY_ID
-## EAP-IKEv2-Secret   - shared secret
-## EAP-IKEv2-AuthType - optional parameter which defines expected client auth
-##                      type. Allowed values are: secret,cert,both,none.
-##                     For the meaning of this values, please see the
-##                      description of 'default_authtype'.
-##                      This attribute can overwrite 'default_authtype' value.
-
-
-
-               # path to  file with server private key
-               private_key_file="/path/to/srv-private-key.pem"
-
-               # password to private key file
-               private_key_password="passwd"
-
-               # path to file with server certificate
-               certificate_file="/path/to/srv-cert.pem"
-
-               # server identity string
-               id="deMaio"
-
-               # Server identity type. Allowed values are:
-               # IPV4_ADDR, FQDN, RFC822_ADDR, IPV6_ADDR, ASN1_DN, ASN1_GN,
-               #  KEY_ID
-               # Default value is:     KEY_ID
-       #   id_type = KEY_ID
-
-
-               # MTU (default: 1398)
-       #   fragment_size = 1398
-    
-               # maximal allowed number of resends SA_INIT after receiving
-               # 'invalid KEY' notification (default 3)
-       #   DH_counter_max = 3
-
-               # option which is used to control whenever send CERT REQ
-               #  payload or not.
-               # Allowed values for this option are "yes" or "no".
-               #Default value is "no".
-       #   certreq = "yes"
-
-               # option which cotrols fast reconnect capability.
-               # Allowed valuse for this option are "yes" or "no".
-               # Default value is "yes".
-       #   enable_fast_reauth = "no"
-    
-               # option which is used to control performing of DH exchange
-               #  during fast rekeying protocol run.
-               # Allowed values for this option are "yes" or "no".
-               # Default value is "no"
-       #   fast_DH_exchange = "yes"
-
-               # Option which is used to set up expiration time of inactive
-               #  IKEv2 session.
-               # After selected period of time (in seconds), inactive
-               # session data will be deleted.
-               # Default value of this option is set to 900 seconds
-       #   fast_timer_expire = 900
-
-               # list of server proposals of available cryptographic
-               # suites
-               proposals {
-                       # proposal number #1 
-                       proposal {
-
-                               # Supported transforms types: encryption,
-                               # prf, integrity, dhgroup. For multiple
-                               # transforms just simple repeat key (i.e.
-                               # integity).
-
-                               # encryption algorithm
-                               # supported algorithms:
-                               # null,3des,aes_128_cbc,aes_192_cbc,
-                               # aes_256_cbc,idea
-                               # blowfish:n, where n range from 8 to 448 bits,
-                               #  step 8 bits
-                               # cast:n, where n range from 40 to 128 bits,
-                               #  step 8 bits 
-                               encryption = 3des
-
-                               # pseudo random function. Supported prf's:
-                               # hmac_md5, hmac_sha1, hmac_tiger
-                               prf = hmac_sha1
-
-                               # integrity algorithm. Supported algorithms:
-                               # hmac_md5_96, hmac_sha1_96,des_mac
-                               integrity = hmac_sha1_96
-                               integrity = hmac_md5_96
-
-                               # Diffie-Hellman groups:
-                               # modp768, modp1024, modp1536, modp2048, 
-                               # modp3072, modp4096, modp6144, modp8192
-                               dhgroup = modp2048 
-                       }
-               
-                       # proposal number #2 
-                       proposal {
-                               encryption = 3des
-                               prf = hmac_md5
-                               integrity = hmac_md5_96
-                               dhgroup = modp1024
-                       }       
-
-                       # proposal number #3 
-                       proposal {
-                               encryption=3des
-                               prf=hmac_md5
-                               integrity=hmac_md5_96
-                               dhgroup=modp2048
-                       } 
-               }
-               }
-       }
-
        # Instantiate a couple instances of the idn module
        idn {
        }
diff --git a/src/modules/rlm_eap2/all.mk b/src/modules/rlm_eap2/all.mk
deleted file mode 100644 (file)
index acccfbc..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# $Id$
-#
-
-#
-#  This module is EXPERIMENTAL!
-#
-
-#
-#  You will have to edit this Makefile to define where the
-#  hostap distribution is located.
-#
-#  You will also have to edit: hostap/eap_example/Makefile
-#  to enable it to create a shared library, rather than a static one.
-#
-HOSTAP         := /path/to/hostap
-
-#TARGET                := rlm_eap2.a 
-SOURCES                := rlm_eap2.c
-SRC_CFLAGS     := -I$(HOSTAP)/src/eap_common \
-       -I$(HOSTAP)/src/eap_server  -I$(HOSTAP)/src  \
-       -I$(HOSTAP)/src/common -I$(HOSTAP)/src/utils
-       
-TGT_LDLIBS     := $(HOSTAP)/eap_example/libeap.so
diff --git a/src/modules/rlm_eap2/rlm_eap2.c b/src/modules/rlm_eap2/rlm_eap2.c
deleted file mode 100644 (file)
index 1cafa0b..0000000
+++ /dev/null
@@ -1,1002 +0,0 @@
-/*
- *   This program is is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License, version 2 if the
- *   License as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/**
- * $Id$
- * @file rlm_eap2.c
- * @brief Uses hostapd library to support some methods not provided by rlm_eap.
- *
- * @copyright 2007  Alan DeKok <aland@deployingradius.com>
- */
-RCSID("$Id$")
-
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/modules.h>
-#include <freeradius-devel/rad_assert.h>
-
-/*
- *     Hostap includes.
- */
-#include <utils/includes.h>
-
-#include <utils/common.h>
-#include <eap_server/eap.h>
-#include <crypto/tls.h>
-
-
-struct eap_server_ctx {
-       struct eap_eapol_interface *eap_if;
-       struct eap_sm *eap;
-       void *tls_ctx;
-};
-
-#define EAP_STATE_LEN (AUTH_VECTOR_LEN)
-typedef struct EAP_HANDLER {
-       struct EAP_HANDLER *prev, *next;
-       uint8_t         state[EAP_STATE_LEN];
-       fr_ipaddr_t     src_ipaddr;
-
-       time_t          timestamp;
-
-       REQUEST         *request;
-       struct rlm_eap_t *inst;
-
-       struct eapol_callbacks eap_cb;
-       struct eap_config eap_conf;
-       struct eap_server_ctx server_ctx;
-} EAP_HANDLER;
-
-typedef struct rlm_eap_t {
-       rbtree_t        *session_tree;
-       EAP_HANDLER     *session_head, *session_tail;
-
-       /*
-        *      Configuration items.
-        */
-       int             timer_limit;
-       int             mod_accounting_username_bug;
-
-       struct tls_connection_params tparams;
-
-       /*
-        *      For EAP-FAST
-        */
-       char            *pac_opaque_encr_key;
-       char            *eap_fast_a_id;
-       char            *eap_fast_a_id_info;
-       int             eap_fast_prov;
-       int             pac_key_lifetime;
-       int             pac_key_refresh_time;
-       int             backend_auth;
-
-       int             num_types;
-       EapType         methods[EAP_MAX_METHODS];
-       int             vendors[EAP_MAX_METHODS];
-
-#ifdef HAVE_PTHREAD_H
-       pthread_mutex_t session_mutex;
-#endif
-
-       fr_randctx      rand_pool;
-       void *tls_ctx;
-} rlm_eap_t;
-
-
-static void eap_handler_free(EAP_HANDLER *handler)
-{
-       eap_server_sm_deinit(handler->server_ctx.eap);
-       free(handler);
-}
-
-static void eaplist_free(rlm_eap_t *inst)
-{
-       EAP_HANDLER *node, *next;
-
-               for (node = inst->session_head; node != NULL; node = next) {
-               next = node->next;
-               eap_handler_free(node);
-       }
-
-       inst->session_head = inst->session_tail = NULL;
-}
-
-/*
- *     Return a 32-bit random number.
- */
-static uint32_t eap_rand(fr_randctx *ctx)
-{
-       uint32_t num;
-
-       num = ctx->randrsl[ctx->randcnt++];
-       if (ctx->randcnt == 256) {
-               ctx->randcnt = 0;
-               fr_isaac(ctx);
-       }
-
-       return num;
-}
-
-/*
- *     Add a handler to the set of active sessions.
- *
- *     Since we're adding it to the list, we guess that this means
- *     the packet needs a State attribute.  So add one.
- */
-static int eaplist_add(rlm_eap_t *inst, EAP_HANDLER *handler)
-{
-       int             i, status;
-       uint32_t        lvalue;
-       VALUE_PAIR      *state;
-       REQUEST         *request = handler->request;
-
-       rad_assert(handler != NULL);
-       rad_assert(handler->request != NULL);
-
-       /*
-        *      Generate State, since we've been asked to add it to
-        *      the list.
-        */
-       state = pairmake_reply("State", NULL, T_OP_EQ);
-       if (!state) return 0;
-       state->length = EAP_STATE_LEN;
-
-       /*
-        *      The time at which this request was made was the time
-        *      at which it was received by the RADIUS server.
-        */
-       handler->timestamp = handler->request->timestamp;
-
-       handler->src_ipaddr = handler->request->packet->src_ipaddr;
-
-       /*
-        *      We don't need this any more.
-        */
-       handler->request = NULL;
-
-       /*
-        *      Playing with a data structure shared among threads
-        *      means that we need a lock, to avoid conflict.
-        */
-       pthread_mutex_lock(&(inst->session_mutex));
-
-       /*
-        *      Create a completely random state.
-        */
-       for (i = 0; i < 4; i++) {
-               lvalue = eap_rand(&inst->rand_pool);
-               memcpy(state->vp_octets + i * 4, &lvalue, sizeof(lvalue));
-       }
-       memcpy(handler->state, state->vp_strvalue, sizeof(handler->state));
-
-       /*
-        *      Big-time failure.
-        */
-       status = rbtree_insert(inst->session_tree, handler);
-
-       if (status) {
-               EAP_HANDLER *prev;
-
-               prev = inst->session_tail;
-               if (prev) {
-                       prev->next = handler;
-                       handler->prev = prev;
-                       handler->next = NULL;
-                       inst->session_tail = handler;
-               } else {
-                       inst->session_head = inst->session_tail = handler;
-                       handler->next = handler->prev = NULL;
-               }
-       }
-
-       /*
-        *      Now that we've finished mucking with the list,
-        *      unlock it.
-        */
-       pthread_mutex_unlock(&(inst->session_mutex));
-
-       if (!status) {
-               ERROR("rlm_eap2: Failed to remember handler!");
-               eap_handler_free(handler);
-               return 0;
-       }
-
-       return 1;
-}
-
-/*
- *     Find a a previous EAP-Request sent by us, which matches
- *     the current EAP-Response.
- *
- *     Then, release the handle from the list, and return it to
- *     the caller.
- *
- *     Also since we fill the eap_ds with the present EAP-Response we
- *     got to free the prev_eapds & move the eap_ds to prev_eapds
- */
-static EAP_HANDLER *eaplist_find(rlm_eap_t *inst, REQUEST *request)
-{
-       int             i;
-       VALUE_PAIR      *state;
-       rbnode_t        *node;
-       EAP_HANDLER     *handler, myHandler;
-
-       /*
-        *      We key the sessions off of the 'state' attribute, so it
-        *      must exist.
-        */
-       state = pairfind(request->packet->vps, PW_STATE, 0, TAG_ANY);
-       if (!state ||
-           (state->length != EAP_STATE_LEN)) {
-               return NULL;
-       }
-
-       myHandler.src_ipaddr = request->packet->src_ipaddr;
-       memcpy(myHandler.state, state->vp_strvalue, sizeof(myHandler.state));
-
-       /*
-        *      Playing with a data structure shared among threads
-        *      means that we need a lock, to avoid conflict.
-        */
-       pthread_mutex_lock(&(inst->session_mutex));
-
-       /*
-        *      Check the first few handlers in the list, and delete
-        *      them if they're too old.  We don't need to check them
-        *      all, as incoming requests will quickly cause older
-        *      handlers to be deleted.
-        *
-        */
-       for (i = 0; i < 2; i++) {
-               handler = inst->session_head;
-               if (handler &&
-                   ((request->timestamp - handler->timestamp) > inst->timer_limit)) {
-                       node = rbtree_find(inst->session_tree, handler);
-                       rad_assert(node != NULL);
-                       rbtree_delete(inst->session_tree, node);
-
-                       /*
-                        *      handler == inst->session_head
-                        */
-                       inst->session_head = handler->next;
-                       if (handler->next) {
-                               handler->next->prev = NULL;
-                       } else {
-                               inst->session_head = NULL;
-                       }
-                       eap_handler_free(handler);
-               }
-       }
-
-       handler = NULL;
-       node = rbtree_find(inst->session_tree, &myHandler);
-       if (node) {
-               handler = rbtree_node2data(inst->session_tree, node);
-
-               /*
-                *      Delete old handler from the tree.
-                */
-               rbtree_delete(inst->session_tree, node);
-               
-               /*
-                *      And unsplice it from the linked list.
-                */
-               if (handler->prev) {
-                       handler->prev->next = handler->next;
-               } else {
-                       inst->session_head = handler->next;
-               }
-               if (handler->next) {
-                       handler->next->prev = handler->prev;
-               } else {
-                       inst->session_tail = handler->prev;
-               }
-               handler->prev = handler->next = NULL;
-       }
-
-       pthread_mutex_unlock(&(inst->session_mutex));
-
-       /*
-        *      Not found.
-        */
-       if (!node) {
-               RDEBUG2("Request not found in the list");
-               return NULL;
-       }
-
-       /*
-        *      Found, but state verification failed.
-        */
-       if (!handler) {
-               ERROR("rlm_eap2: State verification failed.");
-               return NULL;
-       }
-
-       RDEBUG2("Request found, released from the list");
-
-       return handler;
-}
-
-
-/*
- * delete all the allocated space by eap module
- */
-static int mod_detach(void *instance)
-{
-       rlm_eap_t *inst;
-
-       inst = (rlm_eap_t *)instance;
-
-       rbtree_free(inst->session_tree);
-       inst->session_tree = NULL;
-       eaplist_free(inst);
-       eap_server_unregister_methods();
-       tls_deinit(inst->tls_ctx);
-
-       pthread_mutex_destroy(&(inst->session_mutex));
-
-       return 0;
-}
-
-
-/*
- *     Compare two handlers.
- */
-static int eap_handler_cmp(void const *a, void const *b)
-{
-       int rcode;
-       const EAP_HANDLER *one = a;
-       const EAP_HANDLER *two = b;
-
-       rcode = fr_ipaddr_cmp(&one->src_ipaddr, &two->src_ipaddr);
-       if (rcode != 0) return rcode;
-
-       return memcmp(one->state, two->state, sizeof(one->state));
-}
-
-
-static int server_get_eap_user(void *ctx, UNUSED const u8 *identity, UNUSED size_t identity_len, int phase2,
-                              struct eap_user *user)
-{
-       int i;
-       VALUE_PAIR *vp;
-       EAP_HANDLER *handler = ctx;
-       REQUEST *request = handler->request;
-
-       os_memset(user, 0, sizeof(*user));
-
-       /*
-        *      FIXME: Run through "authorise" again to look up
-        *      password for the given identity
-        */
-        
-       /*
-        *      Do this always, just in case.
-        */
-       vp = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD, 0, TAG_ANY);
-       if (vp) {
-               user->password = (u8 *) os_strdup(vp->vp_strvalue);
-               user->password_len = vp->length;
-       }
-       if (!vp) vp = pairfind(request->config_items, PW_NT_PASSWORD, 0, TAG_ANY);
-       if (vp) {
-               user->password = (u8 *) malloc(vp->length);
-               memcpy(user->password, vp->vp_octets, vp->length);
-               user->password_len = vp->length;
-       }
-
-       if (!phase2) {
-               for (i = 0; i < handler->inst->num_types; i++) {
-                       user->methods[i].vendor = handler->inst->vendors[i];
-                       user->methods[i].method = handler->inst->methods[i];
-               }
-               return 0;
-       }
-
-       /*
-        *      FIXME: run tunneled sessions through the tunneled portion...
-        */
-
-       /*
-        *      FIXME: Selectively control tunneled EAP types.
-        */
-       user->methods[0].vendor = EAP_VENDOR_IETF;
-       user->methods[0].method = EAP_TYPE_MD5;
-       user->methods[1].vendor = EAP_VENDOR_IETF;
-       user->methods[1].method = EAP_TYPE_MSCHAPV2;
-
-       /*
-        *      No password configured...
-        */
-
-               return 0;
-}
-
-
-static char const * server_get_eap_req_id_text(UNUSED void *ctx, size_t *len)
-{
-       *len = 0;
-       return NULL;
-}
-
-
-static CONF_PARSER tls_config[] = {
-       /*
-        *      TLS parameters.
-        */
-       { "ca_cert", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, tparams.ca_cert),
-         NULL, "${confdir}/certs/ca.pem" },
-       { "server_cert", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, tparams.client_cert),
-         NULL, "${confdir}/certs/server.pem" },
-       { "private_key_file", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, tparams.private_key),
-         NULL, "${confdir}/certs/server.pem" },
-       { "private_key_password", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, tparams.private_key_passwd),
-         NULL, "whatever" },
-
-       { "dh_file", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, tparams.dh_file), NULL, "whatever" },
-
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
-};
-
-static CONF_PARSER fast_config[] = {
-       { "pac_opaque_encr_key", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, pac_opaque_encr_key), NULL, NULL },
-       { "eap_fast_a_id", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, eap_fast_a_id), NULL, NULL },
-       { "eap_fast_a_id_info", PW_TYPE_STRING_PTR,
-         offsetof(rlm_eap_t, eap_fast_a_id_info), NULL, NULL },
-       { "eap_fast_prov", PW_TYPE_INTEGER,
-         offsetof(rlm_eap_t, eap_fast_prov), NULL, "3"},
-       { "pac_key_lifetime", PW_TYPE_INTEGER,
-         offsetof(rlm_eap_t, pac_key_lifetime), NULL, "604800"},
-       { "pac_key_refresh_time", PW_TYPE_INTEGER,
-         offsetof(rlm_eap_t, pac_key_refresh_time), NULL, "86400"},
-       { NULL, -1, 0, NULL, NULL } /* end the list */
-};
-
-static const CONF_PARSER module_config[] = {
-       { "timer_expire", PW_TYPE_INTEGER,
-         offsetof(rlm_eap_t, timer_limit), NULL, "60"},
-       { "mod_accounting_username_bug", PW_TYPE_BOOLEAN,
-         offsetof(rlm_eap_t, mod_accounting_username_bug), NULL, "no" },
-
-       { "backend_auth", PW_TYPE_BOOLEAN,
-         offsetof(rlm_eap_t, backend_auth), NULL, "yes" },
-
-       { "tls", PW_TYPE_SUBSECTION, 0, NULL, (void const *) tls_config },
-
-       { "fast", PW_TYPE_SUBSECTION, 0, NULL, (void const *) fast_config },
-
-       { NULL, -1, 0, NULL, NULL }        /* end the list */
-};
-
-
-static int eap_example_server_init_tls(rlm_eap_t *inst)
-{
-       struct tls_config tconf;
-
-       os_memset(&tconf, 0, sizeof(tconf));
-       inst->tls_ctx = tls_init(&tconf);
-       if (!inst->tls_ctx)
-               return -1;
-
-       if (tls_global_set_params(inst->tls_ctx, &inst->tparams)) {
-               ERROR("rlm_eap2: Failed to set TLS parameters");
-               return -1;
-       }
-
-       if (tls_global_set_verify(inst->tls_ctx, 0)) {
-               ERROR("rlm_eap2: Failed to set check_crl");
-               return -1;
-       }
-
-       return 0;
-}
-
-
-/*
- * read the config section and load all the eap authentication types present.
- */
-static int mod_instantiate(CONF_SECTION *cs, void *instance)
-{
-       int i, num_types;
-       int             has_tls, do_tls;
-       rlm_eap_t       *inst = instance;
-       CONF_SECTION    *scs;
-
-       /*
-        *      Create our own random pool.
-        */
-       for (i = 0; i < 256; i++) {
-               inst->rand_pool.randrsl[i] = fr_rand();
-       }
-       fr_randinit(&inst->rand_pool, 1);
-
-       /*
-        *      List of sessions are set to NULL by the memset
-        *      of 'inst', above.
-        */
-
-       /*
-        *      Lookup sessions in the tree.  We don't free them in
-        *      the tree, as that's taken care of elsewhere...
-        */
-       inst->session_tree = rbtree_create(eap_handler_cmp, NULL, 0);
-       if (!inst->session_tree) {
-               ERROR("rlm_eap2: Cannot initialize tree");
-               return -1;
-       }
-
-       /*
-        *      This registers ALL available methods.
-        *
-        *      FIXME: we probably want to selectively register
-        *      some methods.
-        */
-       if (eap_server_register_methods() < 0) {
-               return -1;
-       }
-
-       /* Load all the configured EAP-Types */
-       num_types = 0;
-       has_tls = do_tls = 0;
-       for (scs=cf_subsection_find_next(cs, NULL, NULL);
-               scs != NULL;
-               scs=cf_subsection_find_next(cs, scs, NULL)) {
-               char const      *auth_type;
-               char            buffer[64], *p;
-
-               auth_type = cf_section_name1(scs);
-
-               if (!auth_type)  continue;
-
-               if (num_types >= EAP_MAX_METHODS) {
-                       WARN("Ignoring EAP type %s: too many types defined", auth_type);
-                       continue;
-               }
-
-               /*
-                *      Hostapd doesn't do case-insensitive comparisons.
-                *      So we mash everything to uppercase for it.
-                */
-               strlcpy(buffer, auth_type, sizeof(buffer));
-
-               for (p = buffer; *p; p++) {
-                       if (!islower((int)*p)) continue;
-                       *p = toupper((int)*p);
-               }
-
-               inst->methods[num_types] = eap_server_get_type(buffer,
-                                                              &inst->vendors[num_types]);
-               if (inst->methods[num_types] == EAP_TYPE_NONE) {
-                       ERROR("rlm_eap2: Unknown EAP type %s",
-                              auth_type);
-                       return -1;
-               }
-
-               switch (inst->methods[num_types]) {
-               case EAP_TYPE_TLS:
-                       has_tls = true;
-                       /* FALL-THROUGH */
-
-               case EAP_TYPE_TTLS:
-               case EAP_TYPE_PEAP:
-               case EAP_TYPE_FAST:
-                       do_tls = true;
-                       break;
-
-               default:
-                       break;
-               }
-
-               num_types++;    /* successfully loaded one more types */
-       }
-       inst->num_types = num_types;
-
-       if (do_tls && !has_tls) {
-               ERROR("rlm_eap2: TLS has not been configured.  Cannot do methods that need TLS.");
-               return -1;
-       }
-
-       if (do_tls) {
-               /*
-                *      Initialize TLS.
-                */
-               if (eap_example_server_init_tls(inst) < 0) {
-                       ERROR("rlm_eap2: Cannot initialize TLS");
-                       return -1;
-               }
-       }
-
-       pthread_mutex_init(&(inst->session_mutex), NULL);
-       return 0;
-}
-
-
-static int eap_req2vp(EAP_HANDLER *handler)
-{
-       int             encoded, total, size;
-       const uint8_t   *ptr;
-       VALUE_PAIR      *head = NULL;
-       VALUE_PAIR      **tail = &head;
-       VALUE_PAIR      *vp;
-
-       ptr = wpabuf_head(handler->server_ctx.eap_if->eapReqData);
-       encoded = total = wpabuf_len(handler->server_ctx.eap_if->eapReqData);
-
-       do {
-               size = total;
-               if (size > 253) size = 253;
-
-               vp = paircreate(handler->request->reply, PW_EAP_MESSAGE, 0);
-               if (!vp) {
-                       pairfree(&head);
-                       return -1;
-               }
-               pairmemcpy(vp, ptr, size);
-
-               *tail = vp;
-               tail = &(vp->next);
-
-               ptr += size;
-               total -= size;
-       } while (total > 0);
-
-       pairdelete(&handler->request->reply->vps, PW_EAP_MESSAGE, TAG_ANY);
-       pairadd(&handler->request->reply->vps, head);
-
-       return encoded;
-}
-
-static int eap_example_server_step(EAP_HANDLER *handler)
-{
-       int res, process = 0;
-       REQUEST *request = handler->request;
-
-       res = eap_server_sm_step(handler->server_ctx.eap);
-
-       if (handler->server_ctx.eap_if->eapReq) {
-               DEBUG("==> Request");
-               process = 1;
-               handler->server_ctx.eap_if->eapReq = 0;
-       }
-
-       if (handler->server_ctx.eap_if->eapSuccess) {
-               DEBUG("==> Success");
-               process = 1;
-               res = 0;
-
-               if (handler->server_ctx.eap_if->eapKeyAvailable) {
-                       int length = handler->server_ctx.eap_if->eapKeyDataLen;
-                       VALUE_PAIR *vp;
-
-                       if (length > 64) {
-                               length = 32;
-                       } else {
-                               length /= 2;
-                               /*
-                                *      FIXME: Length is zero?
-                                */
-                       }
-
-                       vp = pairmake_reply("MS-MPPE-Recv-Key", NULL, T_OP_EQ);
-                       if (vp) {
-                               pairmemcpy(vp,
-                                          handler->server_ctx.eap_if->eapKeyData,
-                                          length);
-                       }
-                       
-                       vp = pairmake_reply("MS-MPPE-Send-Key", NULL, T_OP_EQ);
-                       if (vp) {
-                               pairmemcpy(vp,
-                                          handler->server_ctx.eap_if->eapKeyData + length,
-                                          length);
-                       }
-               }
-       }
-
-       if (handler->server_ctx.eap_if->eapFail) {
-               DEBUG("==> Fail");
-               process = 1;
-       }
-
-       if (process) {
-               if (wpabuf_head(handler->server_ctx.eap_if->eapReqData)) {
-                       if (!eap_req2vp(handler)) return -1;
-               } else {
-                       return -1;
-               }
-       }
-
-       return res;
-}
-
-
-/*
- * Handles multiple EAP-Message attrs
- * ie concatenates all to get the complete EAP packet.
- *
- * NOTE: Sometimes Framed-MTU might contain the length of EAP-Message,
- *      refer fragmentation in rfc2869.
- */
-static int eap_vp2data(VALUE_PAIR *vps, void **data, int *data_len)
-{
-       VALUE_PAIR *first, *vp;
-       unsigned char *ptr;
-       uint16_t len;
-       int total_len;
-
-       /*
-        *      Get only EAP-Message attribute list
-        */
-       first = pairfind(vps, PW_EAP_MESSAGE, 0, TAG_ANY);
-       if (!first) {
-               ERROR("rlm_eap2: EAP-Message not found");
-               return -1;
-       }
-
-       /*
-        *      Sanity check the length before doing anything.
-        */
-       if (first->length < 4) {
-               ERROR("rlm_eap2: EAP packet is too short.");
-               return -1;
-       }
-
-       /*
-        *      Get the Actual length from the EAP packet
-        *      First EAP-Message contains the EAP packet header
-        */
-       memcpy(&len, first->vp_strvalue + 2, sizeof(len));
-       len = ntohs(len);
-
-       /*
-        *      Take out even more weird things.
-        */
-       if (len < 4) {
-               ERROR("rlm_eap2: EAP packet has invalid length.");
-               return -1;
-       }
-
-       /*
-        *      Sanity check the length, BEFORE malloc'ing memory.
-        */
-       total_len = 0;
-       for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               total_len += vp->length;
-
-               if (total_len > len) {
-                       ERROR("rlm_eap2: Malformed EAP packet.  Length in packet header does not match actual length");
-                       return -1;
-               }
-       }
-
-       /*
-        *      If the length is SMALLER, die, too.
-        */
-       if (total_len < len) {
-               ERROR("rlm_eap2: Malformed EAP packet.  Length in packet header does not match actual length");
-               return -1;
-       }
-
-       /*
-        *      Now that we know the lengths are OK, allocate memory.
-        */
-       *data = malloc(len);
-       if (!*data) {
-               return -1;
-       }
-       *data_len = len;
-
-       /*
-        *      Copy the data from EAP-Message's over to our EAP packet.
-        */
-       ptr = *data;
-
-       /* RADIUS ensures order of attrs, so just concatenate all */
-       for (vp = first; vp; vp = pairfind(vp->next, PW_EAP_MESSAGE, 0, TAG_ANY)) {
-               memcpy(ptr, vp->vp_strvalue, vp->length);
-               ptr += vp->length;
-       }
-
-       return 0;
-}
-
-/*
- *     FIXME: Add an "authorize" section which sets Auth-Type = EAP2
- *     FIXME: Also in "authorize", set User-Name if not already set.
- */
-
-
-/*
- *     Do EAP.
- */
-static rlm_rcode_t mod_authenticate(void *instance, REQUEST *request)
-{
-       rlm_eap_t       *inst;
-       EAP_HANDLER     *handler;
-       void            *data;
-       int             data_len;
-       rlm_rcode_t     rcode;
-       VALUE_PAIR      *vp;
-
-       inst = (rlm_eap_t *) instance;
-
-       vp = pairfind(request->packet->vps, PW_EAP_MESSAGE, 0, TAG_ANY);
-       if (!vp) {
-               RDEBUG("No EAP-Message.  Not doing EAP.");
-               return RLM_MODULE_FAIL;
-       }
-
-       /*
-        *      Get the eap packet  to start with
-        */
-       data = NULL;
-       data_len = 0;
-       if (eap_vp2data(request->packet->vps, &data, &data_len) < 0) {
-               ERROR("rlm_eap2: Malformed EAP Message");
-               return RLM_MODULE_FAIL;
-       }
-
-       vp = pairfind(request->packet->vps, PW_STATE, 0, TAG_ANY);
-       if (vp) {
-               handler = eaplist_find(inst, request);
-               if (!handler) {
-                       RDEBUG("No handler found");
-                       return RLM_MODULE_FAIL;
-               }
-       } else {
-               handler = malloc(sizeof(*handler));
-               if (!handler) return RLM_MODULE_FAIL;
-
-               memset(handler, 0, sizeof(*handler));
-
-               handler->inst = inst;
-               handler->eap_cb.get_eap_user = server_get_eap_user;
-               handler->eap_cb.get_eap_req_id_text = server_get_eap_req_id_text;
-
-               handler->eap_conf.eap_server = 1;
-               handler->eap_conf.ssl_ctx = inst->tls_ctx;
-
-               /*
-                *      Copy EAP-FAST parameters.
-                */
-               handler->eap_conf.pac_opaque_encr_key = inst->pac_opaque_encr_key;
-               handler->eap_conf.eap_fast_a_id = inst->eap_fast_a_id;
-               handler->eap_conf.eap_fast_a_id_len = strlen(inst->eap_fast_a_id);
-               handler->eap_conf.eap_fast_a_id_info = inst->eap_fast_a_id_info;
-               handler->eap_conf.eap_fast_prov = inst->eap_fast_prov;
-               handler->eap_conf.pac_key_lifetime = inst->pac_key_lifetime;
-               handler->eap_conf.pac_key_refresh_time = inst->pac_key_refresh_time;
-               handler->eap_conf.backend_auth = inst->backend_auth;
-               
-               handler->server_ctx.eap = eap_server_sm_init(handler,
-                                                            &handler->eap_cb,
-                                                            &handler->eap_conf);
-               if (!handler->server_ctx.eap) {
-                       free(handler);
-                       return RLM_MODULE_FAIL;
-               }
-               
-               handler->server_ctx.eap_if = eap_get_interface(handler->server_ctx.eap);
-               
-               /* Enable "port" and request EAP to start authentication. */
-               handler->server_ctx.eap_if->portEnabled = true;
-               handler->server_ctx.eap_if->eapRestart = true;
-       }
-
-       handler->request = request;
-       wpabuf_free(handler->server_ctx.eap_if->eapRespData);
-       handler->server_ctx.eap_if->eapRespData = wpabuf_alloc_copy(data, data_len);
-       if (handler->server_ctx.eap_if->eapRespData) {
-               handler->server_ctx.eap_if->eapResp = true;
-       }
-       
-       if (eap_example_server_step(handler) < 0) {
-               RDEBUG("Failed in EAP library");
-               goto fail;
-       }
-
-       if (handler->server_ctx.eap_if->eapSuccess) {
-               request->reply->code = PW_AUTHENTICATION_ACK;
-               rcode = RLM_MODULE_OK;
-
-       } else if (handler->server_ctx.eap_if->eapFail) {
-       fail:
-               request->reply->code = PW_AUTHENTICATION_REJECT;
-               rcode = RLM_MODULE_REJECT;
-
-       } else {
-               request->reply->code = PW_ACCESS_CHALLENGE;
-               rcode = RLM_MODULE_HANDLED;
-       }
-
-       if (handler->server_ctx.eap_if->eapFail ||
-           handler->server_ctx.eap_if->eapSuccess) {
-               RDEBUG2("Freeing handler");
-               /* handler is not required any more, free it now */
-               eap_handler_free(handler);
-               handler = NULL;
-       } else {
-               eaplist_add(inst, 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, 0, TAG_ANY);
-               if (!vp) {
-                       vp = pairmake("User-Name", request->username->vp_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->mod_accounting_username_bug) &&
-                   (vp->length < (int) sizeof(vp->vp_strvalue))) {
-                       vp->vp_strvalue[vp->length] = '\0';
-                       vp->length++;
-               }
-       }
-
-       vp = pairfind(request->reply->vps, PW_MESSAGE_AUTHENTICATOR, 0, TAG_ANY);
-       if (!vp) {
-               vp = paircreate(PW_MESSAGE_AUTHENTICATOR, 0);
-               memset(vp->vp_strvalue, 0, AUTH_VECTOR_LEN);
-               vp->length = AUTH_VECTOR_LEN;
-               pairadd(&(request->reply->vps), vp);
-       }
-       return rcode;
-}
-
-
-/*
- *     The module name should be the only globally exported symbol.
- *     That is, everything else should be 'static'.
- */
-module_t rlm_eap2 = {
-       RLM_MODULE_INIT,
-       "eap2",
-       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
-       sizeof(rlm_eap_t),
-       module_config,
-       mod_instantiate,                /* instantiation */
-       mod_detach,                     /* detach */
-       {
-               mod_authenticate,       /* authentication */
-               NULL,                   /* authorization */
-               NULL,                   /* preaccounting */
-               NULL,                   /* accounting */
-               NULL,                   /* checksimul */
-               NULL,                   /* pre-proxy */
-               NULL,                   /* post-proxy */
-               NULL                    /* post-auth */
-       },
-};