diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2009-11-15 12:06:17 -0800 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2009-11-15 12:06:17 -0800 |
commit | 107783f4e1b1bdf796220b49680e97fc21a8fa7f (patch) | |
tree | 3afdf3d57fcdba5d750b6046d30de8857fa6c3dd | |
parent | f7cdf529d818433b334ed93da380844d6b10ad96 (diff) | |
parent | b3fb13ce35baebffc4608e6e52f2a71446973b18 (diff) | |
download | wpa_supplicant-107783f4e1b1bdf796220b49680e97fc21a8fa7f.tar.gz |
merge from eclair
-rw-r--r-- | Android.mk | 10 | ||||
-rw-r--r-- | common.c | 3 | ||||
-rw-r--r-- | config.c | 42 | ||||
-rw-r--r-- | ctrl_iface.c | 13 | ||||
-rw-r--r-- | driver_wext.c | 103 | ||||
-rw-r--r-- | driver_wext.h | 9 | ||||
-rw-r--r-- | eap_tls_common.c | 154 | ||||
-rw-r--r-- | events.c | 7 | ||||
-rw-r--r-- | if_index.c | 50 | ||||
-rw-r--r-- | os_unix.c | 28 | ||||
-rw-r--r-- | tls_openssl.c | 84 | ||||
-rw-r--r-- | wireless_copy.h | 121 | ||||
-rw-r--r-- | wpa_ctrl.c | 6 | ||||
-rw-r--r-- | wpa_ctrl.h | 2 | ||||
-rw-r--r-- | wpa_supplicant.c | 10 | ||||
-rw-r--r-- | wpa_supplicant_i.h | 3 |
16 files changed, 387 insertions, 258 deletions
@@ -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) @@ -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; } @@ -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; } @@ -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 -} @@ -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 */ @@ -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); @@ -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 |