aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2009-11-15 12:06:17 -0800
committerJean-Baptiste Queru <jbq@google.com>2009-11-15 12:06:17 -0800
commit107783f4e1b1bdf796220b49680e97fc21a8fa7f (patch)
tree3afdf3d57fcdba5d750b6046d30de8857fa6c3dd
parentf7cdf529d818433b334ed93da380844d6b10ad96 (diff)
parentb3fb13ce35baebffc4608e6e52f2a71446973b18 (diff)
downloadwpa_supplicant-107783f4e1b1bdf796220b49680e97fc21a8fa7f.tar.gz
merge from eclair
-rw-r--r--Android.mk10
-rw-r--r--common.c3
-rw-r--r--config.c42
-rw-r--r--ctrl_iface.c13
-rw-r--r--driver_wext.c103
-rw-r--r--driver_wext.h9
-rw-r--r--eap_tls_common.c154
-rw-r--r--events.c7
-rw-r--r--if_index.c50
-rw-r--r--os_unix.c28
-rw-r--r--tls_openssl.c84
-rw-r--r--wireless_copy.h121
-rw-r--r--wpa_ctrl.c6
-rw-r--r--wpa_ctrl.h2
-rw-r--r--wpa_supplicant.c10
-rw-r--r--wpa_supplicant_i.h3
16 files changed, 387 insertions, 258 deletions
diff --git a/Android.mk b/Android.mk
index 3376f2c..5e8f07f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -33,12 +33,15 @@ endif
# To ignore possible wrong network configurations
L_CFLAGS += -DWPA_IGNORE_CONFIG_ERRORS
+# To allow non-ASCII characters in SSID
+L_CFLAGS += -DWPA_UNICODE_SSID
+
# OpenSSL is configured without engines on Android
L_CFLAGS += -DOPENSSL_NO_ENGINE
INCLUDES = external/openssl/include frameworks/base/cmds/keystore
-OBJS = config.c common.c md5.c md4.c rc4.c sha1.c des.c if_index.c
+OBJS = config.c common.c md5.c md4.c rc4.c sha1.c des.c
OBJS_p = wpa_passphrase.c sha1.c md5.c md4.c common.c des.c
OBJS_c = wpa_cli.c wpa_ctrl.c
@@ -664,7 +667,10 @@ include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_MODULE := wpa_supplicant
ifdef CONFIG_DRIVER_CUSTOM
-LOCAL_STATIC_LIBRARIES := libCustomWifi libWifiApi
+LOCAL_STATIC_LIBRARIES := libCustomWifi
+endif
+ifneq ($(BOARD_WPA_SUPPLICANT_PRIVATE_LIB),)
+LOCAL_STATIC_LIBRARIES += $(BOARD_WPA_SUPPLICANT_PRIVATE_LIB)
endif
LOCAL_SHARED_LIBRARIES := libc libcutils libcrypto libssl
LOCAL_CFLAGS := $(L_CFLAGS)
diff --git a/common.c b/common.c
index fce9254..c5b6f7d 100644
--- a/common.c
+++ b/common.c
@@ -616,8 +616,11 @@ const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
os_memcpy(ssid_txt, ssid, ssid_len);
ssid_txt[ssid_len] = '\0';
for (pos = ssid_txt; *pos != '\0'; pos++) {
+#ifndef WPA_UNICODE_SSID
+ /* Don't do this, since it prevents us from using APs with non-ASCII SSIDs */
if ((u8) *pos < 32 || (u8) *pos >= 127)
*pos = '_';
+#endif
}
return ssid_txt;
}
diff --git a/config.c b/config.c
index 6ea66de..e5aeac2 100644
--- a/config.c
+++ b/config.c
@@ -205,6 +205,25 @@ static char * wpa_config_write_str(const struct parse_data *data,
return wpa_config_write_string((const u8 *) *src, len);
}
+#ifdef WPA_UNICODE_SSID
+static char * wpa_config_write_str_unicode(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ size_t len;
+ char **src;
+
+ src = (char **) (((u8 *) ssid) + (long) data->param1);
+ if (*src == NULL)
+ return NULL;
+
+ if (data->param2)
+ len = *((size_t *) (((u8 *) ssid) + (long) data->param2));
+ else
+ len = os_strlen(*src);
+
+ return wpa_config_write_string_ascii((const u8 *) *src, len);
+}
+#endif
static int wpa_config_parse_int(const struct parse_data *data,
struct wpa_ssid *ssid,
@@ -1059,6 +1078,16 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data,
#define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
#define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
+#ifdef WPA_UNICODE_SSID
+/* STR_* variants that do not force conversion to ASCII */
+#define _STR_UNICODE(f) #f, wpa_config_parse_str, wpa_config_write_str_unicode, OFFSET(f)
+#define STR_UNICODE(f) _STR_UNICODE(f), NULL, NULL, NULL, 0
+#define _STR_LEN_UNICODE(f) _STR_UNICODE(f), OFFSET(f ## _len)
+#define STR_LEN_UNICODE(f) _STR_LEN_UNICODE(f), NULL, NULL, 0
+#define _STR_RANGE_UNICODE(f, min, max) _STR_LEN_UNICODE(f), (void *) (min), (void *) (max)
+#define STR_RANGE_UNICODE(f, min, max) _STR_RANGE_UNICODE(f, min, max), 0
+#endif
+
#define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
OFFSET(f), (void *) 0
@@ -1099,7 +1128,11 @@ static char * wpa_config_write_wep_key3(const struct parse_data *data,
* functions.
*/
static const struct parse_data ssid_fields[] = {
+#ifdef WPA_UNICODE_SSID
+ { STR_RANGE_UNICODE(ssid, 0, MAX_SSID_LEN) },
+#else
{ STR_RANGE(ssid, 0, MAX_SSID_LEN) },
+#endif
{ INT_RANGE(scan_ssid, 0, 1) },
{ FUNC(bssid) },
{ FUNC_KEY(psk) },
@@ -1163,6 +1196,15 @@ static const struct parse_data ssid_fields[] = {
{ INT_RANGE(frequency, 0, 10000) }
};
+#ifdef WPA_UNICODE_SSID
+#undef _STR_UNICODE
+#undef STR_UNICODE
+#undef _STR_LEN_UNICODE
+#undef STR_LEN_UNICODE
+#undef _STR_RANGE_UNICODE
+#undef STR_RANGE_UNICODE
+#endif
+
#undef OFFSET
#undef _STR
#undef STR
diff --git a/ctrl_iface.c b/ctrl_iface.c
index c774c86..ef93533 100644
--- a/ctrl_iface.c
+++ b/ctrl_iface.c
@@ -642,6 +642,7 @@ static int wpa_supplicant_ctrl_iface_select_network(
ssid = ssid->next;
}
wpa_s->reassociate = 1;
+ wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
wpa_supplicant_req_scan(wpa_s, 0, 0);
return 0;
@@ -670,7 +671,11 @@ static int wpa_supplicant_ctrl_iface_enable_network(
* Try to reassociate since there is no current configuration
* and a new network was made available. */
wpa_s->reassociate = 1;
+#ifdef ANDROID
+ wpa_supplicant_req_scan(wpa_s, 2, 0);
+#else
wpa_supplicant_req_scan(wpa_s, 0, 0);
+#endif
}
ssid->disabled = 0;
@@ -1249,8 +1254,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
wpa_s->disconnected = 1;
wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
} else if (os_strcmp(buf, "SCAN") == 0) {
- wpa_s->scan_req = 2;
- wpa_supplicant_req_scan(wpa_s, 0, 0);
+ if (!wpa_s->scan_ongoing) {
+ wpa_s->scan_req = 2;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ }
+ else
+ wpa_printf(MSG_DEBUG, "Ongoing Scan action...");
} else if (os_strcmp(buf, "SCAN_RESULTS") == 0) {
reply_len = wpa_supplicant_ctrl_iface_scan_results(
wpa_s, reply, reply_size);
diff --git a/driver_wext.c b/driver_wext.c
index a2e4578..c512586 100644
--- a/driver_wext.c
+++ b/driver_wext.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include <sys/ioctl.h>
#include <net/if_arp.h>
+#include <net/if.h>
#include "wireless_copy.h"
#include "common.h"
@@ -31,6 +32,9 @@
#include "priv_netlink.h"
#include "driver_wext.h"
#include "wpa.h"
+#include "wpa_ctrl.h"
+#include "wpa_supplicant_i.h"
+#include "config_ssid.h"
#ifdef CONFIG_CLIENT_MLME
#include <netpacket/packet.h>
@@ -401,6 +405,12 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom)
}
wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
#endif /* CONFIG_PEERKEY */
+#ifdef ANDROID
+ } else if (os_strncmp(custom, "STOP", 4) == 0) {
+ wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+ } else if (os_strncmp(custom, "START", 5) == 0) {
+ wpa_msg(ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+#endif /* ANDROID */
}
}
@@ -1001,6 +1011,13 @@ static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
{
int flags;
+ if (wpa_driver_wext_get_ifflags(drv, &flags) != 0 ||
+ wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
+ printf("Could not set interface '%s' UP\n", drv->ifname);
+ }
+#ifdef ANDROID
+ os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
+#endif
/*
* Make sure that the driver does not have any obsolete PMKID entries.
*/
@@ -1010,11 +1027,6 @@ static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
printf("Could not configure driver to use managed mode\n");
}
- if (wpa_driver_wext_get_ifflags(drv, &flags) != 0 ||
- wpa_driver_wext_set_ifflags(drv, flags | IFF_UP) != 0) {
- printf("Could not set interface '%s' UP\n", drv->ifname);
- }
-
wpa_driver_wext_get_range(drv);
drv->ifindex = if_nametoindex(drv->ifname);
@@ -1226,7 +1238,13 @@ int wpa_driver_wext_get_scan_results(void *priv,
size_t len, clen, res_buf_len;
os_memset(results, 0, max_size * sizeof(struct wpa_scan_result));
-
+#ifdef ANDROID
+ /* To make sure correctly parse scan results which is impacted by wext
+ * version, first check range->we_version, if it is default value (0),
+ * update again here */
+ if (drv->we_version_compiled == 0)
+ wpa_driver_wext_get_range(drv);
+#endif
res_buf_len = IW_SCAN_MAX_DATA;
for (;;) {
res_buf = os_malloc(res_buf_len);
@@ -1912,10 +1930,16 @@ wpa_driver_wext_associate(void *priv,
struct wpa_driver_wext_data *drv = priv;
int ret = 0;
int allow_unencrypted_eapol;
- int value;
+ int value, flags;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
+ if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
+ if (!(flags & IFF_UP)) {
+ wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
+ }
+ }
+
/*
* If the driver did not support SIOCSIWAUTH, fallback to
* SIOCSIWENCODE here.
@@ -2473,6 +2497,68 @@ int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv)
return drv->we_version_compiled;
}
+#ifdef ANDROID
+static char *wpa_driver_get_country_code(int channels)
+{
+ char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */
+
+ if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI)
+ country = "EU";
+ else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1)
+ country = "JP";
+ return country;
+}
+
+static int wpa_driver_priv_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
+{
+ struct wpa_driver_wext_data *drv = priv;
+ struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
+ struct iwreq iwr;
+ int ret = 0;
+
+ wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
+
+ if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
+ os_strncpy(cmd, "RSSI", MAX_DRV_CMD_SIZE);
+ }
+ else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) {
+ int no_of_chan;
+
+ no_of_chan = atoi(cmd + 13);
+ os_snprintf(cmd, MAX_DRV_CMD_SIZE, "COUNTRY %s",
+ wpa_driver_get_country_code(no_of_chan));
+ }
+ os_memset(&iwr, 0, sizeof(iwr));
+ os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+ os_memcpy(buf, cmd, strlen(cmd) + 1);
+ iwr.u.data.pointer = buf;
+ iwr.u.data.length = buf_len;
+
+ if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
+ perror("ioctl[SIOCSIWPRIV]");
+ }
+
+ if (ret < 0)
+ wpa_printf(MSG_ERROR, "%s failed", __func__);
+ else {
+ ret = 0;
+ if ((os_strcasecmp(cmd, "RSSI") == 0) ||
+ (os_strcasecmp(cmd, "LINKSPEED") == 0) ||
+ (os_strcasecmp(cmd, "MACADDR") == 0)) {
+ ret = strlen(buf);
+ }
+/* else if (os_strcasecmp(cmd, "START") == 0) {
+ os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
+ wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
+ }
+ else if (os_strcasecmp(cmd, "STOP") == 0) {
+ wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
+ }*/
+ wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
+ }
+ return ret;
+}
+#endif
const struct wpa_driver_ops wpa_driver_wext_ops = {
.name = "wext",
@@ -2506,4 +2592,7 @@ const struct wpa_driver_ops wpa_driver_wext_ops = {
.mlme_add_sta = wpa_driver_wext_mlme_add_sta,
.mlme_remove_sta = wpa_driver_wext_mlme_remove_sta,
#endif /* CONFIG_CLIENT_MLME */
+#ifdef ANDROID
+ .driver_cmd = wpa_driver_priv_driver_cmd,
+#endif
};
diff --git a/driver_wext.h b/driver_wext.h
index d65a544..4804ae5 100644
--- a/driver_wext.h
+++ b/driver_wext.h
@@ -45,4 +45,13 @@ void wpa_driver_wext_deinit(void *priv);
int wpa_driver_wext_set_operstate(void *priv, int state);
int wpa_driver_wext_get_version(struct wpa_driver_wext_data *drv);
+#ifdef ANDROID
+#define WEXT_NUMBER_SCAN_CHANNELS_FCC 11
+#define WEXT_NUMBER_SCAN_CHANNELS_ETSI 13
+#define WEXT_NUMBER_SCAN_CHANNELS_MKK1 14
+
+#define WPA_DRIVER_WEXT_WAIT_US 400000
+#define MAX_DRV_CMD_SIZE 248
+#endif
+
#endif /* DRIVER_WEXT_H */
diff --git a/eap_tls_common.c b/eap_tls_common.c
index de17886..d91c6cb 100644
--- a/eap_tls_common.c
+++ b/eap_tls_common.c
@@ -23,152 +23,6 @@
#include "tls.h"
#include "config.h"
-#ifdef ANDROID
-#include <openssl/pem.h>
-#include <openssl/x509v3.h>
-#include <keystore_get.h>
-
-#define PEM_CERT_KEYWORD "CERTIFICATE"
-#define PEM_PRIVATEKEY_KEYWORD "PRIVATE KEY"
-
-struct temporal_blobs {
- struct temporal_blobs *next;
- struct wpa_config_blob *blob;
-};
-
-static struct temporal_blobs *ks_blobs = NULL;
-
-/**
- * The blob data can not be inserted into config->blobs structure, since the
- * protected cert/key may be rewritten to config file. We have to maintain the
- * keystore-only blobs.
- */
-static int add_temporal_blob(struct wpa_config_blob *blob)
-{
- struct temporal_blobs *p;
-
- p = (struct temporal_blobs*) malloc(sizeof(struct temporal_blobs));
- if (p == NULL) {
- return -1;
- }
- p->next = ks_blobs;
- p->blob = blob;
- ks_blobs = p;
- return 0;
-}
-
-static void free_temporal_blobs()
-{
- struct temporal_blobs *p = ks_blobs;
-
- while (p != NULL) {
- struct temporal_blobs *q = p;
- p = p->next;
- if (q->blob) free(q->blob);
- free(q);
- }
- ks_blobs = NULL;
-}
-
-typedef enum {
- PEM_CERTIFICATE,
- PEM_PRIVATE_KEY,
- DER_FORMAT,
- UNKNOWN_CERT_TYPE
-} CERT_TYPE;
-
-/**
- * Tell the encoding format and type of the certificate/key by examining if
- * there is "CERTIFICATE" or "PRIVATE KEY" in the blob. If not, at least we
- * can test if the first byte is '0'.
- */
-static CERT_TYPE get_blob_type(struct wpa_config_blob *blob)
-{
- CERT_TYPE type = UNKNOWN_CERT_TYPE;
- unsigned char p = blob->data[blob->len - 1];
-
- blob->data[blob->len - 1] = 0;
- if (strstr(blob->data, PEM_CERT_KEYWORD) != NULL) {
- type = PEM_CERTIFICATE;
- } else if (strstr(blob->data, PEM_PRIVATEKEY_KEYWORD) != NULL) {
- type = PEM_PRIVATE_KEY;
- } else if (blob->data[0] == '0') {
- type = DER_FORMAT;
- }
- blob->data[blob->len - 1] = p;
- return type;
-}
-
-/**
- * convert_PEM_to_DER() provides the converion from PEM format to DER one, since
- * original certificate handling does not accept the PEM format for blob data.
- * Therefore, we need to convert the data to DER format if it is PEM-format.
- */
-static void convert_PEM_to_DER(struct wpa_config_blob *blob)
-{
- X509 *cert = NULL;
- EVP_PKEY *pkey = NULL;
- BIO *bp = NULL;
- unsigned char *buf = NULL;
- int len = 0;
- CERT_TYPE type;
-
- if (blob->len < sizeof(PEM_CERT_KEYWORD)) {
- return;
- }
-
- if (((type = get_blob_type(blob)) != PEM_CERTIFICATE) &&
- (type != PEM_PRIVATE_KEY)) {
- return;
- }
-
- bp = BIO_new(BIO_s_mem());
- if (!bp) goto err;
- if (!BIO_write(bp, blob->data, blob->len)) goto err;
- if (type == PEM_CERTIFICATE) {
- if ((cert = PEM_read_bio_X509(bp, NULL, NULL, NULL)) != NULL) {
- len = i2d_X509(cert, &buf);
- }
- } else {
- if ((pkey = PEM_read_bio_PrivateKey(bp, NULL, NULL, NULL)) != NULL) {
- len = i2d_PrivateKey(pkey, &buf);
- }
- }
-
-err:
- if (bp) BIO_free(bp);
- if (cert) X509_free(cert);
- if (pkey) EVP_PKEY_free(pkey);
- if (buf) {
- free(blob->data);
- blob->data = buf;
- blob->len = len;
- }
-}
-
-struct wpa_config_blob *get_blob_from_keystore(const char *name)
-{
- int len;
- char *buf = keystore_get((char*)name, &len);
- struct wpa_config_blob *blob = NULL;
-
- if (buf) {
- if ((blob = os_zalloc(sizeof(*blob))) != NULL) {
- blob->name = os_strdup(name);
- blob->data = (unsigned char*)buf;
- blob->len = len;
- } else {
- free(buf);
- }
- }
- if (blob) {
- convert_PEM_to_DER(blob);
- add_temporal_blob(blob);
- }
- return blob;
-}
-#endif
-
static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
const u8 **data, size_t *data_len)
{
@@ -178,11 +32,6 @@ static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
return 0;
blob = eap_get_config_blob(sm, *name + 7);
-#ifdef ANDROID
- if(blob == NULL) {
- blob = get_blob_from_keystore(*name + 7);
- }
-#endif
if (blob == NULL) {
wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not "
"found", __func__, *name + 7);
@@ -346,9 +195,6 @@ int eap_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
ret = 0;
done:
-#ifdef ANDROID
- free_temporal_blobs();
-#endif
return ret;
}
diff --git a/events.c b/events.c
index 1512097..bb5be64 100644
--- a/events.c
+++ b/events.c
@@ -505,6 +505,7 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
struct wpa_ssid *ssid = NULL;
struct wpa_scan_result *results;
+ wpa_s->scan_ongoing = 0;
if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
if (wpa_s->conf->ap_scan == 2)
return;
@@ -515,7 +516,7 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
}
wpa_supplicant_dbus_notify_scan_results(wpa_s);
- wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS " Ready"); /* Dm: */
+ wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS " Ready");
if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
return;
@@ -660,9 +661,9 @@ static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
p += len;
}
- if (!wpa_found && data->assoc_info.beacon_ies)
+ if (!wpa_found)
wpa_sm_set_ap_wpa_ie(wpa_s->wpa, NULL, 0);
- if (!rsn_found && data->assoc_info.beacon_ies)
+ if (!rsn_found)
wpa_sm_set_ap_rsn_ie(wpa_s->wpa, NULL, 0);
}
diff --git a/if_index.c b/if_index.c
deleted file mode 100644
index 8f87d5f..0000000
--- a/if_index.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* if_index.c
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <sys/socket.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#include <linux/if.h>
-#include <linux/sockios.h>
-#include <linux/route.h>
-
-unsigned int if_nametoindex( const char *ifname )
-{
-#ifndef SIOCGIFINDEX
- return 0;
-#else
- struct ifreq ifr;
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
-
- if (fd < 0)
- return 0;
-
- strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
- ifr.ifr_ifindex = 0;
- if (ioctl (fd, SIOCGIFINDEX, &ifr) < 0) {
- return 0;
- }
- return ifr.ifr_ifindex;
-#endif
-}
diff --git a/os_unix.c b/os_unix.c
index 7e3ab4a..edb160a 100644
--- a/os_unix.c
+++ b/os_unix.c
@@ -16,6 +16,12 @@
#include "os.h"
+#ifdef ANDROID
+#include <linux/capability.h>
+#include <linux/prctl.h>
+#include <private/android_filesystem_config.h>
+#endif
+
void os_sleep(os_time_t sec, os_time_t usec)
{
if (sec)
@@ -171,6 +177,28 @@ char * os_rel2abs_path(const char *rel_path)
int os_program_init(void)
{
+#ifdef ANDROID
+ /* We ignore errors here since errors are normal if we
+ * are already running as non-root.
+ */
+ gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE };
+ setgroups(sizeof(groups)/sizeof(groups[0]), groups);
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ setgid(AID_WIFI);
+ setuid(AID_WIFI);
+
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+ cap.effective = cap.permitted =
+ (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
+ cap.inheritable = 0;
+ capset(&header, &cap);
+#endif
+
return 0;
}
diff --git a/tls_openssl.c b/tls_openssl.c
index cb6b974..61fa747 100644
--- a/tls_openssl.c
+++ b/tls_openssl.c
@@ -37,13 +37,29 @@
#define OPENSSL_d2i_TYPE unsigned char **
#endif
+#ifdef ANDROID
+#include <openssl/pem.h>
+#include "keystore_get.h"
+
+static BIO *BIO_from_keystore(const char *key)
+{
+ BIO *bio = NULL;
+ char value[KEYSTORE_MESSAGE_SIZE];
+ int length = keystore_get(key, value);
+ if (length != -1 && (bio = BIO_new(BIO_s_mem())) != NULL) {
+ BIO_write(bio, value, length);
+ }
+ return bio;
+}
+#endif
+
static int tls_openssl_ref_count = 0;
struct tls_connection {
SSL *ssl;
BIO *ssl_in, *ssl_out;
#ifndef OPENSSL_NO_ENGINE
- ENGINE *engine; /* functional reference to the engine */
+ ENGINE *engine; /* functional reference to the engine */
EVP_PKEY *private_key; /* the private key if using engine */
#endif /* OPENSSL_NO_ENGINE */
char *subject_match, *altsubject_match;
@@ -571,7 +587,7 @@ static void ssl_info_cb(const SSL *ssl, int where, int ret)
* @pre: an array of commands and values that load an engine initialized
* in the engine specific function
* @post: an array of commands and values that initialize an already loaded
- * engine (or %NULL if not required)
+ * engine (or %NULL if not required)
* @id: the engine id of the engine to load (only required if post is not %NULL
*
* This function is a generic function that loads any openssl engine.
@@ -1092,7 +1108,6 @@ static int tls_load_ca_der(void *_ssl_ctx, const char *ca_cert)
}
#endif /* OPENSSL_NO_STDIO */
-
static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
const char *ca_cert, const u8 *ca_cert_blob,
size_t ca_cert_blob_len, const char *ca_path)
@@ -1143,6 +1158,33 @@ static int tls_connection_ca_cert(void *_ssl_ctx, struct tls_connection *conn,
return 0;
}
+#ifdef ANDROID
+ if (ca_cert && strncmp("keystore://", ca_cert, 11) == 0) {
+ BIO *bio = BIO_from_keystore(&ca_cert[11]);
+ STACK_OF(X509_INFO) *stack = NULL;
+ int i;
+ if (bio) {
+ stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+ if (!stack) {
+ return -1;
+ }
+ for (i = 0; i < sk_X509_INFO_num(stack); ++i) {
+ X509_INFO *info = sk_X509_INFO_value(stack, i);
+ if (info->x509) {
+ X509_STORE_add_cert(ssl_ctx->cert_store, info->x509);
+ }
+ if (info->crl) {
+ X509_STORE_add_crl(ssl_ctx->cert_store, info->crl);
+ }
+ }
+ sk_X509_INFO_pop_free(stack, X509_INFO_free);
+ SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, tls_verify_cb);
+ return 0;
+ }
+#endif
+
#ifdef CONFIG_NATIVE_WINDOWS
if (ca_cert && tls_cryptoapi_ca_cert(ssl_ctx, conn->ssl, ca_cert) ==
0) {
@@ -1298,6 +1340,25 @@ static int tls_connection_client_cert(struct tls_connection *conn,
if (client_cert == NULL)
return -1;
+#ifdef ANDROID
+ if (strncmp("keystore://", client_cert, 11) == 0) {
+ BIO *bio = BIO_from_keystore(&client_cert[11]);
+ X509 *x509 = NULL;
+ int ret = -1;
+ if (bio) {
+ x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+ if (x509) {
+ if (SSL_use_certificate(conn->ssl, x509) == 1) {
+ ret = 0;
+ }
+ X509_free(x509);
+ }
+ return ret;
+ }
+#endif
+
#ifndef OPENSSL_NO_STDIO
if (SSL_use_certificate_file(conn->ssl, client_cert,
SSL_FILETYPE_ASN1) == 1) {
@@ -1587,6 +1648,23 @@ static int tls_connection_private_key(void *_ssl_ctx,
break;
}
+#ifdef ANDROID
+ if (!ok && private_key && strncmp("keystore://", private_key, 11) == 0) {
+ BIO *bio = BIO_from_keystore(&private_key[11]);
+ EVP_PKEY *pkey = NULL;
+ if (bio) {
+ pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+ if (pkey) {
+ if (SSL_use_PrivateKey(conn->ssl, pkey) == 1) {
+ ok = 1;
+ }
+ EVP_PKEY_free(pkey);
+ }
+ }
+#endif
+
while (!ok && private_key) {
#ifndef OPENSSL_NO_STDIO
if (SSL_use_PrivateKey_file(conn->ssl, private_key,
diff --git a/wireless_copy.h b/wireless_copy.h
index ac81f69..db1a5f3 100644
--- a/wireless_copy.h
+++ b/wireless_copy.h
@@ -1,17 +1,10 @@
-/* This is based on Linux Wireless Extensions header file from WIRELESS_EXT 18.
- * I have just removed kernel related headers and added some typedefs etc. to
- * make this easier to include into user space programs.
- * Jouni Malinen, 2005-03-12.
- */
-
-
/*
* This file define a set of standard wireless extensions
*
- * Version : 19 18.3.05
+ * Version : 22 16.3.07
*
* Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved.
+ * Copyright (c) 1997-2007 Jean Tourrilhes, All Rights Reserved.
*/
#ifndef _LINUX_WIRELESS_H
@@ -76,27 +69,9 @@
/***************************** INCLUDES *****************************/
- /* jkm - replaced linux headers with C library headers, added typedefs */
-#if 0
-/* To minimise problems in user space, I might remove those headers
- * at some point. Jean II */
-#include <linux/types.h> /* for "caddr_t" et al */
+#include <linux/types.h> /* for __u* and __s* typedefs */
#include <linux/socket.h> /* for "struct sockaddr" et al */
#include <linux/if.h> /* for IFNAMSIZ and co... */
-#else
-#include <sys/types.h>
-#include <net/if.h>
-#if !defined(HAVE_ANDROID_OS)
-typedef __uint32_t __u32;
-typedef __int32_t __s32;
-typedef __uint16_t __u16;
-typedef __int16_t __s16;
-typedef __uint8_t __u8;
-#endif
-#ifndef __user
-#define __user
-#endif /* __user */
-#endif
/***************************** VERSION *****************************/
/*
@@ -105,7 +80,7 @@ typedef __uint8_t __u8;
* (there is some stuff that will be added in the future...)
* I just plan to increment with each new version.
*/
-#define WIRELESS_EXT 19
+#define WIRELESS_EXT 22
/*
* Changes :
@@ -229,6 +204,22 @@ typedef __uint8_t __u8;
* - Add IW_QUAL_ALL_UPDATED and IW_QUAL_ALL_INVALID macros
* - Add explicit flag to tell stats are in dBm : IW_QUAL_DBM
* - Add IW_IOCTL_IDX() and IW_EVENT_IDX() macros
+ *
+ * V19 to V20
+ * ----------
+ * - RtNetlink requests support (SET/GET)
+ *
+ * V20 to V21
+ * ----------
+ * - Remove (struct net_device *)->get_wireless_stats()
+ * - Change length in ESSID and NICK to strlen() instead of strlen()+1
+ * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers
+ * - Power/Retry relative values no longer * 100000
+ * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI
+ *
+ * V21 to V22
+ * ----------
+ * - Prevent leaking of kernel space in stream on 64 bits.
*/
/**************************** CONSTANTS ****************************/
@@ -342,7 +333,7 @@ typedef __uint8_t __u8;
* separate range because of collisions with other tools such as
* 'mii-tool'.
* We now have 32 commands, so a bit more space ;-).
- * Also, all 'odd' commands are only usable by root and don't return the
+ * Also, all 'even' commands are only usable by root and don't return the
* content of ifr/iwr to user (but you are not obliged to use the set/get
* convention, just use every other two command). More details in iwpriv.c.
* And I repeat : you are not forced to use them with iwpriv, but you
@@ -356,7 +347,7 @@ typedef __uint8_t __u8;
#define SIOCIWLAST SIOCIWLASTPRIV /* 0x8BFF */
#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
-/* Even : get (world access), odd : set (root access) */
+/* Odd : get (world access), even : set (root access) */
#define IW_IS_SET(cmd) (!((cmd) & 0x1))
#define IW_IS_GET(cmd) ((cmd) & 0x1)
@@ -459,6 +450,7 @@ typedef __uint8_t __u8;
#define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
#define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
+#define IW_MODE_MESH 7 /* Mesh (IEEE 802.11s) network */
/* Statistics flags (bitmask in updated) */
#define IW_QUAL_QUAL_UPDATED 0x01 /* Value was updated since last read */
@@ -469,6 +461,7 @@ typedef __uint8_t __u8;
#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */
#define IW_QUAL_LEVEL_INVALID 0x20
#define IW_QUAL_NOISE_INVALID 0x40
+#define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */
#define IW_QUAL_ALL_INVALID 0x70
/* Frequency flags */
@@ -521,10 +514,12 @@ typedef __uint8_t __u8;
#define IW_RETRY_TYPE 0xF000 /* Type of parameter */
#define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/
#define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */
-#define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */
+#define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */
#define IW_RETRY_MIN 0x0001 /* Value is a minimum */
#define IW_RETRY_MAX 0x0002 /* Value is a maximum */
#define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
+#define IW_RETRY_SHORT 0x0010 /* Value is for short packets */
+#define IW_RETRY_LONG 0x0020 /* Value is for long packets */
/* Scanning request flags */
#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
@@ -540,7 +535,17 @@ typedef __uint8_t __u8;
#define IW_SCAN_TYPE_ACTIVE 0
#define IW_SCAN_TYPE_PASSIVE 1
/* Maximum size of returned data */
-#define IW_SCAN_MAX_DATA 4096 /* In bytes */
+#define IW_SCAN_MAX_DATA 8192 /* In bytes */
+
+/* Scan capability flags - in (struct iw_range *)->scan_capa */
+#define IW_SCAN_CAPA_NONE 0x00
+#define IW_SCAN_CAPA_ESSID 0x01
+#define IW_SCAN_CAPA_BSSID 0x02
+#define IW_SCAN_CAPA_CHANNEL 0x04
+#define IW_SCAN_CAPA_MODE 0x08
+#define IW_SCAN_CAPA_RATE 0x10
+#define IW_SCAN_CAPA_TYPE 0x20
+#define IW_SCAN_CAPA_TIME 0x40
/* Max number of char in custom event - use multiple of them if needed */
#define IW_CUSTOM_MAX 256 /* In bytes */
@@ -551,6 +556,8 @@ typedef __uint8_t __u8;
/* MLME requests (SIOCSIWMLME / struct iw_mlme) */
#define IW_MLME_DEAUTH 0
#define IW_MLME_DISASSOC 1
+#define IW_MLME_AUTH 2
+#define IW_MLME_ASSOC 3
/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */
#define IW_AUTH_INDEX 0x0FFF
@@ -604,6 +611,7 @@ typedef __uint8_t __u8;
#define IW_ENCODE_ALG_WEP 1
#define IW_ENCODE_ALG_TKIP 2
#define IW_ENCODE_ALG_CCMP 3
+#define IW_ENCODE_ALG_PMK 4
/* struct iw_encode_ext ->ext_flags */
#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
@@ -623,6 +631,7 @@ typedef __uint8_t __u8;
#define IW_ENC_CAPA_WPA2 0x00000002
#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
+#define IW_ENC_CAPA_4WAY_HANDSHAKE 0x00000010
/* Event capability macros - in (struct iw_range *)->event_capa
* Because we have more than 32 possible events, we use an array of
@@ -668,6 +677,19 @@ struct iw_point
__u16 flags; /* Optional params */
};
+#ifdef __KERNEL__
+#ifdef CONFIG_COMPAT
+
+#include <linux/compat.h>
+
+struct compat_iw_point {
+ compat_caddr_t pointer;
+ __u16 length;
+ __u16 flags;
+};
+#endif
+#endif
+
/*
* A frequency
* For numbers lower than 10^9, we encode the number in 'm' and
@@ -962,6 +984,9 @@ struct iw_range
__u16 old_num_channels;
__u8 old_num_frequency;
+ /* Scan capabilities */
+ __u8 scan_capa; /* IW_SCAN_CAPA_* bit field */
+
/* Wireless event capability bitmasks */
__u32 event_capa[6];
@@ -1038,7 +1063,7 @@ struct iw_range
/* Note : this frequency list doesn't need to fit channel numbers,
* because each entry contain its channel index */
- __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
+ __u32 enc_capa; /* IW_ENC_CAPA_* bit field */
};
/*
@@ -1065,7 +1090,7 @@ struct iw_priv_args
*/
struct iw_event
{
- __u16 len; /* Real lenght of this stuff */
+ __u16 len; /* Real length of this stuff */
__u16 cmd; /* Wireless IOCTL */
union iwreq_data u; /* IOCTL fixed payload */
};
@@ -1088,4 +1113,30 @@ struct iw_event
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
IW_EV_POINT_OFF)
+#ifdef __KERNEL__
+#ifdef CONFIG_COMPAT
+struct __compat_iw_event {
+ __u16 len; /* Real length of this stuff */
+ __u16 cmd; /* Wireless IOCTL */
+ compat_caddr_t pointer;
+};
+#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
+#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
+#define IW_EV_COMPAT_POINT_LEN \
+ (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
+ IW_EV_COMPAT_POINT_OFF)
+#endif
+#endif
+
+/* Size of the Event prefix when packed in stream */
+#define IW_EV_LCP_PK_LEN (4)
+/* Size of the various events when packed in stream */
+#define IW_EV_CHAR_PK_LEN (IW_EV_LCP_PK_LEN + IFNAMSIZ)
+#define IW_EV_UINT_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(__u32))
+#define IW_EV_FREQ_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_freq))
+#define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality))
+#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4)
+
#endif /* _LINUX_WIRELESS_H */
diff --git a/wpa_ctrl.c b/wpa_ctrl.c
index 0d5dd28..32866cf 100644
--- a/wpa_ctrl.c
+++ b/wpa_ctrl.c
@@ -153,7 +153,7 @@ void wpa_ctrl_close(struct wpa_ctrl *ctrl)
* event of crashes that prevented them from being removed as part
* of the normal orderly shutdown.
*/
-void wpa_ctrl_cleanup()
+void wpa_ctrl_cleanup(void)
{
DIR *dir;
struct dirent entry;
@@ -292,7 +292,11 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
os_free(cmd_buf);
for (;;) {
+#ifdef ANDROID
+ tv.tv_sec = 10;
+#else
tv.tv_sec = 2;
+#endif
tv.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(ctrl->s, &rfds);
diff --git a/wpa_ctrl.h b/wpa_ctrl.h
index a81dec9..1171712 100644
--- a/wpa_ctrl.h
+++ b/wpa_ctrl.h
@@ -187,7 +187,7 @@ int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl);
* event of crashes that prevented them from being removed as part
* of the normal orderly shutdown.
*/
-void wpa_ctrl_cleanup();
+void wpa_ctrl_cleanup(void);
#endif /* ANDROID */
#ifdef CONFIG_CTRL_IFACE_UDP
diff --git a/wpa_supplicant.c b/wpa_supplicant.c
index 706a010..aabef73 100644
--- a/wpa_supplicant.c
+++ b/wpa_supplicant.c
@@ -492,6 +492,7 @@ void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
*/
void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
{
+#ifndef ANDROID
/* If there's at least one network that should be specifically scanned
* then don't cancel the scan and reschedule. Some drivers do
* background scanning which generates frequent scan results, and that
@@ -513,6 +514,7 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
return;
}
}
+#endif
wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
sec, usec);
@@ -954,7 +956,11 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
wpa_supplicant_clear_status(wpa_s);
wpa_s->reassociate = 1;
+#ifdef ANDROID
+ wpa_supplicant_req_scan(wpa_s, 2, 0);
+#else
wpa_supplicant_req_scan(wpa_s, 0, 0);
+#endif
wpa_msg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
return 0;
}
@@ -1105,6 +1111,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
wpa_supplicant_req_scan(wpa_s, 10, 0);
}
+ else
+ wpa_s->scan_ongoing = 1;
}
@@ -1385,6 +1393,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
os_memset(wpa_s->bssid, 0, ETH_ALEN);
os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
+ wpa_s->link_speed = bss->maxrate;
+ wpa_s->rssi = bss->level;
} else {
wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
diff --git a/wpa_supplicant_i.h b/wpa_supplicant_i.h
index 775462e..9989fe7 100644
--- a/wpa_supplicant_i.h
+++ b/wpa_supplicant_i.h
@@ -342,6 +342,9 @@ struct wpa_supplicant {
struct wpa_client_mlme mlme;
int use_client_mlme;
+ int scan_ongoing; /* scan ongoing or not */
+ int link_speed; /* current link speed */
+ int rssi; /* current signal level */
#ifdef ANDROID
int scan_interval; /* time between scans when no APs available */
#endif