Moved data structures to new collections subfolder
[strongswan.git] / src / libcharon / plugins / eap_mschapv2 / eap_mschapv2.c
index 3cd8d99..96f4375 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <daemon.h>
 #include <library.h>
 
 #include <daemon.h>
 #include <library.h>
-#include <utils/enumerator.h>
+#include <collections/enumerator.h>
 #include <crypto/crypters/crypter.h>
 #include <crypto/hashers/hasher.h>
 
 #include <crypto/crypters/crypter.h>
 #include <crypto/hashers/hasher.h>
 
@@ -281,7 +281,11 @@ static status_t NtPasswordHash(chunk_t password, chunk_t *password_hash)
                DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, no MD4 hasher available");
                return FAILED;
        }
                DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, no MD4 hasher available");
                return FAILED;
        }
-       hasher->allocate_hash(hasher, password, password_hash);
+       if (!hasher->allocate_hash(hasher, password, password_hash))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
        hasher->destroy(hasher);
        return SUCCESS;
 }
        hasher->destroy(hasher);
        return SUCCESS;
 }
@@ -302,7 +306,11 @@ static status_t ChallengeHash(chunk_t peer_challenge, chunk_t server_challenge,
                return FAILED;
        }
        concat = chunk_cata("ccc", peer_challenge, server_challenge, username);
                return FAILED;
        }
        concat = chunk_cata("ccc", peer_challenge, server_challenge, username);
-       hasher->allocate_hash(hasher, concat, challenge_hash);
+       if (!hasher->allocate_hash(hasher, concat, challenge_hash))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
        hasher->destroy(hasher);
        /* we need only the first 8 octets */
        challenge_hash->len = 8;
        hasher->destroy(hasher);
        /* we need only the first 8 octets */
        challenge_hash->len = 8;
@@ -337,9 +345,15 @@ static status_t ChallengeResponse(chunk_t challenge_hash, chunk_t password_hash,
        for (i = 0; i < 3; i++)
        {
                chunk_t expanded, encrypted;
        for (i = 0; i < 3; i++)
        {
                chunk_t expanded, encrypted;
+
                expanded = ExpandDESKey(keys[i]);
                expanded = ExpandDESKey(keys[i]);
-               crypter->set_key(crypter, expanded);
-               crypter->encrypt(crypter, challenge_hash, chunk_empty, &encrypted);
+               if (!crypter->set_key(crypter, expanded) ||
+                       !crypter->encrypt(crypter, challenge_hash, chunk_empty, &encrypted))
+               {
+                       chunk_clear(&expanded);
+                       crypter->destroy(crypter);
+                       return FAILED;
+               }
                memcpy(&response->ptr[i * 8], encrypted.ptr, encrypted.len);
                chunk_clear(&encrypted);
                chunk_clear(&expanded);
                memcpy(&response->ptr[i * 8], encrypted.ptr, encrypted.len);
                chunk_clear(&encrypted);
                chunk_clear(&expanded);
@@ -376,10 +390,17 @@ static status_t AuthenticatorResponse(chunk_t password_hash_hash,
        }
 
        concat = chunk_cata("ccc", password_hash_hash, nt_response, magic1);
        }
 
        concat = chunk_cata("ccc", password_hash_hash, nt_response, magic1);
-       hasher->allocate_hash(hasher, concat, &digest);
+       if (!hasher->allocate_hash(hasher, concat, &digest))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
        concat = chunk_cata("ccc", digest, challenge_hash, magic2);
        concat = chunk_cata("ccc", digest, challenge_hash, magic2);
-       hasher->allocate_hash(hasher, concat, response);
-
+       if (!hasher->allocate_hash(hasher, concat, response))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
        hasher->destroy(hasher);
        chunk_free(&digest);
        return SUCCESS;
        hasher->destroy(hasher);
        chunk_free(&digest);
        return SUCCESS;
@@ -428,7 +449,9 @@ static status_t GenerateMSK(chunk_t password_hash_hash,
        chunk_t keypad = chunk_from_chars(
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
        chunk_t keypad = chunk_from_chars(
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-       chunk_t concat, master_key, master_receive_key, master_send_key;
+       char master_key[HASH_SIZE_SHA1];
+       char master_receive_key[HASH_SIZE_SHA1], master_send_key[HASH_SIZE_SHA1];
+       chunk_t concat, master;
        hasher_t *hasher;
 
        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
        hasher_t *hasher;
 
        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
@@ -439,23 +462,29 @@ static status_t GenerateMSK(chunk_t password_hash_hash,
        }
 
        concat = chunk_cata("ccc", password_hash_hash, nt_response, magic1);
        }
 
        concat = chunk_cata("ccc", password_hash_hash, nt_response, magic1);
-       hasher->allocate_hash(hasher, concat, &master_key);
-       master_key.len = 16;
-
-       concat = chunk_cata("cccc", master_key, shapad1, magic2, shapad2);
-       hasher->allocate_hash(hasher, concat, &master_receive_key);
-       master_receive_key.len = 16;
-
-       concat = chunk_cata("cccc", master_key, shapad1, magic3, shapad2);
-       hasher->allocate_hash(hasher, concat, &master_send_key);
-       master_send_key.len = 16;
+       if (!hasher->get_hash(hasher, concat, master_key))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
+       master = chunk_create(master_key, 16);
+       concat = chunk_cata("cccc", master, shapad1, magic2, shapad2);
+       if (!hasher->get_hash(hasher, concat, master_receive_key))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
+       concat = chunk_cata("cccc", master, shapad1, magic3, shapad2);
+       if (!hasher->get_hash(hasher, concat, master_send_key))
+       {
+               hasher->destroy(hasher);
+               return FAILED;
+       }
 
 
-       *msk = chunk_cat("cccc", master_receive_key, master_send_key, keypad, keypad);
+       *msk = chunk_cat("cccc", chunk_create(master_receive_key, 16),
+                                        chunk_create(master_send_key, 16), keypad, keypad);
 
        hasher->destroy(hasher);
 
        hasher->destroy(hasher);
-       chunk_free(&master_key);
-       chunk_free(&master_receive_key);
-       chunk_free(&master_send_key);
        return SUCCESS;
 }
 
        return SUCCESS;
 }
 
@@ -533,13 +562,12 @@ static char* sanitize(char *str)
 
 /**
  * Returns a chunk of just the username part of the given user identity.
 
 /**
  * Returns a chunk of just the username part of the given user identity.
- * Note: the chunk points to internal data of the identification.
+ * Note: the chunk points to internal data of the given chunk
  */
  */
-static chunk_t extract_username(identification_t* identification)
+static chunk_t extract_username(chunk_t id)
 {
        char *has_domain;
 {
        char *has_domain;
-       chunk_t id;
-       id = identification->get_encoding(identification);
+
        has_domain = (char*)memchr(id.ptr, '\\', id.len);
        if (has_domain)
        {
        has_domain = (char*)memchr(id.ptr, '\\', id.len);
        if (has_domain)
        {
@@ -560,19 +588,15 @@ static void set_ms_length(eap_mschapv2_header_t *eap, u_int16_t len)
        memcpy(&eap->ms_length, &len, sizeof(u_int16_t));
 }
 
        memcpy(&eap->ms_length, &len, sizeof(u_int16_t));
 }
 
-/**
- * Implementation of eap_method_t.initiate for the peer
- */
-static status_t initiate_peer(private_eap_mschapv2_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_peer, status_t,
+       private_eap_mschapv2_t *this, eap_payload_t **out)
 {
        /* peer never initiates */
        return FAILED;
 }
 
 {
        /* peer never initiates */
        return FAILED;
 }
 
-/**
- * Implementation of eap_method_t.initiate for the server
- */
-static status_t initiate_server(private_eap_mschapv2_t *this, eap_payload_t **out)
+METHOD(eap_method_t, initiate_server, status_t,
+       private_eap_mschapv2_t *this, eap_payload_t **out)
 {
        rng_t *rng;
        eap_mschapv2_header_t *eap;
 {
        rng_t *rng;
        eap_mschapv2_header_t *eap;
@@ -581,12 +605,12 @@ static status_t initiate_server(private_eap_mschapv2_t *this, eap_payload_t **ou
        u_int16_t len = CHALLENGE_PAYLOAD_LEN + sizeof(MSCHAPV2_HOST_NAME) - 1;
 
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
        u_int16_t len = CHALLENGE_PAYLOAD_LEN + sizeof(MSCHAPV2_HOST_NAME) - 1;
 
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
+       if (!rng || !rng->allocate_bytes(rng, CHALLENGE_LEN, &this->challenge))
        {
        {
-               DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, no RNG");
+               DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, no challenge");
+               DESTROY_IF(rng);
                return FAILED;
        }
                return FAILED;
        }
-       rng->allocate_bytes(rng, CHALLENGE_LEN, &this->challenge);
        rng->destroy(rng);
 
        eap = alloca(len);
        rng->destroy(rng);
 
        eap = alloca(len);
@@ -649,7 +673,7 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
        eap_mschapv2_header_t *eap;
        eap_mschapv2_challenge_t *cha;
        eap_mschapv2_response_t *res;
        eap_mschapv2_header_t *eap;
        eap_mschapv2_challenge_t *cha;
        eap_mschapv2_response_t *res;
-       chunk_t data, peer_challenge, username, nt_hash;
+       chunk_t data, peer_challenge, userid, username, nt_hash;
        u_int16_t len = RESPONSE_PAYLOAD_LEN;
 
        data = in->get_data(in);
        u_int16_t len = RESPONSE_PAYLOAD_LEN;
 
        data = in->get_data(in);
@@ -674,14 +698,14 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
        this->mschapv2id = eap->ms_chapv2_id;
        this->challenge = chunk_clone(chunk_create(cha->challenge, CHALLENGE_LEN));
 
        this->mschapv2id = eap->ms_chapv2_id;
        this->challenge = chunk_clone(chunk_create(cha->challenge, CHALLENGE_LEN));
 
+       peer_challenge = chunk_alloca(CHALLENGE_LEN);
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
+       if (!rng || !rng->get_bytes(rng, CHALLENGE_LEN, peer_challenge.ptr))
        {
        {
-               DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, no RNG");
+               DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, allocating challenge failed");
+               DESTROY_IF(rng);
                return FAILED;
        }
                return FAILED;
        }
-       peer_challenge = chunk_alloca(CHALLENGE_LEN);
-       rng->get_bytes(rng, CHALLENGE_LEN, peer_challenge.ptr);
        rng->destroy(rng);
 
        if (!get_nt_hash(this, this->peer, this->server, &nt_hash))
        rng->destroy(rng);
 
        if (!get_nt_hash(this, this->peer, this->server, &nt_hash))
@@ -691,8 +715,11 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
                return NOT_FOUND;
        }
 
                return NOT_FOUND;
        }
 
-       username = extract_username(this->peer);
-       len += username.len;
+       /* we transmit the whole user identity (including the domain part) but
+        * only use the user part when calculating the challenge hash */
+       userid = this->peer->get_encoding(this->peer);
+       len += userid.len;
+       username = extract_username(userid);
 
        if (GenerateStuff(this, this->challenge, peer_challenge,
                                          username, nt_hash) != SUCCESS)
 
        if (GenerateStuff(this, this->challenge, peer_challenge,
                                          username, nt_hash) != SUCCESS)
@@ -717,9 +744,7 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
        memset(&res->response, 0, RESPONSE_LEN);
        memcpy(res->response.peer_challenge, peer_challenge.ptr, peer_challenge.len);
        memcpy(res->response.nt_response, this->nt_response.ptr, this->nt_response.len);
        memset(&res->response, 0, RESPONSE_LEN);
        memcpy(res->response.peer_challenge, peer_challenge.ptr, peer_challenge.len);
        memcpy(res->response.nt_response, this->nt_response.ptr, this->nt_response.len);
-
-       username = this->peer->get_encoding(this->peer);
-       memcpy(res->name, username.ptr, username.len);
+       memcpy(res->name, userid.ptr, userid.len);
 
        *out = eap_payload_create_data(chunk_create((void*) eap, len));
        return NEED_MORE;
 
        *out = eap_payload_create_data(chunk_create((void*) eap, len));
        return NEED_MORE;
@@ -818,7 +843,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
        eap_mschapv2_header_t *eap;
        chunk_t data;
        char *message, *token, *msg = NULL;
        eap_mschapv2_header_t *eap;
        chunk_t data;
        char *message, *token, *msg = NULL;
-       int message_len, error = 0, retryable;
+       int message_len, error = 0;
        chunk_t challenge = chunk_empty;
 
        data = in->get_data(in);
        chunk_t challenge = chunk_empty;
 
        data = in->get_data(in);
@@ -846,8 +871,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
                }
                else if (strneq(token, "R=", 2))
                {
                }
                else if (strneq(token, "R=", 2))
                {
-                       token += 2;
-                       retryable = atoi(token);
+                       /* ignore retriable */
                }
                else if (strneq(token, "C=", 2))
                {
                }
                else if (strneq(token, "C=", 2))
                {
@@ -864,9 +888,7 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
                }
                else if (strneq(token, "V=", 2))
                {
                }
                else if (strneq(token, "V=", 2))
                {
-                       int version;
-                       token += 2;
-                       version = atoi(token);
+                       /* ignore version */
                }
                else if (strneq(token, "M=", 2))
                {
                }
                else if (strneq(token, "M=", 2))
                {
@@ -880,17 +902,17 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
                 mschapv2_error_names, error, sanitize(msg));
 
        /**
                 mschapv2_error_names, error, sanitize(msg));
 
        /**
-        * at this point, if the error is retryable, we MAY retry the authentication
+        * at this point, if the error is retriable, we MAY retry the authentication
         * or MAY send a Change Password packet.
         *
         * or MAY send a Change Password packet.
         *
-        * if the error is not retryable (or if we do neither of the above), we
+        * if the error is not retriable (or if we do neither of the above), we
         * SHOULD send a Failure Response packet.
         * windows clients don't do that, and since windows server 2008 r2 behaves
         * pretty odd if we do send a Failure Response, we just don't send one
         * either. windows 7 actually sends a delete notify (which, according to the
         * logs, results in an error on windows server 2008 r2).
         *
         * SHOULD send a Failure Response packet.
         * windows clients don't do that, and since windows server 2008 r2 behaves
         * pretty odd if we do send a Failure Response, we just don't send one
         * either. windows 7 actually sends a delete notify (which, according to the
         * logs, results in an error on windows server 2008 r2).
         *
-        * btw, windows server 2008 r2 does not send non-retryable errors for e.g.
+        * btw, windows server 2008 r2 does not send non-retriable errors for e.g.
         * a disabled account but returns the windows error code in a notify payload
         * of type 12345.
         */
         * a disabled account but returns the windows error code in a notify payload
         * of type 12345.
         */
@@ -904,11 +926,8 @@ error:
        return status;
 }
 
        return status;
 }
 
-/**
- * Implementation of eap_method_t.process for the peer
- */
-static status_t process_peer(private_eap_mschapv2_t *this, eap_payload_t *in,
-               eap_payload_t **out)
+METHOD(eap_method_t, process_peer, status_t,
+       private_eap_mschapv2_t *this, eap_payload_t *in, eap_payload_t **out)
 {
        chunk_t data;
        eap_mschapv2_header_t *eap;
 {
        chunk_t data;
        eap_mschapv2_header_t *eap;
@@ -974,12 +993,12 @@ static status_t process_server_retry(private_eap_mschapv2_t *this,
        DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed, retry (%d)", this->retries);
 
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
        DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed, retry (%d)", this->retries);
 
        rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (!rng)
+       if (!rng || !rng->get_bytes(rng, CHALLENGE_LEN, this->challenge.ptr))
        {
        {
-               DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, no RNG");
+               DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed, allocating challenge failed");
+               DESTROY_IF(rng);
                return FAILED;
        }
                return FAILED;
        }
-       rng->get_bytes(rng, CHALLENGE_LEN, this->challenge.ptr);
        rng->destroy(rng);
 
        chunk_free(&this->nt_response);
        rng->destroy(rng);
 
        chunk_free(&this->nt_response);
@@ -1036,7 +1055,8 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
        snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
        userid = identification_create_from_string(buf);
        DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
        snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
        userid = identification_create_from_string(buf);
        DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%Y'", userid);
-       username = extract_username(userid);
+       /* userid can only be destroyed after the last use of username */
+       username = extract_username(userid->get_encoding(userid));
 
        if (!get_nt_hash(this, this->server, userid, &nt_hash))
        {
 
        if (!get_nt_hash(this, this->server, userid, &nt_hash))
        {
@@ -1091,11 +1111,8 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
        return process_server_retry(this, out);
 }
 
        return process_server_retry(this, out);
 }
 
-/**
- * Implementation of eap_method_t.process for the server
- */
-static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
-               eap_payload_t **out)
+METHOD(eap_method_t, process_server, status_t,
+       private_eap_mschapv2_t *this, eap_payload_t *in, eap_payload_t **out)
 {
        eap_mschapv2_header_t *eap;
        chunk_t data;
 {
        eap_mschapv2_header_t *eap;
        chunk_t data;
@@ -1140,19 +1157,15 @@ static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
        return FAILED;
 }
 
        return FAILED;
 }
 
-/**
- * Implementation of eap_method_t.get_type.
- */
-static eap_type_t get_type(private_eap_mschapv2_t *this, u_int32_t *vendor)
+METHOD(eap_method_t, get_type, eap_type_t,
+       private_eap_mschapv2_t *this, u_int32_t *vendor)
 {
        *vendor = 0;
        return EAP_MSCHAPV2;
 }
 
 {
        *vendor = 0;
        return EAP_MSCHAPV2;
 }
 
-/**
- * Implementation of eap_method_t.get_msk.
- */
-static status_t get_msk(private_eap_mschapv2_t *this, chunk_t *msk)
+METHOD(eap_method_t, get_msk, status_t,
+       private_eap_mschapv2_t *this, chunk_t *msk)
 {
        if (this->msk.ptr)
        {
 {
        if (this->msk.ptr)
        {
@@ -1162,18 +1175,26 @@ static status_t get_msk(private_eap_mschapv2_t *this, chunk_t *msk)
        return FAILED;
 }
 
        return FAILED;
 }
 
-/**
- * Implementation of eap_method_t.is_mutual.
- */
-static bool is_mutual(private_eap_mschapv2_t *this)
+METHOD(eap_method_t, get_identifier, u_int8_t,
+       private_eap_mschapv2_t *this)
+{
+       return this->identifier;
+}
+
+METHOD(eap_method_t, set_identifier, void,
+       private_eap_mschapv2_t *this, u_int8_t identifier)
+{
+       this->identifier = identifier;
+}
+
+METHOD(eap_method_t, is_mutual, bool,
+       private_eap_mschapv2_t *this)
 {
        return FALSE;
 }
 
 {
        return FALSE;
 }
 
-/**
- * Implementation of eap_method_t.destroy.
- */
-static void destroy(private_eap_mschapv2_t *this)
+METHOD(eap_method_t, destroy, void,
+        private_eap_mschapv2_t *this)
 {
        this->peer->destroy(this->peer);
        this->server->destroy(this->server);
 {
        this->peer->destroy(this->peer);
        this->server->destroy(this->server);
@@ -1189,25 +1210,22 @@ static void destroy(private_eap_mschapv2_t *this)
  */
 static private_eap_mschapv2_t *eap_mschapv2_create_generic(identification_t *server, identification_t *peer)
 {
  */
 static private_eap_mschapv2_t *eap_mschapv2_create_generic(identification_t *server, identification_t *peer)
 {
-       private_eap_mschapv2_t *this = malloc_thing(private_eap_mschapv2_t);
-
-       this->public.eap_method_interface.initiate = NULL;
-       this->public.eap_method_interface.process = NULL;
-       this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
-       this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
-       this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
-       this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
-
-       /* private data */
-       this->peer = peer->clone(peer);
-       this->server = server->clone(server);
-       this->challenge = chunk_empty;
-       this->nt_response = chunk_empty;
-       this->auth_response = chunk_empty;
-       this->msk = chunk_empty;
-       this->identifier = 0;
-       this->mschapv2id = 0;
-       this->retries = 0;
+       private_eap_mschapv2_t *this;
+
+       INIT(this,
+               .public = {
+                       .eap_method_interface = {
+                               .get_type = _get_type,
+                               .is_mutual = _is_mutual,
+                               .get_msk = _get_msk,
+                               .get_identifier = _get_identifier,
+                               .set_identifier = _set_identifier,
+                               .destroy = _destroy,
+                       },
+               },
+               .peer = peer->clone(peer),
+               .server = server->clone(server),
+       );
 
        return this;
 }
 
        return this;
 }
@@ -1219,8 +1237,8 @@ eap_mschapv2_t *eap_mschapv2_create_server(identification_t *server, identificat
 {
        private_eap_mschapv2_t *this = eap_mschapv2_create_generic(server, peer);
 
 {
        private_eap_mschapv2_t *this = eap_mschapv2_create_generic(server, peer);
 
-       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
-       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*, eap_payload_t**))process_server;
+       this->public.eap_method_interface.initiate = _initiate_server;
+       this->public.eap_method_interface.process = _process_server;
 
        /* generate a non-zero identifier */
        do
 
        /* generate a non-zero identifier */
        do
@@ -1240,8 +1258,8 @@ eap_mschapv2_t *eap_mschapv2_create_peer(identification_t *server, identificatio
 {
        private_eap_mschapv2_t *this = eap_mschapv2_create_generic(server, peer);
 
 {
        private_eap_mschapv2_t *this = eap_mschapv2_create_generic(server, peer);
 
-       this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
-       this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*, eap_payload_t**))process_peer;
+       this->public.eap_method_interface.initiate = _initiate_peer;
+       this->public.eap_method_interface.process = _process_peer;
 
        return &this->public;
 }
 
        return &this->public;
 }