* EAP peer method: EAP-FAST PAC file processing
* Copyright (c) 2004-2006, 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
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
static const char * eap_fast_parse_pac_type(struct eap_fast_pac *pac,
char *pos)
{
+ if (!pos)
+ return "Cannot parse pac type";
pac->pac_type = atoi(pos);
if (pac->pac_type != PAC_TYPE_TUNNEL_PAC &&
pac->pac_type != PAC_TYPE_USER_AUTHORIZATION &&
if (eap_fast_init_pac_data(sm, pac_file, &rc) < 0)
return 0;
- if (eap_fast_read_line(&rc, &pos) < 0 ||
- os_strcmp(pac_file_hdr, rc.buf) != 0)
+ if (eap_fast_read_line(&rc, &pos) < 0) {
+ /* empty file - assume it is fine to overwrite */
+ eap_fast_deinit_pac_data(&rc);
+ return 0;
+ }
+ if (os_strcmp(pac_file_hdr, rc.buf) != 0)
err = "Unrecognized header line";
while (!err && eap_fast_read_line(&rc, &pos) == 0) {
*buf = NULL;
return;
}
+ *pos = nbuf + (*pos - *buf);
*buf = nbuf;
*buf_len += need;
}
end = *buf + *buf_len;
ret = os_snprintf(*pos, end - *pos, "%s=", field);
- if (ret < 0 || ret >= end - *pos)
+ if (os_snprintf_error(end - *pos, ret))
return;
*pos += ret;
*pos += wpa_snprintf_hex(*pos, end - *pos, data, len);
ret = os_snprintf(*pos, end - *pos, "\n");
- if (ret < 0 || ret >= end - *pos)
+ if (os_snprintf_error(end - *pos, ret))
return;
*pos += ret;
if (txt) {
ret = os_snprintf(*pos, end - *pos, "%s-txt=", field);
- if (ret < 0 || ret >= end - *pos)
+ if (os_snprintf_error(end - *pos, ret))
return;
*pos += ret;
for (i = 0; i < len; i++) {
ret = os_snprintf(*pos, end - *pos, "%c", data[i]);
- if (ret < 0 || ret >= end - *pos)
+ if (os_snprintf_error(end - *pos, ret))
return;
*pos += ret;
}
ret = os_snprintf(*pos, end - *pos, "\n");
- if (ret < 0 || ret >= end - *pos)
+ if (os_snprintf_error(end - *pos, ret))
return;
*pos += ret;
}
ret = os_snprintf(*pos, *buf + *buf_len - *pos,
"START\nPAC-Type=%d\n", pac->pac_type);
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ if (os_snprintf_error(*buf + *buf_len - *pos, ret))
return -1;
*pos += ret;
return -1;
}
ret = os_snprintf(*pos, *buf + *buf_len - *pos, "END\n");
- if (ret < 0 || ret >= *buf + *buf_len - *pos)
+ if (os_snprintf_error(*buf + *buf_len - *pos, ret))
return -1;
*pos += ret;
return -1;
ret = os_snprintf(pos, buf + buf_len - pos, "%s\n", pac_file_hdr);
- if (ret < 0 || ret >= buf + buf_len - pos) {
+ if (os_snprintf_error(buf + buf_len - pos, ret)) {
os_free(buf);
return -1;
}
pos += 2;
len = WPA_GET_BE16(pos);
pos += 2;
- if (pos + len > end)
+ if (len > (unsigned int) (end - pos))
break;
if (type == PAC_TYPE_A_ID) {
pos = buf + 6;
end = buf + len;
while (pos < end) {
- if (end - pos < 2 + 32 + 2 + 2)
+ u16 val;
+
+ if (end - pos < 2 + EAP_FAST_PAC_KEY_LEN + 2 + 2)
goto parse_fail;
pac = os_zalloc(sizeof(*pac));
pos += 2;
os_memcpy(pac->pac_key, pos, EAP_FAST_PAC_KEY_LEN);
pos += EAP_FAST_PAC_KEY_LEN;
- pac->pac_opaque_len = WPA_GET_BE16(pos);
+ val = WPA_GET_BE16(pos);
pos += 2;
- if (pos + pac->pac_opaque_len + 2 > end)
+ if (val > end - pos)
goto parse_fail;
+ pac->pac_opaque_len = val;
pac->pac_opaque = os_malloc(pac->pac_opaque_len);
if (pac->pac_opaque == NULL)
goto parse_fail;
os_memcpy(pac->pac_opaque, pos, pac->pac_opaque_len);
pos += pac->pac_opaque_len;
- pac->pac_info_len = WPA_GET_BE16(pos);
+ if (2 > end - pos)
+ goto parse_fail;
+ val = WPA_GET_BE16(pos);
pos += 2;
- if (pos + pac->pac_info_len > end)
+ if (val > end - pos)
goto parse_fail;
+ pac->pac_info_len = val;
pac->pac_info = os_malloc(pac->pac_info_len);
if (pac->pac_info == NULL)
goto parse_fail;