📄 xsupgui_events.c
字号:
/**
* Licensed under a dual GPL/BSD license. (See LICENSE file for more info.)
*
* \file xsupgui_events.c
*
* \author chris@open1x.org
*
* $Id: xsupgui_events.c,v 1.1.2.38 2008/01/21 22:51:44 chessing Exp $
* $Date: 2008/01/21 22:51:44 $
**/
#include <string.h>
#include <libxml/parser.h>
#ifndef WINDOWS
#include <stdint.h>
#endif
#include "../../src/ipc_events_index.h"
#include "../../src/ipc_events_catalog.h"
#include "../libxsupconfig/xsupconfig_structs.h"
#include "ipc_events_errors.h"
#include "xsupgui_events.h"
#include "xsupgui.h"
#include "xsupgui_request.h"
/**
* \brief When an event is generated that is a log event, call this function
* to generate a displayable string.
*
* \todo This will need to be internationalized!
*
* @param[out] ints The OS name of the interface that generated the event.
* @param[out] logline A return value that contains a printable string that
* is contained in the IPC event.
*
* \retval -1 on error ('logline' will be invalid, 'ints' may not!)
* \retval 0 unknown ('logline' *MAY* be valid. Check before using it.)
* \retval >=1 success, with 'logline' being at the log level defined by
* \ref xsupgui_events.h
*
* \warning The caller is expected to free the memory that is allocated
* for 'logline'.
**/
int xsupgui_events_generate_log_string(char **ints, char **logline)
{
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL;
xmlNodePtr log = NULL;
xmlNodePtr msg = NULL;
xmlNodePtr t = NULL;
int retval = REQUEST_SUCCESS;
char *level = NULL;
char *temp = NULL;
int id = 0;
(*ints) = NULL;
(*logline) = NULL;
doc = xsupgui_get_event_doc();
if (doc == NULL)
{
return IPC_ERROR_NULL_DOCUMENT;
}
root = xmlDocGetRootElement(doc);
if (root == NULL)
{
retval = IPC_ERROR_BAD_RESPONSE;
goto gen_log_done;
}
log = xsupgui_request_find_node(root->children, "Log");
if (log == NULL)
{
retval = IPC_ERROR_BAD_RESPONSE_DATA;
goto gen_log_done;
}
t = xsupgui_request_find_node(log->children, "Interface");
if (t == NULL)
{
retval = IPC_ERROR_BAD_RESPONSE_DATA;
goto gen_log_done;
}
(*ints) = xmlNodeGetContent(t);
msg = xsupgui_request_find_node(log->children, "Message");
if (msg == NULL)
{
retval = IPC_ERROR_BAD_RESPONSE_DATA;
goto gen_log_done;
}
(*logline) = xmlNodeGetContent(msg);
gen_log_done:
return retval;
}
/**
* \brief Go through an event document that has been identified as being
* from a state machine, and return the values it stores.
*
* @param[out] intf The name of the interface that generated the event.
* @param[out] sm An integer that identifies the type of state machine
* that generated the event.
* @param[out] oldstate The state that the state machine was in before
* it changed to the new state.
* @param[out] newstate The state that the state machine is in now.
*
* @param[out] tncconnectionid The TNC Connection ID corresponding to this
*
* \retval -1 on error (all data will be invalid)
* \retval 0 on success
**/
int xsupgui_events_get_state_change(char **intf, int *sm, int *oldstate, int *newstate, uint32_t *tncconnectionid)
{
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL, t = NULL;
int retval = 0;
char *value = NULL;
doc = xsupgui_get_event_doc();
if (doc == NULL)
{
return -1;
}
root = xmlDocGetRootElement(doc);
if (root == NULL)
{
retval = -1;
goto state_change_done;
}
t = xsupgui_request_find_node(root->children, "State_Transition");
if (t == NULL)
{
retval = -1;
goto state_change_done;
}
t = t->children;
t = xsupgui_request_find_node(t, "Interface");
if (t == NULL)
{
retval = -1;
goto state_change_done;
}
(*intf) = xmlNodeGetContent(t);
t = xsupgui_request_find_node(t, "Statemachine");
if (t == NULL)
{
retval = -1;
goto state_change_done;
}
value = xmlNodeGetContent(t);
(*sm) = atoi(value);
free(value);
value = NULL;
t = xsupgui_request_find_node(t, "Old_State");
if (t == NULL)
{
retval = -1;
goto state_change_done;
}
value = xmlNodeGetContent(t);
(*oldstate) = atoi(value);
free(value);
value = NULL;
t = xsupgui_request_find_node(t, "New_State");
if (t == NULL)
{
retval = -1;
goto state_change_done;
}
value = xmlNodeGetContent(t);
(*newstate) = atoi(value);
free(value);
value = NULL;
// Note that if this tag doesn't exist, we still need to return
// a value, otherwise non-tnc builds will fail here.
t = xsupgui_request_find_node(t, "TNC_Connection_ID");
if (t == NULL)
{
// For non-tnc versions of XSupplicant.
(*tncconnectionid) = 0xFFFFFFFF;
}
else
{
value = xmlNodeGetContent(t);
(*tncconnectionid) = atoi(value);
}
free(value);
value = NULL;
state_change_done:
//xsupgui_free_event_doc();
return retval;
}
/**
* \brief Given an event document, parse it, and determine the event ID, so that
* the caller can make the proper request.
*
* @param[in] doc The XML document that was returned from the backend supplicant.
*
* \retval -1 couldn't determine the ID from the document
* \retval >0 the ID value for the message
**/
long int xsupgui_events_get_event_num(xmlDocPtr doc)
{
xmlNodePtr n, t;
long int retval = 0;
n = xmlDocGetRootElement(doc);
if (n == NULL) return -1;
/**
* All event checks below should be checked from most likely to
* least likely in an effort to reduce the work needed to
* process them!
**/
t = xsupgui_request_find_node(n->children, "State_Transition");
if (t != NULL)
{
retval = IPC_EVENT_STATEMACHINE;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "Log");
if (t != NULL)
{
retval = IPC_EVENT_LOG;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "UI_Event");
if (t != NULL)
{
retval = IPC_EVENT_UI;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "Wireless_Scan_Complete");
if (t != NULL)
{
retval = IPC_EVENT_SCAN_COMPLETE;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "TNC_Event");
if (t != NULL)
{
retval = IPC_EVENT_TNC_UI;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "TNC_Request_Event");
if (t != NULL)
{
retval = IPC_EVENT_TNC_UI_REQUEST;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "TNC_Request_Batch_Event");
if (t != NULL)
{
retval = IPC_EVENT_TNC_UI_BATCH_REQUEST;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "Error_Event");
if (t != NULL)
{
retval = IPC_EVENT_ERROR;
goto event_num_done;
}
t = xsupgui_request_find_node(n->children, "EAP_Password_Request");
if (t != NULL)
{
retval = IPC_EVENT_REQUEST_PWD;
goto event_num_done;
}
event_num_done:
return retval;
}
/**
* \brief Go through an event document that has been identified as being
* a scan complete, and find the interface name that generated the
* event.
*
* @param[out] intf The name of the interface that generated the event.
*
* \retval -1 on error (all data will be invalid)
* \retval 0 unknown (all data should be considered invalid)
* \retval >=1 success
**/
int xsupgui_events_get_scan_complete_interface(char **intf)
{
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL, t = NULL;
int retval = 0;
doc = xsupgui_get_event_doc();
if (doc == NULL)
{
// xsupgui_free_event_doc();
return -1;
}
root = xmlDocGetRootElement(doc);
if (root == NULL)
{
retval = -1;
goto done;
}
t = xsupgui_request_find_node(root->children, "Wireless_Scan_Complete");
if (t == NULL)
{
retval = -1;
goto done;
}
t = t->children;
t = xsupgui_request_find_node(t, "Interface");
if (t == NULL)
{
retval = -1;
goto done;
}
(*intf) = xmlNodeGetContent(t);
done:
// xsupgui_free_event_doc();
return retval;
}
/**
* \brief Parse a "get password" event, and return the data to the
* caller.
*
* @param[in,out] conn_name The connection that is requesting this information.
* @param[in,out] eapmethod A string that identifies the EAP method that is requesting
* the authentication method.
* @param[in,out] chalstr The challenge string to display to the user.
*
* \retval -1 on error (all data will be invalid)
* \retval 0 unknown (all data should be considered invalid)
* \retval >=1 success
**/
int xsupgui_events_get_passwd_challenge(char **conn_name, char **eapmethod, char **chalstr)
{
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL, t = NULL;
int retval = 0;
doc = xsupgui_get_event_doc();
if (doc == NULL)
{
// xsupgui_free_event_doc();
return -1;
}
root = xmlDocGetRootElement(doc);
if (root == NULL)
{
retval = -1;
goto done;
}
t = xsupgui_request_find_node(root->children, "EAP_Password_Request");
if (t == NULL)
{
retval = -1;
goto done;
}
t = t->children;
t = xsupgui_request_find_node(t, "Connection_Name");
if (t == NULL)
{
retval = -1;
goto done;
}
(*conn_name) = xmlNodeGetContent(t);
t = xsupgui_request_find_node(t, "EAP_Method");
if (t == NULL)
{
retval = -1;
goto done;
}
(*eapmethod) = xmlNodeGetContent(t);
t = xsupgui_request_find_node(t, "Challenge_String");
if (t == NULL)
{
retval = -1;
goto done;
}
(*chalstr) = xmlNodeGetContent(t);
done:
// xsupgui_free_event_doc();
return retval;
}
/**
* \brief Allocate enough memory to safely return an error string, and
* assemble the string from the master string, and the argument
* that came across IPC.
*
* @param[in,out] errstr The resulting error string.
* @param[in] instr The "master" string from ipc_events_errors.h
* @param[in] arg The argument that was sent from the supplicant.
**/
void xsupgui_events_build_error(char **errstr, char *instr, char *arg)
{
char *mystr = NULL;
if (instr == NULL) (*errstr) = NULL; // Nothing to do.
if (arg == NULL)
{
(*errstr) = strdup(instr);
return;
}
// This malloc() will result in a buffer that is at least 2 bytes larger than
// what we really need. So, we should be safe from overflows.
mystr = malloc(strlen(instr) + strlen(arg) + 10);
if (mystr == NULL)
{
(*errstr) = NULL;
return;
}
memset(mystr, 0x00, (sizeof(instr) + strlen(arg)));
sprintf(mystr, instr, arg);
(*errstr) = mystr;
}
/**
* \brief Parse an error condition event, and return the data to the
* caller.
*
* @param[in,out] errstr The reconstructed error string.
*
* \retval -1 on error (all data will be invalid)
* \retval 0 unknown (all data should be considered invalid)
* \retval >=1 success
**/
int xsupgui_events_get_error(int *errnum, char **errstr)
{
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL, t = NULL, n = NULL;
char *value = NULL;
int code = 0;
int retval = 0;
if (errnum == NULL) return -1;
if (errstr == NULL) return -1;
(*errnum) = 0;
doc = xsupgui_get_event_doc();
if (doc == NULL)
{
return -1;
}
root = xmlDocGetRootElement(doc);
if (root == NULL)
{
retval = -1;
goto done;
}
t = xsupgui_request_find_node(root->children, "Error_Event");
if (t == NULL)
{
retval = -1;
goto done;
}
t = t->children;
n = xsupgui_request_find_node(t, "Error_Code");
if (n == NULL)
{
retval = -1;
goto done;
}
value = xmlNodeGetContent(n);
code = atoi(value);
(*errnum) = code;
free(value);
n = xsupgui_request_find_node(n, "Argument");
if (n == NULL)
{
retval = -1;
goto done;
}
value = xmlNodeGetContent(n);
// Now, build the string.
switch (code)
{
case IPC_EVENT_ERROR_CANT_START_SCAN:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_CANT_START_SCAN_STR, value);
break;
case IPC_EVENT_ERROR_TIMEOUT_WAITING_FOR_ID:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_TIMEOUT_WAITING_FOR_ID_STR, value);
break;
case IPC_EVENT_ERROR_TIMEOUT_DURING_AUTH:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_TIMEOUT_DURING_AUTH_STR, value);
break;
case IPC_EVENT_ERROR_MALLOC:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_MALLOC_STR, value);
break;
case IPC_EVENT_ERROR_GET_MAC:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_GET_MAC_STR, value);
break;
case IPC_EVENT_ERROR_CANT_CREATE_WIRELESS_CTX:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_CANT_CREATE_WIRELESS_CTX_STR, value);
break;
case IPC_EVENT_ERROR_SEND_FAILED:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_SEND_FAILED_STR, value);
break;
case IPC_EVENT_ERROR_GETTING_INT_INFO:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_GETTING_INT_INFO_STR, value);
break;
case IPC_EVENT_ERROR_GETTING_SCAN_DATA:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_GETTING_SCAN_DATA_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_802_11_AUTH_MODE:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_802_11_AUTH_MODE_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_802_11_ENC_MODE:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_802_11_ENC_MODE_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_802_11_INFRA_MODE:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_802_11_INFRA_MODE_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_SSID:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_SSID_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_BSSID:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_BSSID_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_GETTING_BSSID:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_GETTING_BSSID_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_GETTING_SSID:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_GETTING_SSID_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_WEP_KEY:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_WEP_KEY_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_TKIP_KEY:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_TKIP_KEY_STR, value);
break;
case IPC_EVENT_ERROR_FAILED_SETTING_CCMP_KEY:
xsupgui_events_build_error(errstr, IPC_EVENT_ERROR_FAILED_SETTING_CCMP_KEY_STR, value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -