⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsupconfig.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 5 页
字号:
/**
 * 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 + -