📄 eappeap.c
字号:
/******************************************************************* * EAPPEAP Function implementations * * Licensed under a dual GPL/BSD license. (See LICENSE file for more info.) * * File: eappeap.c * * Authors: Chris.Hessing@utah.edu * * $Id: eappeap.c,v 1.43 2006/06/01 22:49:50 galimorerpg Exp $ * $Date: 2006/06/01 22:49:50 $ * $Log: eappeap.c,v $ * Revision 1.43 2006/06/01 22:49:50 galimorerpg * Converted all instances of u_char to uint8_t * Fixed a bad #include in the generic frame handler. * * Revision 1.42 2006/05/29 04:17:58 chessing * Fixes for some memory leaks. * * Revision 1.41 2006/04/25 01:17:44 chessing * LOTS of code cleanups, new error checking/debugging code added, and other misc. fixes/changes. * * Revision 1.40 2006/03/28 21:16:07 chessing * Fixes to EAP-AKA, and PEAP. PEAP now handles inner success messages, and works with Funk SBR. * * Revision 1.39 2005/11/12 23:59:52 chessing * Some typo/debug patches from Pekka Savola. * * Revision 1.38 2005/10/17 03:56:54 chessing * Updates to the libxsupconfig library. It no longer relies on other source from the main tree, so it can be used safely in other code with problems. * * Revision 1.37 2005/10/14 02:26:18 shaftoe * - cleanup gcc 4 warnings * - (re)add support for a pid in the form of /var/run/xsupplicant.<iface>.pid * * -- Eric Evans <eevans@sym-link.com> * * Revision 1.36 2005/09/14 03:34:54 chessing * Small cosmetic changes. Default association mode is now auto instead of manual. Fixes for bug IDs #1290449 & #1290323. * * Revision 1.35 2005/08/25 03:34:06 chessing * Removed a bunch of functions from config.c that could be handled better in other ways. * * Revision 1.34 2005/08/09 01:39:17 chessing * Cleaned out old commit notes from the released version. Added a few small features including the ability to disable the friendly warnings that are spit out. (Such as the warning that is displayed when keys aren't rotated after 10 minutes.) We should also be able to start when the interface is down. Last, but not least, we can handle empty network configs. (This may be useful for situations where there isn't a good reason to have a default network defined.) * * *******************************************************************/#include <string.h>#include <stdlib.h>#include "profile.h"#include "xsupconfig.h"#include "xsup_debug.h"#include "xsup_err.h"#include "frame_structs.h"#include "eap_types/tls/eaptls.h"#include "eap_types/tls/tls_funcs.h"#include "eap.h"#include "eappeap.h"#include "peap_phase2.h"#ifdef USE_EFENCE#include <efence.h>#endifint eappeap_setup(struct generic_eap_data *thisint){ struct tls_vars *mytls_vars; struct phase2_data *p2d; struct config_eap_peap *userdata; struct config_globals *globals; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return XEMALLOC; userdata = (struct config_eap_peap *)thisint->eap_conf_data; if (!xsup_assert((userdata != NULL), "userdata != NULL", FALSE)) return XENOUSERDATA; // First, set up the structure to hold all of our instance specific // variables. thisint->eap_data = (char *)malloc(sizeof(struct tls_vars)); if (thisint->eap_data == NULL) { debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for eap_data in PEAP!\n"); return XEMALLOC; } memset(thisint->eap_data, 0, sizeof(struct tls_vars)); mytls_vars = (struct tls_vars *)thisint->eap_data; // Set our variables to NULL. mytls_vars->ctx = NULL; mytls_vars->ssl = NULL; mytls_vars->ssl_in = NULL; mytls_vars->ssl_out = NULL; mytls_vars->tlsoutdata = NULL; mytls_vars->tlsoutsize = 0; mytls_vars->tlsoutptr = 0; mytls_vars->cncheck = userdata->cncheck; mytls_vars->cnexact = userdata->cnexact; mytls_vars->resume = userdata->session_resume; mytls_vars->quickResponse = FALSE; mytls_vars->cert_loaded = FALSE; mytls_vars->verify_mode = SSL_VERIFY_PEER; mytls_vars->phase2data = (char *)malloc(sizeof(struct phase2_data)); if (mytls_vars->phase2data == NULL) return XEMALLOC; memset(mytls_vars->phase2data, 0, sizeof(struct phase2_data)); p2d = (struct phase2_data *)mytls_vars->phase2data; p2d->peap_version = 0; p2d->eapdata = NULL; debug_printf(DEBUG_EVERYTHING, "(EAP-PEAP) Initialized.\n"); if (tls_funcs_init(thisint) != XENONE) { debug_printf(DEBUG_NORMAL, "Couldn't initialize OpenSSL!\n"); return XETLSINIT; } if ((!userdata->root_cert) && (!userdata->root_dir)) { debug_printf(DEBUG_NORMAL, "The root cert is set to NULL! We cannot continue!\n"); return XENOUSERDATA; } if ((userdata->root_cert) && (strcmp(userdata->root_cert, "NONE") == 0)) { // We were told not to verify certificates. Spew out a warning, and // then do it! mytls_vars->verify_mode = SSL_VERIFY_NONE; globals = config_get_globals(); if (globals != NULL) { if (!TEST_FLAG(globals->flags, CONFIG_GLOBALS_NO_FRIENDLY_WARNINGS)) { debug_printf(DEBUG_NORMAL, "****WARNING**** Turning off certificate " "verification is a *VERY* bad idea! You should not " "use this mode outside of basic testing, as it will " "compromise the security of your connection!\n"); } } } else { if (tls_funcs_load_root_certs(thisint, userdata->root_cert, userdata->root_dir, userdata->crl_dir) != XENONE) { debug_printf(DEBUG_NORMAL, "Couldn't load root certificates!\n"); return XETLSINIT; } } if ((userdata->user_cert != NULL) && ((userdata->user_key_pass != NULL) || (thisint->tempPwd != NULL))) { debug_printf(DEBUG_NORMAL, "Using user certificate for PEAP!\n"); tls_funcs_load_user_cert(thisint, userdata->user_cert, userdata->user_key, userdata->user_key_pass, userdata->random_file); mytls_vars->cert_loaded = TRUE; } if (userdata->user_cert == NULL) mytls_vars->cert_loaded = TRUE; return XENONE;}int eappeap_process(struct generic_eap_data *thisint, uint8_t *dataoffs, int insize, uint8_t *outframe, int *outsize){ struct config_eap_peap *userdata; struct tls_vars *mytls_vars; struct phase2_data *p2d; int peap_version; int retVal = XENONE; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return XEMALLOC; if (!xsup_assert((dataoffs != NULL), "dataoffs != NULL", FALSE)) return XEMALLOC; if (!xsup_assert((outframe != NULL), "outframe != NULL", FALSE)) return XEMALLOC; if (!xsup_assert((outsize != NULL), "outsize != NULL", FALSE)) return XEMALLOC; if (insize > 1520) { debug_printf(DEBUG_NORMAL, "Packet too large in eappeap_process()! Ignoring!\n"); return XEBADPACKETSIZE; } userdata = (struct config_eap_peap *)thisint->eap_conf_data; if (!xsup_assert((userdata != NULL), "userdata != NULL", FALSE)) return XENOUSERDATA; mytls_vars = (struct tls_vars *)thisint->eap_data; if (!mytls_vars) { debug_printf(DEBUG_NORMAL, "Invalid EAP type data passed in to eappeap_process()!\n"); return XEMALLOC; } p2d = (struct phase2_data *)mytls_vars->phase2data; if (!p2d) { debug_printf(DEBUG_NORMAL, "No phase 2 data available in eappeap_process()!\n"); return XEMALLOC; } // The state machine wants to know if we have anything else to say. // We may be waiting for the server to send us more information, or // we may need to send a request to the GUI for a password, and wait // for an answer. // PEAP is slightly different than others. Since we don't *need* to have // a client certificate to make things work correctly, we may not need // a password here. if (userdata->user_cert != NULL) { if ((thisint->tempPwd == NULL) && (userdata->user_key_pass == NULL)) { thisint->need_password = 1; thisint->eaptype = strdup("EAP-PEAP User Certificate"); thisint->eapchallenge = NULL; *outsize = 0; return XENONE; } if ((mytls_vars->cert_loaded == FALSE) && ((thisint->tempPwd != NULL) || (userdata->user_key_pass != NULL))) { // Load the user certificate. if ((retVal = tls_funcs_load_user_cert(thisint, userdata->user_cert, userdata->user_key, userdata->user_key_pass, userdata->random_file))!=XENONE) { debug_printf(DEBUG_NORMAL, "Error loading user certificate!\n"); return retVal; } else { // Otherwise, the certificate is loaded. mytls_vars->cert_loaded = TRUE; // If we used the GUI to get a password, we need to free it // so that phase 2 can make use of it. if (thisint->tempPwd != NULL) { free(thisint->tempPwd); thisint->tempPwd = NULL; } } } } if (dataoffs == NULL) return XENONE;/* PEAP adds some version bits to flags byte. They need to be stripped out. */ peap_version = ((uint8_t)dataoffs[0] & 0x03); // Get the version #. set_peap_version(p2d, peap_version); // Tell PEAP what version we want to use. dataoffs[0] = ((uint8_t)dataoffs[0] & 0xfc); // Mask out the version bits. retVal = tls_funcs_decode_packet(thisint, (char *) dataoffs, insize, (char *) outframe, outsize, (phase2_call)peap_do_phase2, userdata->chunk_size); if ((retVal != XENONE) && (retVal != XINNERSUCCESS)) { return XEGENERROR; } // We need to reset the version bits, just in case we store this frame for // use later. dataoffs[0] = dataoffs[0]+p2d->peap_version; if (*outsize <= 0) { debug_printf(DEBUG_AUTHTYPES, "Nothing returned from PEAP!\n"); *outsize = 0; return retVal; } // By the time we come out the first time, we should have decided on which // PEAP version we want to use. So, set up the values needed to generate // the keying material. if (mytls_vars->sessionkeyconst == NULL) { switch (p2d->peap_version) { case PEAP_VERSION0: debug_printf(DEBUG_AUTHTYPES, "Setting Key Constant for PEAP v0!\n"); mytls_vars->sessionkeyconst = (char *)malloc(PEAP_SESSION_KEY_CONST_SIZE); if (mytls_vars->sessionkeyconst == NULL) return XEMALLOC; bzero(mytls_vars->sessionkeyconst, PEAP_SESSION_KEY_CONST_SIZE); strncpy(mytls_vars->sessionkeyconst, PEAP_SESSION_KEY_CONST, PEAP_SESSION_KEY_CONST_SIZE); mytls_vars->sessionkeylen = PEAP_SESSION_KEY_CONST_SIZE; break; case PEAP_VERSION1: debug_printf(DEBUG_AUTHTYPES, "Setting Key Constant for PEAP v1!\n"); mytls_vars->sessionkeyconst = (char *)malloc(PEAPv1_SESSION_KEY_CONST_SIZE); if (mytls_vars->sessionkeyconst == NULL) return XEMALLOC; bzero(mytls_vars->sessionkeyconst, PEAPv1_SESSION_KEY_CONST_SIZE); if (userdata->proper_peapv1 == 0) { strncpy(mytls_vars->sessionkeyconst, PEAP_SESSION_KEY_CONST, PEAP_SESSION_KEY_CONST_SIZE); mytls_vars->sessionkeylen = PEAP_SESSION_KEY_CONST_SIZE; } else { debug_printf(DEBUG_AUTHTYPES, "Using proper PEAPv1 key constant" "!\n"); strncpy(mytls_vars->sessionkeyconst, PEAPv1_SESSION_KEY_CONST, PEAPv1_SESSION_KEY_CONST_SIZE); mytls_vars->sessionkeylen = PEAPv1_SESSION_KEY_CONST_SIZE; } break; default: debug_printf(DEBUG_NORMAL, "Unknown PEAP version!\n"); break; } } if (*outsize > 0) { outframe[0] = outframe[0]+p2d->peap_version; } return retVal;}int eappeap_get_keys(struct interface_data *thisint){ struct config_network *network_data; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return XEMALLOC; network_data = config_get_network_config(); if (!xsup_assert((network_data != NULL), "network_data != NULL", FALSE)) return XEMALLOC; if (thisint->keyingMaterial != NULL) { free(thisint->keyingMaterial); } thisint->keyingMaterial = (uint8_t *) tls_funcs_gen_keyblock(network_data->activemethod); thisint->keyingLength = 32; if (thisint->keyingMaterial == NULL) return -1; return 0;}int eappeap_cleanup(struct generic_eap_data *thisint){ struct tls_vars *mytls_vars; if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return XEMALLOC; mytls_vars = (struct tls_vars *)thisint->eap_data; if (!mytls_vars) { debug_printf(DEBUG_NORMAL, "Invalid EAP type data in eappeap_cleanup()!\n"); return XEMALLOC; } if (mytls_vars->phase2data != NULL) { struct phase2_data *p2d; p2d = (struct phase2_data *) mytls_vars->phase2data; free(p2d->eapdata); free(mytls_vars->phase2data); } tls_funcs_cleanup(thisint); debug_printf(DEBUG_EVERYTHING, "(EAP-PEAP) Cleaned up.\n"); return XENONE;}int eappeap_failed(struct generic_eap_data *thisint){ if (!xsup_assert((thisint != NULL), "thisint != NULL", FALSE)) return XEMALLOC; // Let our phase 2 die out, if there is one. peap_phase2_failed(thisint); tls_funcs_failed(thisint); debug_printf(DEBUG_EVERYTHING, "(EAP-PEAP) Failed. Resetting.\n"); return XENONE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -