1 /*
2  * wpa_supplicant/hostapd / common helper functions, etc.
3  * Copyright (c) 2002-2019, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 #include <limits.h>
11 
12 #include <time.h>
13 #include "common/ieee802_11_defs.h"
14 #include "common.h"
15 
16 // -Wimplicit-function-declaration
17 extern time_t mktime(struct tm*);
18 
hex2num(char c)19 static int hex2num(char c)
20 {
21 	if (c >= '0' && c <= '9')
22 		return c - '0';
23 	if (c >= 'a' && c <= 'f')
24 		return c - 'a' + 10;
25 	if (c >= 'A' && c <= 'F')
26 		return c - 'A' + 10;
27 	return -1;
28 }
29 
30 
hex2byte(const char * hex)31 int hex2byte(const char *hex)
32 {
33 	int a, b;
34 	a = hex2num(*hex++);
35 	if (a < 0)
36 		return -1;
37 	b = hex2num(*hex++);
38 	if (b < 0)
39 		return -1;
40 	return (a << 4) | b;
41 }
42 
43 
44 /**
45  * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
46  * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
47  * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
48  * Returns: Characters used (> 0) on success, -1 on failure
49  */
hwaddr_aton2(const char * txt,u8 * addr)50 int hwaddr_aton2(const char *txt, u8 *addr)
51 {
52 	int i;
53 	const char *pos = txt;
54 
55 	for (i = 0; i < 6; i++) {
56 		int a, b;
57 
58 		while (*pos == ':' || *pos == '.' || *pos == '-')
59 			pos++;
60 
61 		a = hex2num(*pos++);
62 		if (a < 0)
63 			return -1;
64 		b = hex2num(*pos++);
65 		if (b < 0)
66 			return -1;
67 		*addr++ = (a << 4) | b;
68 	}
69 
70 	return pos - txt;
71 }
72 
73 
74 /**
75  * hexstr2bin - Convert ASCII hex string into binary data
76  * @hex: ASCII hex string (e.g., "01ab")
77  * @buf: Buffer for the binary data
78  * @len: Length of the text to convert in bytes (of buf); hex will be double
79  * this size
80  * Returns: 0 on success, -1 on failure (invalid hex string)
81  */
hexstr2bin(const char * hex,u8 * buf,size_t len)82 int hexstr2bin(const char *hex, u8 *buf, size_t len)
83 {
84 	size_t i;
85 	int a;
86 	const char *ipos = hex;
87 	u8 *opos = buf;
88 
89 	for (i = 0; i < len; i++) {
90 		a = hex2byte(ipos);
91 		if (a < 0)
92 			return -1;
93 		*opos++ = a;
94 		ipos += 2;
95 	}
96 	return 0;
97 }
98 
99 
100 /**
101  * inc_byte_array - Increment arbitrary length byte array by one
102  * @counter: Pointer to byte array
103  * @len: Length of the counter in bytes
104  *
105  * This function increments the last byte of the counter by one and continues
106  * rolling over to more significant bytes if the byte was incremented from
107  * 0xff to 0x00.
108  */
inc_byte_array(u8 * counter,size_t len)109 void inc_byte_array(u8 *counter, size_t len)
110 {
111 	int pos = len - 1;
112 	while (pos >= 0) {
113 		counter[pos]++;
114 		if (counter[pos] != 0)
115 			break;
116 		pos--;
117 	}
118 }
119 
120 
buf_shift_right(u8 * buf,size_t len,size_t bits)121 void buf_shift_right(u8 *buf, size_t len, size_t bits)
122 {
123 	size_t i;
124 	for (i = len - 1; i > 0; i--)
125 		buf[i] = (buf[i - 1] << (8 - bits)) | (buf[i] >> bits);
126 	buf[0] >>= bits;
127 }
128 
129 
wpa_get_ntp_timestamp(u8 * buf)130 void wpa_get_ntp_timestamp(u8 *buf)
131 {
132 	struct os_time now;
133 	u32 sec, usec;
134 	be32 tmp;
135 
136 	/* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
137 	os_get_time(&now);
138 	sec = now.sec + 2208988800U; /* Epoch to 1900 */
139 	/* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
140 	usec = now.usec;
141 	usec = 4295 * usec - (usec >> 5) - (usec >> 9);
142 	tmp = host_to_be32(sec);
143 	os_memcpy(buf, (u8 *) &tmp, 4);
144 	tmp = host_to_be32(usec);
145 	os_memcpy(buf + 4, (u8 *) &tmp, 4);
146 }
printf_encode(char * txt,size_t maxlen,const u8 * data,size_t len)147 void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
148 {
149 	char *end = txt + maxlen;
150 	size_t i;
151 
152 	for (i = 0; i < len; i++) {
153 		if (txt + 4 >= end)
154 			break;
155 
156 		switch (data[i]) {
157 		case '\"':
158 			*txt++ = '\\';
159 			*txt++ = '\"';
160 			break;
161 		case '\\':
162 			*txt++ = '\\';
163 			*txt++ = '\\';
164 			break;
165 		case '\033':
166 			*txt++ = '\\';
167 			*txt++ = 'e';
168 			break;
169 		case '\n':
170 			*txt++ = '\\';
171 			*txt++ = 'n';
172 			break;
173 		case '\r':
174 			*txt++ = '\\';
175 			*txt++ = 'r';
176 			break;
177 		case '\t':
178 			*txt++ = '\\';
179 			*txt++ = 't';
180 			break;
181 		default:
182 			if (data[i] >= 32 && data[i] <= 126) {
183 				*txt++ = data[i];
184 			} else {
185 				txt += os_snprintf(txt, end - txt, "\\x%02x",
186 						   data[i]);
187 			}
188 			break;
189 		}
190 	}
191 
192 	*txt = '\0';
193 }
194 
195 
printf_decode(u8 * buf,size_t maxlen,const char * str)196 size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
197 {
198 	const char *pos = str;
199 	size_t len = 0;
200 	int val;
201 
202 	while (*pos) {
203 		if (len + 1 >= maxlen)
204 			break;
205 		switch (*pos) {
206 		case '\\':
207 			pos++;
208 			switch (*pos) {
209 			case '\\':
210 				buf[len++] = '\\';
211 				pos++;
212 				break;
213 			case '"':
214 				buf[len++] = '"';
215 				pos++;
216 				break;
217 			case 'n':
218 				buf[len++] = '\n';
219 				pos++;
220 				break;
221 			case 'r':
222 				buf[len++] = '\r';
223 				pos++;
224 				break;
225 			case 't':
226 				buf[len++] = '\t';
227 				pos++;
228 				break;
229 			case 'e':
230 				buf[len++] = '\033';
231 				pos++;
232 				break;
233 			case 'x':
234 				pos++;
235 				val = hex2byte(pos);
236 				if (val < 0) {
237 					val = hex2num(*pos);
238 					if (val < 0)
239 						break;
240 					buf[len++] = val;
241 					pos++;
242 				} else {
243 					buf[len++] = val;
244 					pos += 2;
245 				}
246 				break;
247 			case '0':
248 			case '1':
249 			case '2':
250 			case '3':
251 			case '4':
252 			case '5':
253 			case '6':
254 			case '7':
255 				val = *pos++ - '0';
256 				if (*pos >= '0' && *pos <= '7')
257 					val = val * 8 + (*pos++ - '0');
258 				if (*pos >= '0' && *pos <= '7')
259 					val = val * 8 + (*pos++ - '0');
260 				buf[len++] = val;
261 				break;
262 			default:
263 				break;
264 			}
265 			break;
266 		default:
267 			buf[len++] = *pos++;
268 			break;
269 		}
270 	}
271 	if (maxlen > len)
272 		buf[len] = '\0';
273 
274 	return len;
275 }
276 
277 
278 /**
279  * wpa_ssid_txt - Convert SSID to a printable string
280  * @ssid: SSID (32-octet string)
281  * @ssid_len: Length of ssid in octets
282  * Returns: Pointer to a printable string
283  *
284  * This function can be used to convert SSIDs into printable form. In most
285  * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
286  * does not limit the used character set, so anything could be used in an SSID.
287  *
288  * This function uses a static buffer, so only one call can be used at the
289  * time, i.e., this is not re-entrant and the returned buffer must be used
290  * before calling this again.
291  */
wpa_ssid_txt(const u8 * ssid,size_t ssid_len)292 const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
293 {
294 	static char ssid_txt[SSID_MAX_LEN * 4 + 1];
295 
296 	if (ssid == NULL) {
297 		ssid_txt[0] = '\0';
298 		return ssid_txt;
299 	}
300 
301 	printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
302 	return ssid_txt;
303 }
304 
305 
__hide_aliasing_typecast(void * foo)306 void * __hide_aliasing_typecast(void *foo)
307 {
308 	return foo;
309 }
310 
311 
wpa_config_parse_string(const char * value,size_t * len)312 char * wpa_config_parse_string(const char *value, size_t *len)
313 {
314 	if (*value == '"') {
315 		const char *pos;
316 		char *str;
317 		value++;
318 		pos = os_strrchr(value, '"');
319 		if (pos == NULL || pos[1] != '\0')
320 			return NULL;
321 		*len = pos - value;
322 		str = dup_binstr(value, *len);
323 		if (str == NULL)
324 			return NULL;
325 		return str;
326 	} else if (*value == 'P' && value[1] == '"') {
327 		const char *pos;
328 		char *tstr, *str;
329 		size_t tlen;
330 		value += 2;
331 		pos = os_strrchr(value, '"');
332 		if (pos == NULL || pos[1] != '\0')
333 			return NULL;
334 		tlen = pos - value;
335 		tstr = dup_binstr(value, tlen);
336 		if (tstr == NULL)
337 			return NULL;
338 
339 		str = os_malloc(tlen + 1);
340 		if (str == NULL) {
341 			os_free(tstr);
342 			return NULL;
343 		}
344 
345 		*len = printf_decode((u8 *) str, tlen + 1, tstr);
346 		os_free(tstr);
347 
348 		return str;
349 	} else {
350 		u8 *str;
351 		size_t tlen, hlen = os_strlen(value);
352 #ifndef ESP_SUPPLICANT
353 		if (hlen & 1)
354 			return NULL;
355 #else
356 		if (hlen == 5 || hlen == 13) {
357 			*len = hlen;
358 			str = (u8 *)os_malloc(*len + 1);
359 			if (str == NULL) {
360 				return NULL;
361 			}
362 			memcpy(str, value, *len);
363 			str[*len] = '\0';
364 			return (char *) str;
365 	        }
366 #endif
367 		tlen = hlen / 2;
368 		str = os_malloc(tlen + 1);
369 		if (str == NULL)
370 			return NULL;
371 		if (hexstr2bin(value, str, tlen)) {
372 			os_free(str);
373 			return NULL;
374 		}
375 		str[tlen] = '\0';
376 		*len = tlen;
377 		return (char *) str;
378 	}
379 }
380 
381 
wpa_is_hex(const u8 * data,size_t len)382 int wpa_is_hex(const u8 *data, size_t len)
383 {
384 	size_t i;
385 
386 	for (i = 0; i < len; i++) {
387 		if (data[i] < 32 || data[i] >= 127)
388 			return 1;
389 	}
390 	return 0;
391 }
392 
393 
has_ctrl_char(const u8 * data,size_t len)394 int has_ctrl_char(const u8 *data, size_t len)
395 {
396 	size_t i;
397 
398 	for (i = 0; i < len; i++) {
399 		if (data[i] < 32 || data[i] == 127)
400 			return 1;
401 	}
402 	return 0;
403 }
404 
405 
406 
wpa_merge_byte_arrays(u8 * res,size_t res_len,const u8 * src1,size_t src1_len,const u8 * src2,size_t src2_len)407 size_t wpa_merge_byte_arrays(u8 *res, size_t res_len,
408 			 const u8 *src1, size_t src1_len,
409 			 const u8 *src2, size_t src2_len)
410 {
411 	size_t len = 0;
412 
413 	os_memset(res, 0, res_len);
414 
415 	if (src1) {
416 		if (src1_len >= res_len) {
417 			os_memcpy(res, src1, res_len);
418 			return res_len;
419 		}
420 
421 		os_memcpy(res, src1, src1_len);
422 		len += src1_len;
423 	}
424 
425 	if (src2) {
426 		if (len + src2_len >= res_len) {
427 			os_memcpy(res + len, src2, res_len - len);
428 			return res_len;
429 		}
430 
431 		os_memcpy(res + len, src2, src2_len);
432 		len += src2_len;
433 	}
434 
435 	return len;
436 }
437 
438 
dup_binstr(const void * src,size_t len)439 char * dup_binstr(const void *src, size_t len)
440 {
441 	char *res;
442 
443 	if (src == NULL)
444 		return NULL;
445 	res = os_malloc(len + 1);
446 	if (res == NULL)
447 		return NULL;
448 	os_memcpy(res, src, len);
449 	res[len] = '\0';
450 
451 	return res;
452 }
453 
454 
int_array_len(const int * a)455 size_t int_array_len(const int *a)
456 {
457 	size_t i;
458 
459 	for (i = 0; a && a[i]; i++)
460 		;
461 	return i;
462 }
463 
str_clear_free(char * str)464 void str_clear_free(char *str)
465 {
466 	if (str) {
467 		size_t len = os_strlen(str);
468 		forced_memzero(str, len);
469 		os_free(str);
470 	}
471 }
472 
473 
bin_clear_free(void * bin,size_t len)474 void bin_clear_free(void *bin, size_t len)
475 {
476 	if (bin) {
477 		forced_memzero(bin, len);
478 		os_free(bin);
479 	}
480 }
481 
482 
os_gmtime(os_time_t t,struct os_tm * tm)483 int os_gmtime(os_time_t t, struct os_tm *tm)
484 {
485 	struct tm *tm2;
486 	time_t t2 = t;
487 
488 	tm2 = gmtime(&t2);
489 	if (tm2 == NULL)
490 		return -1;
491 	tm->sec = tm2->tm_sec;
492 	tm->min = tm2->tm_min;
493 	tm->hour = tm2->tm_hour;
494 	tm->day = tm2->tm_mday;
495 	tm->month = tm2->tm_mon + 1;
496 	tm->year = tm2->tm_year + 1900;
497 	return 0;
498 }
499 
os_mktime(int year,int month,int day,int hour,int min,int sec,os_time_t * t)500 int os_mktime(int year, int month, int day, int hour, int min, int sec,
501 		os_time_t *t)
502 {
503 	struct tm tm;
504 
505 	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
506 			hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
507 			sec > 60)
508 		return -1;
509 
510 	os_memset(&tm, 0, sizeof(tm));
511 	tm.tm_year = year - 1900;
512 	tm.tm_mon = month - 1;
513 	tm.tm_mday = day;
514 	tm.tm_hour = hour;
515 	tm.tm_min = min;
516 	tm.tm_sec = sec;
517 
518 	*t = (os_time_t) mktime(&tm);
519 	return 0;
520 }
521 
os_memdup(const void * src,size_t len)522 void * os_memdup(const void *src, size_t len)
523 {
524 	void *r = os_malloc(len);
525 
526 	if (r && src)
527 		os_memcpy(r, src, len);
528 	return r;
529 }
530 
os_reltime_expired(struct os_time * now,struct os_time * ts,os_time_t timeout_secs)531 int os_reltime_expired(struct os_time *now,
532 			struct os_time *ts,
533 			os_time_t timeout_secs)
534 {
535 	struct os_time age;
536 
537 	os_time_sub(now, ts, &age);
538 	return (age.sec > timeout_secs) ||
539 		(age.sec == timeout_secs && age.usec > 0);
540 }
541 
542 
os_reltime_initialized(struct os_reltime * t)543 int os_reltime_initialized(struct os_reltime *t)
544 {
545 	return t->sec != 0 || t->usec != 0;
546 }
547 
548 
rssi_to_rcpi(int rssi)549 u8 rssi_to_rcpi(int rssi)
550 {
551 	if (!rssi)
552 		return 255; /* not available */
553 	if (rssi < -110)
554 		return 0;
555 	if (rssi > 0)
556 		return 220;
557 	return (rssi + 110) * 2;
558 }
559 
560 
get_param(const char * cmd,const char * param)561 char * get_param(const char *cmd, const char *param)
562 {
563 	const char *pos, *end;
564 	char *val;
565 	size_t len;
566 
567 	pos = os_strstr(cmd, param);
568 	if (!pos)
569 		return NULL;
570 
571 	pos += os_strlen(param);
572 	end = os_strchr(pos, ' ');
573 	if (end)
574 		len = end - pos;
575 	else
576 		len = os_strlen(pos);
577 	val = os_malloc(len + 1);
578 	if (!val)
579 		return NULL;
580 	os_memcpy(val, pos, len);
581 	val[len] = '\0';
582 	return val;
583 }
584