📄 xsupconfig.c
字号:
/**
* Implementation for parsing configuration file, and storing needed data.
*
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file xsupconfig.c
*
* \author chris@open1x.org
*
* $Id: xsupconfig.c,v 1.20.2.93 2008/02/04 19:46:50 chessing Exp $
* $Date: 2008/02/04 19:46:50 $
**/
#include <stdlib.h>
#ifndef WINDOWS
#include <strings.h>
#endif
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include "../../src/xsup_err.h"
#include "../../src/xsup_common.h"
#include "../../src/xsup_debug.h"
#include "xsupconfig_structs.h"
#include "xsupconfig_vars.h"
#include "xsupconfig_devices.h"
#include "xsupconfig.h"
#include "xsupconfig_structs.h"
#include "xsupconfig_parse.h"
#include "../../src/error_prequeue.h"
#ifdef USE_EFENCE
#include <efence.h>
#endif
char *forced_profile = NULL;
#define FREE_STRING(x) if (x != NULL) {free(x); x = NULL;}
/**
* \brief Load an Xsupplicant configuration file in to memory.
*
* Load all of the configuration information in to memory.
*
* @param[in] path_to_config The full path to the configuration file to be loaded in to
* memory. (i.e. /etc/xsupplicant.conf)
*
* \retval XENONE on success
**/
int config_setup(char *path_to_config)
{
xmlDocPtr doc;
xmlNode *root_element = NULL;
char *errstr = NULL;
TRACE
xsupconfig_devices_init();
doc = loadConfig(path_to_config);
if (doc == NULL)
{
// DO NOT change this to xsupconfig_common_log(), since it will cause linker issues with libxsupgui!
if (xsup_common_in_startup() != TRUE)
{
debug_printf(DEBUG_NORMAL, "Couldn't load configuration file '%s'!\n", path_to_config);
}
return XECONFIGFILEFAIL;
}
root_element = xmlDocGetRootElement(doc);
xsupconfig_parse(root_element, baselevel, NULL);
// set the file name
config_fname = _strdup(path_to_config);
xmlFreeDoc(doc);
xmlCleanupParser();
return XENONE;
}
/**
* \brief Return a pointer to the master structure that contains all of the
* connection configurations.
*
* \retval NULL if there are no connections loaded in to memory. (Indicates
* that either there are no connections defined in the configuration file
* or, the configuration file isn't loaded.)
* \retval ptr to the connections structure.
*
* \warning You should *NOT* free the pointer that is returned from this function call. It
* is *NOT* a copy of the connections structure, it is a pointer to the master
* configuration structure! If you free it, bad stuff *WILL* happen.
**/
struct config_connection *config_get_connections()
{
return conf_connections;
}
/**
* \brief Return a pointer to the master structure that contains all of the
* trusted server information.
*
* \retval NULL if there are no trusted servers loaded in to memory. (Indicates
* that either there are no trusted servers defined in the configuration file
* or, the configuration file isn't loaded.)
* \retval ptr to the trusted servers structure.
*
* \warning You should *NOT* free the pointer that is returned from this function call. It
* is *NOT* a copy of the connections structure, it is a pointer to the master
* configuration structure! If you free it, bad stuff *WILL* happen.
**/
struct config_trusted_servers *config_get_trusted_servers()
{
return conf_trusted_servers;
}
/**
* \brief Return a pointer to the master structure that contains all of the
* managed networks information.
*
* \retval NULL if there are no managed networks loaded in to memory. (Indicates
* that either there are no managed networks defined in the configuration file
* or, the configuration file isn't loaded.)
* \retval ptr to the trusted servers structure.
*
* \warning You should *NOT* free the pointer that is returned from this function call. It
* is *NOT* a copy of the connections structure, it is a pointer to the master
* configuration structure! If you free it, bad stuff *WILL* happen.
**/
struct config_managed_networks *config_get_managed_networks()
{
return conf_managed_networks;
}
/**
* \brief Change the head of the linked list for managed networks to point
* to something else.
*
* @param[in] nets A pointer to the new head of the list.
**/
void config_set_managed_networks(struct config_managed_networks *nets)
{
conf_managed_networks = nets;
}
/**
* \brief Return a pointer to the master structure that contains all of the
* profile configurations.
*
* \retval NULL if there are no profiles loaded in to memory. (Indicates
* that either there are no profiles defined in the configuration file
* or, the configuration file isn't loaded.
*
* \warning You should *NOT* free the pointer that is returned from this function call. It
* is *NOT* a copy of the profiles structure, it is a pointer to the master
* profiles structure! If you free it, bad stuff *WILL* happen.
**/
struct config_profiles *config_get_profiles()
{
return conf_profiles;
}
/**
* \brief Check the <Globals> part of the configuration to see if
* the user wants "friendly warnings" enabled.
*
* \retval TRUE enable friendly warnings
* \retval FALSE disable friendly warnings
**/
uint8_t config_get_friendly_warnings()
{
TRACE
if (TEST_FLAG(conf_globals->flags,
CONFIG_GLOBALS_NO_FRIENDLY_WARNINGS))
{
// We don't want friendly warnings.
return FALSE;
}
return TRUE;
}
/**
* \brief Return the value of the idleWhile timer.
*
* \retval 0..255 the number of seconds to count down on the idleWhile timer.
*
* \note This will return either the value that was configured in the <Globals>
* section of the configuration file, or the default value defined by
* \ref IDLE_WHILE_TIMER.
**/
uint8_t config_get_idleWhile()
{
TRACE
if (conf_globals->idleWhile_timeout == 0)
{
return IDLE_WHILE_TIMER;
}
return conf_globals->idleWhile_timeout;
}
/**
* \brief Create an empty config in memory.
*
* \warning THIS FUNCTION SHOULD *NEVER* BE CALLED INSIDE OF XSUPPLICANT!!
* IT IS PROVIDED SO THAT GUI INTERFACES CAN HAVE A File|New.. OPTION!
**/
void config_create_new_config()
{
TRACE
config_fname = NULL; // We don't know what the file name will be.
// Populate the globals
initialize_config_globals(&conf_globals);
initialize_config_connections(&conf_connections);
}
/**
* \brief Change a password based on the phase 2 information for TTLS.
*
* @param[in] meth A structure that contains a pointer to EAP method
* specific configuration data, in addition to a
* numeric value that indicates the EAP type it points
* to.
* @param[in] password The new value to set the password to for the EAP
* type defined by 'meth'.
*
* \retval XENONE on success
**/
int config_change_ttls_pwd(struct config_eap_method *meth, char *password)
{
struct config_eap_ttls *ttls;
void *ptr;
ttls = (struct config_eap_ttls *)meth->method_data;
if (ttls == NULL) return -1;
switch (ttls->phase2_type)
{
case TTLS_PHASE2_PAP:
case TTLS_PHASE2_CHAP:
case TTLS_PHASE2_MSCHAP:
case TTLS_PHASE2_MSCHAPV2:
if (ttls->phase2_data == NULL)
{
ttls->phase2_data = Malloc(sizeof(struct config_pwd_only));
if (ttls->phase2_data == NULL) return -1;
}
ptr = ((struct config_pwd_only *)(ttls->phase2_data))->password;
if (ptr != NULL)
FREE(((struct config_pwd_only *)(ttls->phase2_data))->password);
((struct config_pwd_only *)(ttls->phase2_data))->password = _strdup(password);
break;
case TTLS_PHASE2_EAP:
return config_change_pwd(ttls->phase2_data, password);
break;
default:
debug_printf(DEBUG_NORMAL, "Unknown phase 2 authentication type %d!\n", ttls->phase2_type);
break;
}
return XENONE;
}
/**
* \brief Change a password based on the EAP method structure.
*
* @param[in] meth A structure that contains a pointer to EAP method
* specific configuration data, in addition to a
* numeric value that indicates the EAP type it points
* to.
* @param[in] password The new value to set the password to for the EAP
* type defined by 'meth'.
*
* \retval XENONE on success
**/
int config_change_pwd(struct config_eap_method *meth, char *password)
{
void *ptr;
if (password == NULL) return XENONE; // Nothing to do.
if (meth->method_data == NULL) return XEMALLOC;
switch (meth->method_num)
{
case EAP_TYPE_MD5:
case EAP_TYPE_LEAP:
case EAP_TYPE_GTC:
ptr = ((struct config_pwd_only *)(meth->method_data))->password;
if (ptr != NULL)
FREE(((struct config_pwd_only *)(meth->method_data))->password);
((struct config_pwd_only *)(meth->method_data))->password = _strdup(password);
break;
case EAP_TYPE_TLS:
ptr = ((struct config_eap_tls *)(meth->method_data))->user_key_pass;
if (ptr != NULL)
FREE(((struct config_eap_tls *)(meth->method_data))->user_key_pass);
((struct config_eap_tls *)(meth->method_data))->user_key_pass = _strdup(password);
break;
case EAP_TYPE_SIM:
ptr = ((struct config_eap_sim *)(meth->method_data))->password;
if (ptr != NULL)
FREE(((struct config_eap_sim *)(meth->method_data))->password);
((struct config_eap_sim *)(meth->method_data))->password = _strdup(password);
break;
case EAP_TYPE_AKA:
ptr = ((struct config_eap_aka *)(meth->method_data))->password;
if (ptr != NULL)
FREE(((struct config_eap_aka *)(meth->method_data))->password);
((struct config_eap_aka *)(meth->method_data))->password = _strdup(password);
break;
case EAP_TYPE_MSCHAPV2:
ptr = ((struct config_eap_mschapv2 *)(meth->method_data))->password;
if (ptr != NULL)
FREE(((struct config_eap_mschapv2 *)(meth->method_data))->password);
((struct config_eap_mschapv2 *)(meth->method_data))->password = _strdup(password);
break;
case EAP_TYPE_PEAP:
return config_change_pwd(((struct config_eap_peap *)(meth->method_data))->phase2, password);
break;
case EAP_TYPE_TTLS:
return config_change_ttls_pwd(meth, password);
break;
case EAP_TYPE_FAST:
return config_change_pwd(((struct config_eap_fast *)(meth->method_data))->phase2, password);
break;
default:
debug_printf(DEBUG_NORMAL, "Invalid EAP method requested! (Type %d)\n",
meth->method_num);
break;
}
return XENONE;
}
/**
* \brief Given a profile name, set the password.
*
* @param[in] prof_name A string that indicates the profile name to use.
* @param[in] password The new value to set the password to for the
* profile specified by 'prof_name'.
*
* \retval XENONE on success
**/
int config_set_pwd_on_profile(char *prof_name, char *password)
{
struct config_profiles *prof;
prof = config_find_profile(prof_name);
if (prof == NULL) return -1;
return config_change_pwd(prof->method, password);
}
/**
* \brief Locate a connection based on the SSID that is mapped to it.
*
* @param[in] ssidname The SSID name that we are looking for.
*
* \retval ptr to the connection (if found), NULL if the connection isn't found.
**/
struct config_connection *config_find_connection_from_ssid(char *ssidname)
{
struct config_connection *cur = NULL;
if (!ssidname) return NULL;
// Start at the top of the list.
cur = conf_connections;
while (cur != NULL)
{
if (cur->ssid != NULL)
{
if (strcmp(cur->ssid, ssidname) == 0) break;
}
cur = cur->next;
}
return cur;
}
/**
* \brief Locate the priority value for a named connection.
*
* Given the connection name 'matchname', find the connection, and return the
* connection priority that was assigned to it.
*
* \retval 0..255 The priority of the connection. (1 = Highest, 254 = Lowest, 255 = No priority)
*
**/
uint8_t config_get_network_priority(char *matchname)
{
struct config_connection *cur = NULL;
TRACE
if (!matchname)
return 0xff;
// Start at the top of the list.
cur = config_find_connection_from_ssid(matchname);
if (!cur) return 0xff;
return cur->priority;
}
/**
* \brief Set the forced profile value to be used later.
*
* @param[in] profilename The name of the profile to force
* the supplicant to use.
**/
void config_set_forced_profile(char *profilename)
{
TRACE
if (forced_profile != NULL)
{
free(forced_profile);
forced_profile = NULL;
}
if (profilename != NULL)
{
forced_profile = _strdup(profilename);
}
}
/**
* \brief Given a connection name, find the configuration information in memory.
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -