aboutsummaryrefslogtreecommitdiffstats
path: root/src/radius
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-01-24 16:10:04 -0800
committerDmitry Shmidt <dimitrysh@google.com>2012-01-24 16:44:49 -0800
commit1f69aa52ea2e0a73ac502565df8c666ee49cab6a (patch)
tree8ea94735f75f461769454853da0c24cbb89cc4cc /src/radius
parentbf5edf439c90418b6f4122ff5e3925123263bda4 (diff)
downloadandroid_external_wpa_supplicant_8-1f69aa52ea2e0a73ac502565df8c666ee49cab6a.tar.gz
android_external_wpa_supplicant_8-1f69aa52ea2e0a73ac502565df8c666ee49cab6a.tar.bz2
android_external_wpa_supplicant_8-1f69aa52ea2e0a73ac502565df8c666ee49cab6a.zip
Update to new version 0.8.16 from BRCM
Sync with main tree commit b8349523e460493fa0b4de36c689595109e45e91 Author: Neeraj Kumar Garg <neerajkg@broadcom.com> Date: Tue Dec 27 23:21:45 2011 +0200 P2P: Reject p2p_group_add if forced frequency is not acceptable Change-Id: Icb4541a371b05c270e80440d7a7fdea7f33ff61e Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/radius')
-rw-r--r--src/radius/radius.c121
-rw-r--r--src/radius/radius.h4
-rw-r--r--src/radius/radius_server.c32
-rw-r--r--src/radius/radius_server.h6
4 files changed, 158 insertions, 5 deletions
diff --git a/src/radius/radius.c b/src/radius/radius.c
index 70754ef5..3ead8471 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -218,6 +218,8 @@ static struct radius_attr_type radius_attrs[] =
{ RADIUS_ATTR_TUNNEL_TYPE, "Tunnel-Type", RADIUS_ATTR_HEXDUMP },
{ RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, "Tunnel-Medium-Type",
RADIUS_ATTR_HEXDUMP },
+ { RADIUS_ATTR_TUNNEL_PASSWORD, "Tunnel-Password",
+ RADIUS_ATTR_UNDIST },
{ RADIUS_ATTR_CONNECT_INFO, "Connect-Info", RADIUS_ATTR_TEXT },
{ RADIUS_ATTR_EAP_MESSAGE, "EAP-Message", RADIUS_ATTR_UNDIST },
{ RADIUS_ATTR_MESSAGE_AUTHENTICATOR, "Message-Authenticator",
@@ -1090,8 +1092,7 @@ radius_msg_add_attr_user_password(struct radius_msg *msg,
const u8 *secret, size_t secret_len)
{
u8 buf[128];
- int padlen, i;
- size_t buf_len, pos;
+ size_t padlen, i, buf_len, pos;
const u8 *addr[2];
size_t len[2];
u8 hash[16];
@@ -1103,7 +1104,7 @@ radius_msg_add_attr_user_password(struct radius_msg *msg,
buf_len = data_len;
padlen = data_len % 16;
- if (padlen) {
+ if (padlen && data_len < sizeof(buf)) {
padlen = 16 - padlen;
os_memset(buf + data_len, 0, padlen);
buf_len += padlen;
@@ -1276,6 +1277,120 @@ int radius_msg_get_vlanid(struct radius_msg *msg)
}
+/**
+ * radius_msg_get_tunnel_password - Parse RADIUS attribute Tunnel-Password
+ * @msg: Received RADIUS message
+ * @keylen: Length of returned password
+ * @secret: RADIUS shared secret
+ * @secret_len: Length of secret
+ * @sent_msg: Sent RADIUS message
+ * Returns: pointer to password (free with os_free) or %NULL
+ */
+char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
+ const u8 *secret, size_t secret_len,
+ struct radius_msg *sent_msg)
+{
+ u8 *buf = NULL;
+ size_t buflen;
+ const u8 *salt;
+ u8 *str;
+ const u8 *addr[3];
+ size_t len[3];
+ u8 hash[16];
+ u8 *pos;
+ size_t i;
+ struct radius_attr_hdr *attr;
+ const u8 *data;
+ size_t dlen;
+ const u8 *fdata = NULL; /* points to found item */
+ size_t fdlen = -1;
+ char *ret = NULL;
+
+ /* find attribute with lowest tag and check it */
+ for (i = 0; i < msg->attr_used; i++) {
+ attr = radius_get_attr_hdr(msg, i);
+ if (attr == NULL ||
+ attr->type != RADIUS_ATTR_TUNNEL_PASSWORD) {
+ continue;
+ }
+ if (attr->length <= 5)
+ continue;
+ data = (const u8 *) (attr + 1);
+ dlen = attr->length - sizeof(*attr);
+ if (dlen <= 3 || dlen % 16 != 3)
+ continue;
+ if (fdata != NULL && fdata[0] <= data[0])
+ continue;
+
+ fdata = data;
+ fdlen = dlen;
+ }
+ if (fdata == NULL)
+ goto out;
+
+ /* alloc writable memory for decryption */
+ buf = os_malloc(fdlen);
+ if (buf == NULL)
+ goto out;
+ os_memcpy(buf, fdata, fdlen);
+ buflen = fdlen;
+
+ /* init pointers */
+ salt = buf + 1;
+ str = buf + 3;
+
+ /* decrypt blocks */
+ pos = buf + buflen - 16; /* last block */
+ while (pos >= str + 16) { /* all but the first block */
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = pos - 16;
+ len[1] = 16;
+ md5_vector(2, addr, len, hash);
+
+ for (i = 0; i < 16; i++)
+ pos[i] ^= hash[i];
+
+ pos -= 16;
+ }
+
+ /* decrypt first block */
+ if (str != pos)
+ goto out;
+ addr[0] = secret;
+ len[0] = secret_len;
+ addr[1] = sent_msg->hdr->authenticator;
+ len[1] = 16;
+ addr[2] = salt;
+ len[2] = 2;
+ md5_vector(3, addr, len, hash);
+
+ for (i = 0; i < 16; i++)
+ pos[i] ^= hash[i];
+
+ /* derive plaintext length from first subfield */
+ *keylen = (unsigned char) str[0];
+ if ((u8 *) (str + *keylen) >= (u8 *) (buf + buflen)) {
+ /* decryption error - invalid key length */
+ goto out;
+ }
+ if (*keylen == 0) {
+ /* empty password */
+ goto out;
+ }
+
+ /* copy passphrase into new buffer */
+ ret = os_malloc(*keylen);
+ if (ret)
+ os_memcpy(ret, str + 1, *keylen);
+
+out:
+ /* return new buffer */
+ os_free(buf);
+ return ret;
+}
+
+
void radius_free_class(struct radius_class_data *c)
{
size_t i;
diff --git a/src/radius/radius.h b/src/radius/radius.h
index a3cdac0d..e69a0476 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -82,6 +82,7 @@ enum { RADIUS_ATTR_USER_NAME = 1,
RADIUS_ATTR_NAS_PORT_TYPE = 61,
RADIUS_ATTR_TUNNEL_TYPE = 64,
RADIUS_ATTR_TUNNEL_MEDIUM_TYPE = 65,
+ RADIUS_ATTR_TUNNEL_PASSWORD = 69,
RADIUS_ATTR_CONNECT_INFO = 77,
RADIUS_ATTR_EAP_MESSAGE = 79,
RADIUS_ATTR_MESSAGE_AUTHENTICATOR = 80,
@@ -231,6 +232,9 @@ radius_msg_add_attr_user_password(struct radius_msg *msg,
const u8 *secret, size_t secret_len);
int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len);
int radius_msg_get_vlanid(struct radius_msg *msg);
+char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen,
+ const u8 *secret, size_t secret_len,
+ struct radius_msg *sent_msg);
static inline int radius_msg_add_attr_int32(struct radius_msg *msg, u8 type,
u32 value)
diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index 6f1c3a50..47948bc4 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -1,6 +1,6 @@
/*
* RADIUS authentication server
- * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2009, 2011, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -292,6 +292,10 @@ struct radius_server_data {
* msg_ctx - Context data for wpa_msg() calls
*/
void *msg_ctx;
+
+#ifdef CONFIG_RADIUS_TEST
+ char *dump_msk_file;
+#endif /* CONFIG_RADIUS_TEST */
};
@@ -574,6 +578,24 @@ radius_server_encapsulate_eap(struct radius_server_data *data,
if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
int len;
+#ifdef CONFIG_RADIUS_TEST
+ if (data->dump_msk_file) {
+ FILE *f;
+ char buf[2 * 64 + 1];
+ f = fopen(data->dump_msk_file, "a");
+ if (f) {
+ len = sess->eap_if->eapKeyDataLen;
+ if (len > 64)
+ len = 64;
+ len = wpa_snprintf_hex(
+ buf, sizeof(buf),
+ sess->eap_if->eapKeyData, len);
+ buf[len] = '\0';
+ fprintf(f, "%s\n", buf);
+ fclose(f);
+ }
+ }
+#endif /* CONFIG_RADIUS_TEST */
if (sess->eap_if->eapKeyDataLen > 64) {
len = 32;
} else {
@@ -1277,6 +1299,11 @@ radius_server_init(struct radius_server_conf *conf)
}
}
+#ifdef CONFIG_RADIUS_TEST
+ if (conf->dump_msk_file)
+ data->dump_msk_file = os_strdup(conf->dump_msk_file);
+#endif /* CONFIG_RADIUS_TEST */
+
data->clients = radius_server_read_clients(conf->client_file,
conf->ipv6);
if (data->clients == NULL) {
@@ -1328,6 +1355,9 @@ void radius_server_deinit(struct radius_server_data *data)
os_free(data->eap_fast_a_id);
os_free(data->eap_fast_a_id_info);
os_free(data->eap_req_id_text);
+#ifdef CONFIG_RADIUS_TEST
+ os_free(data->dump_msk_file);
+#endif /* CONFIG_RADIUS_TEST */
os_free(data);
}
diff --git a/src/radius/radius_server.h b/src/radius/radius_server.h
index 126e3144..8d6e2ab6 100644
--- a/src/radius/radius_server.h
+++ b/src/radius/radius_server.h
@@ -1,6 +1,6 @@
/*
* RADIUS authentication server
- * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2009, 2011, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -201,6 +201,10 @@ struct radius_server_conf {
* msg_ctx - Context data for wpa_msg() calls
*/
void *msg_ctx;
+
+#ifdef CONFIG_RADIUS_TEST
+ const char *dump_msk_file;
+#endif /* CONFIG_RADIUS_TEST */
};