/*
* Reaver - Initialization functions
* Copyright (c) 2011, Tactical Network Solutions, Craig Heffner <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
#include "init.h"
/*
* Generates a wps_config structure which is passed to wps_init() to create
* an initial wps_data structure.
*/
struct wps_data *initialize_wps_data()
{
struct wps_config *wpsconf = NULL;
struct wps_data *wps = NULL;
struct wps_registrar_config *reg_conf = NULL;
wpsconf = malloc(sizeof(struct wps_config));
if(!wpsconf)
{
perror("malloc");
goto end;
}
memset(wpsconf, 0, sizeof(struct wps_config));
reg_conf = malloc(sizeof(struct wps_registrar_config));
if(!reg_conf)
{
perror("malloc");
goto end;
}
memset(reg_conf, 0, sizeof(struct wps_registrar_config));
/* Configure ourselves as a registrar */
wpsconf->registrar = 1;
/* Tell the AP to not generate a random PSK */
reg_conf->disable_auto_conf = 1;
/* Allocate space for the wps_context structure member */
wpsconf->wps = malloc(sizeof(struct wps_context));
if(!wpsconf->wps)
{
perror("malloc");
goto end;
}
memset(wpsconf->wps, 0, sizeof(struct wps_context));
/*
* Initialize the registrar sub-structure. This is necessary when calling
* wpa_supplicant functions to build registrar response payloads.
*/
wpsconf->wps->registrar = wps_registrar_init(wpsconf->wps, (const struct wps_registrar_config *) reg_conf);
if(wpsconf->wps->registrar == NULL)
{
cprintf(CRITICAL, "[X] ERROR: Failed to initialize registrar structure!\n");
}
/*
* In registrar mode, only the uuid wps_context member needs to be
* populated in order to call wps_init(). If acting as an enrollee,
* the wps_device_data sub-structure must also be populated.
*/
if(os_get_random(wpsconf->wps->uuid, UUID_LEN) == -1)
{
memcpy(wpsconf->wps->uuid, DEFAULT_UUID, UUID_LEN);
}
wps = wps_init(wpsconf);
if(wps)
{
/* Report that we are a Windows 7 registrar, if --win7 was specified on the command line */
if(wps->wps && get_win7_compat())
{
wps->wps->dev.device_name = WPS_DEVICE_NAME;
wps->wps->dev.manufacturer = WPS_MANUFACTURER;
wps->wps->dev.model_name = WPS_MODEL_NAME;
wps->wps->dev.model_number = WPS_MODEL_NUMBER;
memcpy(wps->wps->dev.pri_dev_type, WPS_DEVICE_TYPE, WPS_DEV_TYPE_LEN);
memcpy((void *) &wps->wps->dev.os_version, WPS_OS_VERSION, 4);
wps->wps->dev.rf_bands = WPS_RF_BANDS;
}
}
end:
if(wpsconf) free(wpsconf);
if(reg_conf) free(reg_conf);
return wps;
}
/* Initializes pcap capture settings and returns a pcap handle on success, NULL on error */
pcap_t *capture_init(char *capture_source)
{
pcap_t *handle;
char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
int status;
int activate_rfmon = 0;
handle = pcap_open_offline(capture_source, errbuf);
if(handle) return handle;
#ifdef __APPLE__
// must disassociate from any current AP. This is the only way.
pid_t pid = fork();
if (!pid) {
char* argv[] = {"/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", "-z", NULL};
execve("/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport", argv, NULL);
}
waitpid(pid,&status,0);
activate_rfmon = 1;
#endif
handle = pcap_create(capture_source, errbuf);
if (handle) {
pcap_set_snaplen(handle, 65536);
pcap_set_timeout(handle, 50);
pcap_set_rfmon(handle, activate_rfmon);
pcap_set_promisc(handle, 1);
if(!(status = pcap_activate(handle)))
return handle;
if(status == PCAP_ERROR_RFMON_NOTSUP) {
pcap_set_rfmon(handle, 0);
status = pcap_activate(handle);
if(!status) return handle;
}
cprintf(CRITICAL, "[X] ERROR: pcap_activate status %d\n", status);
static const char *pcap_errmsg[] = {
[1] = "generic error code",
[2] = "loop terminated by pcap_breakloop",
[3] = "the capture needs to be activated",
[4] = "the operation can't be performed on already activated captures",
[5] = "no such device exists",
[6] = "this device doesn't support rfmon (monitor) mode",
[7] = "operation supported only in monitor mode",
[8] = "no permission to open the device",
[9] = "interface isn't up",
[10]= "this device doesn't support setting the time stamp type",
[11]= "you don't have permission to capture in promiscuous mode",
[12]= "the requested time stamp precision is not supported",
};
if(status < 0 && status > -13)
cprintf(CRITICAL, "[X] PCAP: %s\n", pcap_errmsg[-status]);
pcap_close(handle);
handle = 0;
}
if(!handle) {
cprintf(CRITICAL, "couldn't get pcap handle, exiting\n");
exit(1);
}
return handle;
}