From d34408a811f9fb6a14e625b156f1950815056864 Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Fri, 20 Jun 2014 16:53:44 +0100 Subject: [PATCH] Cleanup IKEv2 code so it builds again --- src/modules/rlm_eap/types/rlm_eap_ikev2/ike_conf.c | 7 +- .../rlm_eap/types/rlm_eap_ikev2/rlm_eap_ikev2.c | 643 +++++++++++---------- 2 files changed, 337 insertions(+), 313 deletions(-) diff --git a/src/modules/rlm_eap/types/rlm_eap_ikev2/ike_conf.c b/src/modules/rlm_eap/types/rlm_eap_ikev2/ike_conf.c index 5033040..4675a40 100644 --- a/src/modules/rlm_eap/types/rlm_eap_ikev2/ike_conf.c +++ b/src/modules/rlm_eap/types/rlm_eap_ikev2/ike_conf.c @@ -28,6 +28,7 @@ #include #include + #include "ike_conf.h" #include "eap.h" #include "logging_impl.h" @@ -50,8 +51,6 @@ enum { }; - - static struct config_transform config_transforms[] = { {"integrity", IKEv2_TRT_INTEGRITY_ALGORITHM, OPT_INTEGRITY}, @@ -62,8 +61,6 @@ static struct config_transform config_transforms[] = }; - - /* * Copied from rlm_files, and NOT under the same copyright * as the rest of the module! @@ -329,7 +326,7 @@ void rad_update_shared_seclist(struct sharedSecList **list, char const *id, VALU if (!vp || !vp->length) { DEBUG(IKEv2_LOG_PREFIX "[%s] -- Secret not set", id); } else { - secret = vp->vp_strvalue; + memcpy(&secret, &vp->vp_strvalue, sizeof(secret)); } //authtype diff --git a/src/modules/rlm_eap/types/rlm_eap_ikev2/rlm_eap_ikev2.c b/src/modules/rlm_eap/types/rlm_eap_ikev2/rlm_eap_ikev2.c index 394b1de..3438e43 100644 --- a/src/modules/rlm_eap/types/rlm_eap_ikev2/rlm_eap_ikev2.c +++ b/src/modules/rlm_eap/types/rlm_eap_ikev2/rlm_eap_ikev2.c @@ -29,26 +29,75 @@ #include #include "eap.h" -#include -#include #include - - #include + #include "logging_impl.h" #include #include "ike_conf.h" +typedef enum { + PW_IKEV2_CHALLENGE = 1, + PW_IKEV2_RESPONSE, + PW_IKEV2_SUCCESS, + PW_IKEV2_FAILURE, + PW_IKEV2_MAX_CODES +} pw_ikev2_code; -#define PW_IKEV2_CHALLENGE 1 -#define PW_IKEV2_RESPONSE 2 -#define PW_IKEV2_SUCCESS 3 -#define PW_IKEV2_FAILURE 4 -#define PW_IKEV2_MAX_CODES 4 - -#define IKEV2_HEADER_LEN 4 +#define IKEV2_HEADER_LEN 4 #define IKEV2_MPPE_KEY_LEN 32 +typedef struct rlm_eap_ikev2 { + char const *tls_ca_file; //!< Sets the full path to a CA certificate (used to validate + //!< the certificate the server presents). + + char const *tls_private_key_file; //!< Sets the path to the private key for our public + //!< certificate. + char const *tls_private_key_password; //!< Sets the path to the private key for our public + //!< certificate. + + char const *tls_certificate_file; //!< Sets the path to the public certificate file we present + //!< to the servers. + char const *tls_crl; + + char const *id; + uint32_t max_fragment_size; + uint32_t dh_counter_max; + + char const *default_auth_type; + char const *users_file_name; + char const *server_auth_type; + char const *server_id_type; + bool send_cert_request; + + uint32_t fast_expire; + + bool enable_fast_dhex; + bool enable_fast_reconnect; +} rlm_eap_ikev2_t; + +CONF_PARSER module_config[] = { + { "ca_file", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, tls_ca_file), NULL }, + { "private_key_file", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, tls_private_key_file), NULL }, + { "private_key_password", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, tls_private_key_password), NULL }, + { "certificate_file", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, tls_certificate_file), NULL }, + { "crl_file", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, tls_crl), NULL }, + + { "id", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, id), NULL }, + { "fragment_size", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_ikev2_t, max_fragment_size), IKEv2_DEFAULT_MAX_FRAGMENT_SIZE_STR }, + { "dh_counter_max", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_ikev2_t, dh_counter_max), IKEv2_DEFAULT_DH_COUNTER_MAX_STR }, + { "default_authtype", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, default_auth_type), "both" }, + { "usersfile", FR_CONF_OFFSET(PW_TYPE_FILE_INPUT, rlm_eap_ikev2_t, users_file_name),"${confdir}/users" }, + { "server_authtype", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, server_auth_type), "secret" }, + { "idtype", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_eap_ikev2_t, server_id_type), IKEv2_DEFAULT_IDTYPE_STR }, + { "certreq", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_ikev2_t, send_cert_request), "no" }, + { "fast_timer_expire", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_eap_ikev2_t, fast_expire), "900" }, + + { "fast_dh_exchange", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_ikev2_t, enable_fast_dhex), "no" }, + { "enable_fast_reauth", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_eap_ikev2_t, enable_fast_reconnect), "yes" }, + + { NULL, -1, 0, NULL, NULL } /* end the list */ +}; static int set_mppe_keys(eap_handler_t *handler) { @@ -69,419 +118,397 @@ static int set_mppe_keys(eap_handler_t *handler) return 0; } +/** Compose Radius like message from table of output bytes + * + */ +static int compose_rad_message(uint8_t *out,u_int32_t olen, EAP_DS *eap_ds) { + int len; -// Compose Radius like message from table of output bytes -static int ComposeRadMsg(uint8_t *out,u_int32_t olen, EAP_DS *eap_ds){ eap_ds->request->type.num = PW_EAP_IKEV2; eap_ds->request->code = ((struct EAPHeader *)out)->Code; - if(eap_ds->request->code<=PW_EAP_REQUEST && olen>4) { - int len=(int)ntohs(((struct EAPHeader *)out)->Length); - eap_ds->request->type.data = talloc_array(eap_ds->request, - uint8_t, len); - if (!eap_ds->request->type.data) { - return 1; - } - memcpy(eap_ds->request->type.data,out+5,len-5); - eap_ds->request->type.length = len-5; - } else { - eap_ds->request->type.data=NULL; - eap_ds->request->type.length=0; + + if (eap_ds->request->code > PW_EAP_REQUEST || (olen <= 4)) { + eap_ds->request->type.data = NULL; + eap_ds->request->type.length = 0; + + return 0; } - return 0; -} + len = ntohs(((struct EAPHeader *)out)->Length); + eap_ds->request->type.data = talloc_array(eap_ds->request, uint8_t, len); + if (!eap_ds->request->type.data) return 1; + memcpy(eap_ds->request->type.data, out + 5, len - 5); + eap_ds->request->type.length = len - 5; -/** - * Free memory after EAP-IKEv2 module usage - */ + return 0; +} +/** Free memory after EAP-IKEv2 module usage + * + */ static int ikev2_detach(void *instance) { - struct ikev2_ctx *data = (struct ikev2_ctx *) instance; - if (data) { - Free_ikev2_ctx(data); - data=NULL; - } - return 0; + struct ikev2_ctx *data = (struct ikev2_ctx *) instance; + + if (data) { + Free_ikev2_ctx(data); + data = NULL; + } + return 0; } -/** - * Free memory after finished IKEv2 session +/** Free memory after finished IKEv2 session + * */ - static void ikev2_free_opaque(void *opaque) { - DEBUG(IKEv2_LOG_PREFIX "Free session data"); - struct IKEv2Data *ikev2_data=(struct IKEv2Data*)opaque; - if(ikev2_data->session) { - if(ikev2_data->session->Status!=IKEv2_SST_ESTABLISHED) { - DEBUG(IKEv2_LOG_PREFIX "Unfinished IKEv2 session - cleanup!!!"); - IKEv2EndSession(ikev2_data->i2,ikev2_data->session); - ikev2_data->session=NULL; - } else { - DEBUG(IKEv2_LOG_PREFIX "Unfinished IKEv2 session - keep it!!!"); - ikev2_data->session=NULL; + + int fast_deleted; + struct IKEv2Data *ikev2_data=(struct IKEv2Data*)opaque; + + DEBUG(IKEv2_LOG_PREFIX "Free session data"); + + if (ikev2_data->session) { + if (ikev2_data->session->Status != IKEv2_SST_ESTABLISHED) { + DEBUG(IKEv2_LOG_PREFIX "Unfinished IKEv2 session - cleanup!!!"); + IKEv2EndSession(ikev2_data->i2, ikev2_data->session); + ikev2_data->session = NULL; + } else { + DEBUG(IKEv2_LOG_PREFIX "Unfinished IKEv2 session - keep it!!!"); + ikev2_data->session = NULL; + } } - } - int fastDeleted=FreeSessionIfExpired(ikev2_data->i2,time(NULL)); - if(fastDeleted) { - DEBUG(IKEv2_LOG_PREFIX "Deleted %d expired IKEv2 sessions",fastDeleted); - } - free(ikev2_data); -} + fast_deleted = FreeSessionIfExpired(ikev2_data->i2, time(NULL)); + if (fast_deleted) { + DEBUG(IKEv2_LOG_PREFIX "Deleted %d expired IKEv2 sessions", fast_deleted); + } + free(ikev2_data); +} -/** - * Configure EAP-ikev2 handler +/** Configure EAP-ikev2 handler + * */ - static int ikev2_attach(CONF_SECTION *conf, void **instance) { - char *default_authtype=NULL; - char *usersfilename=NULL; - char *server_authtype=NULL; - char *server_idtype=NULL; - - CONF_PARSER module_config[] = { - { "ca_file", FR_CONF_OFFSET(PW_TYPE_STRING, ikev2_ctx, trusted), NULL }, - { "private_key_file", FR_CONF_OFFSET(PW_TYPE_STRING, ikev2_ctx, pkfile), NULL }, - { "private_key_password", FR_CONF_OFFSET(PW_TYPE_STRING, ikev2_ctx, pkfile_pwd), NULL }, - { "certificate_file", FR_CONF_OFFSET(PW_TYPE_STRING, ikev2_ctx, certificate_file), NULL }, - { "crl_file", FR_CONF_OFFSET(PW_TYPE_STRING, ikev2_ctx, crl_file), NULL }, - { "id", FR_CONF_OFFSET(PW_TYPE_STRING, ikev2_ctx, id), NULL }, - { "fragment_size", FR_CONF_OFFSET(PW_TYPE_INTEGER, ikev2_ctx, max_fragment_size), IKEv2_DEFAULT_MAX_FRAGMENT_SIZE_STR }, - { "dh_counter_max", FR_CONF_OFFSET(PW_TYPE_INTEGER, ikev2_ctx, DHCounterMax), IKEv2_DEFAULT_dh_counter_max_STR }, - { "default_authtype", FR_CONF_POINTER(PW_TYPE_STRING, &default_authtype), "both" }, - { "usersfile", FR_CONF_POINTER(PW_TYPE_FILE_INPUT, &usersfilename),"${confdir}/users" }, - { "server_authtype", FR_CONF_POINTER(PW_TYPE_STRING, &server_authtype), "secret" }, - { "idtype", FR_CONF_POINTER(PW_TYPE_STRING, &server_idtype), IKEv2_DEFAULT_IDTYPE_STR }, - { "certreq", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ikev2_ctx, sendCertReq), "no" }, - { "fast_dh_exchange", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ikev2_ctx, enableFastDHEx), "no" }, - { "fast_timer_expire", FR_CONF_OFFSET(PW_TYPE_INTEGER, ikev2_ctx, fastExpire), "900" }, - { "enable_fast_reauth", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, ikev2_ctx, enableFastReconnect), "yes" }, - + int ret; + + struct ikev2_ctx *i2; + rlm_eap_ikev2_t *inst; + + char *server_auth_type, *default_auth_type, *users_file_name; + + ikev2_set_log_callback(vxlogf); + + inst = talloc_zero(conf, rlm_eap_ikev2_t); + if (cf_section_parse(conf, &inst, module_config) < 0) return -1; + + i2 = Create_ikev2_ctx(); + if (!i2) return -1; + *instance = i2; + + /* + * Map our config structure onto the IKEv2 context + */ + memcpy(&i2->trusted, &inst->tls_ca_file, sizeof(i2->trusted)); + memcpy(&i2->pkfile, &inst->tls_private_key_file, sizeof(i2->pkfile)); + memcpy(&i2->pkfile_pwd, &inst->tls_private_key_password, sizeof(i2->pkfile_pwd)); + memcpy(&i2->certfile, &inst->tls_certificate_file, sizeof(i2->certfile)); + memcpy(&i2->id, &inst->id, sizeof(i2->id)); + i2->max_fragment_size = inst->max_fragment_size; + i2->DHCounterMax = inst->dh_counter_max; + i2->sendCertReq = (uint8_t) inst->send_cert_request; + i2->fastExpire = inst->fast_expire; + i2->enableFastDHEx = inst->enable_fast_dhex; + i2->enableFastReconnect = inst->enable_fast_reconnect; + + memcpy(&server_auth_type, &inst->server_auth_type, sizeof(server_auth_type)); + memcpy(&default_auth_type, &inst->default_auth_type, sizeof(default_auth_type)); + memcpy(&users_file_name, &inst->users_file_name, sizeof(users_file_name)); + hexalize(&i2->id, &i2->idlen); + + i2->authtype = rad_get_authtype(server_auth_type); + if (!i2->id) { + ERROR(IKEv2_LOG_PREFIX "'id' configuration option is required!!!"); + return -1; + } - { NULL, -1, 0, NULL, NULL } /* end the list */ - }; + switch (i2->authtype) { + default: + case IKEv2_AUTH_SK: + break; - ikev2_set_log_callback(vxlogf); + case IKEv2_AUTH_CERT: + if (!i2->certfile || !i2->pkfile) { + ERROR(IKEv2_LOG_PREFIX "'certificate_file' and 'private_key_file' items are required " + "for 'cert' auth type"); + return -1; + } - struct ikev2_ctx *i2; + if (!file_exists(i2->certfile)) { + ERROR(IKEv2_LOG_PREFIX "Can not open 'certificate_file' %s", i2->certfile); + return -1; + } + if (!file_exists(i2->pkfile)) { + ERROR(IKEv2_LOG_PREFIX "Can not open 'private_key_file' %s",i2->pkfile); + return -1; + } + break; + } - i2 = Create_ikev2_ctx(); - if (!i2) { - return -1; - } - *instance =i2; + if (!i2->trusted) { + AUTH(IKEv2_LOG_PREFIX "'ca_file' item not set, client cert based authentication will fail"); + } else { + if (!file_exists(i2->trusted)) { + ERROR(IKEv2_LOG_PREFIX "Can not open 'ca_file' %s", i2->trusted); + return -1; + } + } - if (cf_section_parse(conf,i2, module_config) < 0) { - return -1; - } - hexalize(&i2->id,&i2->idlen); + if (i2->crl_file) { + if (!file_exists(i2->crl_file)) { + ERROR(IKEv2_LOG_PREFIX "Can not open 'crl_file' %s", i2->crl_file); + return -1; + } + } - i2->authtype=rad_get_authtype(server_authtype); - if(!i2->id) { - ERROR(IKEv2_LOG_PREFIX "'id' configuration option is required!!!"); - return -1; - } - switch(i2->authtype) { - case IKEv2_AUTH_SK: - break; - case IKEv2_AUTH_CERT: - if(!i2->certificate_file || !i2->pkfile) { - ERROR(IKEv2_LOG_PREFIX "'certificate_file' and 'private_key_file' items are required for 'cert' auth type"); + i2->idtype = IdTypeFromName(inst->server_id_type); + if (i2->idtype <= 0) { + ERROR(IKEv2_LOG_PREFIX "Unsupported 'idtype': %s", inst->server_id_type); return -1; - } - if(!file_exists(i2->certificate_file)) { - ERROR(IKEv2_LOG_PREFIX "Can not open 'certificate_file' %s",i2->certificate_file); - return -1; - } - if(!file_exists(i2->pkfile)) { - ERROR(IKEv2_LOG_PREFIX "Can not open 'private_key_file' %s",i2->pkfile); + } + + if (rad_load_proposals(i2, conf)) { + ERROR(IKEv2_LOG_PREFIX "Failed to load proposals"); return -1; - } - - break; - } - if(!i2->trusted) { - AUTH(IKEv2_LOG_PREFIX "'ca_file' item not set, client cert based authentication will fail"); - } else { - if(!file_exists(i2->trusted)) { - ERROR(IKEv2_LOG_PREFIX "Can not open 'ca_file' %s",i2->trusted); - return -1; } - } - if(i2->crl_file) { - if(!file_exists(i2->crl_file)) { - ERROR(IKEv2_LOG_PREFIX "Can not open 'crl_file' %s",i2->crl_file); - return -1; + + ret = rad_load_credentials(instance, i2, users_file_name, default_auth_type); + if (ret == -1) { + ERROR(IKEv2_LOG_PREFIX "Error while loading users credentials"); + return -1; } - } - - i2->idtype=IdTypeFromName(server_idtype); - if(i2->idtype<=0) { - ERROR(IKEv2_LOG_PREFIX "Unsupported 'idtype': %s",server_idtype); - return -1; - } - - if(rad_load_proposals(i2,conf)) { - ERROR(IKEv2_LOG_PREFIX "Failed to load proposals"); - return -1; - } - - int res=rad_load_credentials(instance, i2,usersfilename,default_authtype); - if(res==-1) { - ERROR(IKEv2_LOG_PREFIX "Error while loading users credentials"); - return -1; - } - - i2->x509_store = NULL; - if(CertInit(i2)){ - ERROR(IKEv2_LOG_PREFIX "Error while loading certs/crl"); - return -1; - } - - return 0; -} + i2->x509_store = NULL; + if(CertInit(i2)){ + ERROR(IKEv2_LOG_PREFIX "Error while loading certs/crl"); + return -1; + } + return 0; +} -/* - * Initiate the EAP-ikev2 session by sending a challenge to the peer. +/** Initiate the EAP-ikev2 session by sending a challenge to the peer. + * */ - - static int ikev2_initiate(void *instance, eap_handler_t *handler) { - INFO(IKEv2_LOG_PREFIX "Initiate connection!"); -// This is the way for silent discarding behavior -// handler->request->log.lvl|=RAD_REQUEST_OPTION_FAKE_REQUEST; -// handler->request->log.lvl|=RAD_REQUEST_OPTION_DONT_CACHE; -// handler->request->reply->code=0; -// return 0; + INFO(IKEv2_LOG_PREFIX "Initiate connection!"); + + struct IKEv2Data *ikev2_data; + struct ikev2_ctx *i2=(struct ikev2_ctx*)instance; - struct ikev2_ctx *i2=(struct ikev2_ctx*)instance; + uint8_t *sikemsg = NULL; + u_int32_t slen = 0; + uint8_t *out = NULL; + u_int32_t olen = 0; - struct IKEv2Session *session; - handler->free_opaque=ikev2_free_opaque; + struct IKEv2Session *session; + handler->free_opaque = ikev2_free_opaque; + /* try get respondent FASTID */ + uint8_t const *eap_username; - // try get respondent FASTID - uint8_t *eap_username = handler->request->username->vp_octets; - session = FindSessionByFastid(i2, (char const *)eap_username); - if(!session) { - if(IKEv2BeginSession( i2, &session, IKEv2_STY_INITIATOR ) != IKEv2_RET_OK) { - ERROR(IKEv2_LOG_PREFIX "Can't initialize IKEv2 session"); - return 1; + eap_username = handler->request->username->vp_octets; + session = FindSessionByFastid(i2, (char const *)eap_username); + if (!session) { + if (IKEv2BeginSession( i2, &session, IKEv2_STY_INITIATOR ) != IKEv2_RET_OK) { + ERROR(IKEv2_LOG_PREFIX "Can't initialize IKEv2 session"); + return 1; + } + } else { + DEBUG(IKEv2_LOG_PREFIX "Fast reconnect procedure start"); } - } else { - DEBUG(IKEv2_LOG_PREFIX "Fast reconnect procedure start"); - } - session->timestamp=time(NULL); - - struct IKEv2Data *ikev2_data=IKEv2Data_new(i2,session); - handler->opaque=ikev2_data; - - -#if 0 - // print session counter - if(i2->SessionList) { - int session_count=0; - struct IKEv2Session *ss; - ss=i2->SessionList; - while(ss) { - session_count++; - //ERROR("XXX scounter -> fastid=[%s]",ss->fastID); - ss=ss->pNext; + session->timestamp=time(NULL); + + ikev2_data = IKEv2Data_new(i2,session); + handler->opaque = ikev2_data; + + if (IKEv2ProcessMsg(i2, NULL , &sikemsg, &slen, session) != IKEv2_RET_OK) { + ERROR(IKEv2_LOG_PREFIX "Error while processing IKEv2 message"); + return 1; } - ERROR("Session list contains: %d",session_count); - } -#endif + if (slen != 0) { + session->eapMsgID++; + olen = CreateIKEv2Message(i2, sikemsg, slen, false, 0, session, &out ); + if (session->fragdata) { + session->sendfrag = true; + } + } - uint8_t *sikemsg=NULL; - u_int32_t slen=0; + if ((olen > 0) && (out!=NULL)) { + if (compose_rad_message(out, olen, handler->eap_ds)) { + free(out); + return 0; + } + free(out); + } - if( IKEv2ProcessMsg( i2, NULL , &sikemsg, &slen, session) != IKEv2_RET_OK ) - { - ERROR(IKEv2_LOG_PREFIX "Error while processing IKEv2 message"); + /* + * We don't need to authorize the user at this point. + * + * We also don't need to keep the challenge, as it's + * stored in 'handler->eap_ds', which will be given back + * to us... + */ + handler->stage = AUTHENTICATE; return 1; - } - - uint8_t *out=NULL; - u_int32_t olen=0; - - if( slen != 0 ) - { - session->eapMsgID++; - olen = CreateIKEv2Message(i2, sikemsg, slen, false, 0, session, &out ); - if( session->fragdata ) - session->sendfrag = true; - } - if (olen>0&&out!=NULL){ - if(ComposeRadMsg(out,olen,handler->eap_ds)){ - free(out); - return 0; - } - free(out); - } - - - /* - * We don't need to authorize the user at this point. - * - * We also don't need to keep the challenge, as it's - * stored in 'handler->eap_ds', which will be given back - * to us... - */ - handler->stage = AUTHENTICATE; - return 1; } - -/* - * Authenticate a previously sent challenge. +/** Authenticate a previously sent challenge + * */ static int ikev2_authenticate(void *instance, eap_handler_t *handler) { + uint8_t *in; + uint8_t *out = NULL; + + uint8_t *ikemsg; + u_int32_t len; + + uint8_t *sikemsg = NULL; //out message + u_int32_t slen = 0; + + u_int32_t olen = 0; + struct ikev2_ctx *i2 = (struct ikev2_ctx*)instance; + struct EAPHeader *hdr; + + struct IKEv2Data *ikev2_data; + struct IKEv2Session *session; - struct ikev2_ctx *i2=(struct ikev2_ctx*)instance; INFO(IKEv2_LOG_PREFIX "authenticate" ); rad_assert(handler->request != NULL); rad_assert(handler->stage == AUTHENTICATE); - //!!!!!if( hdr->Code == EAP_CODE_RESPONSE && hdr->Id == session->MsgID ) - //!!!!! dorobic sprawdzanie czy to nie potwierdzenie odebrania fragmentu!!! EAP_DS *eap_ds=handler->eap_ds; - if (!eap_ds || - !eap_ds->response || - (eap_ds->response->code != PW_IKEV2_RESPONSE) || - eap_ds->response->type.num != PW_EAP_IKEV2 || - !eap_ds->response->type.data){ + if (!eap_ds || + !eap_ds->response || + (eap_ds->response->code != PW_IKEV2_RESPONSE) || + eap_ds->response->type.num != PW_EAP_IKEV2 || + !eap_ds->response->type.data) { ERROR(IKEv2_LOG_PREFIX "corrupted data"); return -1; } - //skladanie pakietu - uint8_t *in=NULL; - if(!(in=talloc_array(eap_ds, uint8_t, eap_ds->response->length))){ + in = talloc_array(eap_ds, uint8_t, eap_ds->response->length); + if (in){ ERROR(IKEv2_LOG_PREFIX "alloc error"); return -1; } - rad_assert(in!=NULL); - struct EAPHeader *hdr = (struct EAPHeader *)in; + rad_assert(in != NULL); + hdr = (struct EAPHeader *)in; - hdr->Code=eap_ds->response->code; - hdr->Id=eap_ds->response->id; - hdr->Length=htons(eap_ds->response->length); - hdr->Type=eap_ds->response->type.num; - memcpy(in+5,eap_ds->response->type.data,eap_ds->response->length-5); - //koniec: skladanie pakietu + hdr->Code = eap_ds->response->code; + hdr->Id = eap_ds->response->id; + hdr->Length = htons(eap_ds->response->length); + hdr->Type = eap_ds->response->type.num; + memcpy(in + 5, eap_ds->response->type.data, eap_ds->response->length - 5); - uint8_t *out=NULL; - u_int32_t olen=0; - struct IKEv2Data *ikev2_data=(struct IKEv2Data*)handler->opaque; - struct IKEv2Session *session=ikev2_data->session; - session->timestamp=time(NULL); + ikev2_data = (struct IKEv2Data*)handler->opaque; + session = ikev2_data->session; + session->timestamp = time(NULL); + + if (!session->fragdata) session->sendfrag = false; + + if (session->sendfrag && !ParseFragmentAck(in, session)){ + session->eapMsgID = eap_ds->response->id + 1; - if( !session->fragdata ) - session->sendfrag = false; - if( session->sendfrag && !ParseFragmentAck( in, session ) ){ - session->eapMsgID=eap_ds->response->id+1; - olen = CreateIKEv2Message( i2, NULL, 0, false, hdr->Id, session, (uint8_t **)&out ); + olen = CreateIKEv2Message(i2, NULL, 0, false, hdr->Id, session, (uint8_t **)&out); talloc_free(in); - if(ComposeRadMsg(out,olen,handler->eap_ds)){ - free(out); - return 0; + + if (compose_rad_message(out,olen,handler->eap_ds)) { + free(out); + return 0; } + free(out); return 1; } - uint8_t *ikemsg; - u_int32_t len; + session->eapMsgID = eap_ds->response->id + 1; - session->eapMsgID=eap_ds->response->id+1; + if (ParseIKEv2Message(in, &ikemsg, &len, session)){ + if (ikemsg != NULL) free(ikemsg); - if( ParseIKEv2Message( in, &ikemsg, &len, session ) ) - { - if(ikemsg!=NULL) free (ikemsg); handler->eap_ds->request->code=PW_EAP_FAILURE; INFO(IKEv2_LOG_PREFIX "Discarded packet"); + return 1; } - if( !ikemsg || !len ) // send fragment ack - { - if(session->SK_ready) session->include_integ=1; - olen = CreateFragmentAck( in, &out, session ); // confirm fragment - talloc_free(in); - in=NULL; - if(ComposeRadMsg(out,olen,handler->eap_ds)){ + /* Send fragment ack */ + if (!ikemsg || !len) { + if (session->SK_ready) session->include_integ = 1; + + olen = CreateFragmentAck(in, &out, session); // confirm fragment + TALLOC_FREE(in); + + if (compose_rad_message(out,olen,handler->eap_ds)) { free(out); return 0; } + free(out); return 1; } - talloc_free(in); - in=NULL; - - uint8_t *sikemsg=NULL; //out message - u_int32_t slen=0; + TALLOC_FREE(in); - if( IKEv2ProcessMsg( i2, ikemsg, &sikemsg, &slen, session) != IKEv2_RET_OK ) - { + if (IKEv2ProcessMsg(i2, ikemsg, &sikemsg, &slen, session) != IKEv2_RET_OK) { INFO(IKEv2_LOG_PREFIX "EAP_STATE_DISCARD"); //session->State = EAP_STATE_DISCARD; free(out); return 1; } - free( ikemsg ); + free(ikemsg); - if( slen != 0 ) //if there is there is something to send - { - olen = CreateIKEv2Message(i2, sikemsg, slen, false, 0, session, &out ); - //bobo: a to co ? - if( session->fragdata ) - session->sendfrag = true; + /* If there is there is something to send */ + if (slen != 0){ + olen = CreateIKEv2Message(i2, sikemsg, slen, false, 0, session, &out); + if (session->fragdata) session->sendfrag = true; } else { - - if( session->Status == IKEv2_SST_FAILED ) - { + if (session->Status == IKEv2_SST_FAILED ) { INFO(IKEv2_LOG_PREFIX "FAILED"); olen = CreateResultMessage( false, session, &out ); } - if( session->Status == IKEv2_SST_ESTABLISHED ) - { - INFO(IKEv2_LOG_PREFIX "SUCCESS"); - olen = CreateResultMessage( true, session, &out ); - session->fFastReconnect=i2->enableFastReconnect; + if(session->Status == IKEv2_SST_ESTABLISHED) { + INFO(IKEv2_LOG_PREFIX "SUCCESS"); + olen = CreateResultMessage(true, session, &out); + session->fFastReconnect = i2->enableFastReconnect; - //bobo:session->eapKeyData jest zle zainicjalizowane tutaj !!!!!!!!!!!!!! nie jest NULL!!!!!!!!!!1!!!!!!!!!!!!!!!!!!!!!!!11 - GenEapKeys(session,EAP_IKEv2_KEY_LEN); + GenEapKeys(session ,EAP_IKEv2_KEY_LEN); set_mppe_keys(handler); } // keep sessions in memory, only reference cleared - ikev2_data->session=NULL; + ikev2_data->session = NULL; } - if (olen>0&&out!=NULL){ - if(ComposeRadMsg(out,olen,handler->eap_ds)){ + if ((olen > 0) && (out != NULL)){ + if (compose_rad_message(out, olen, handler->eap_ds)){ free(out); return 0; } } - //eap_ds->request->code = PW_EAP_REQUEST; + free(out); return 1; } -- 2.1.4