Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include <errno.h>
6 : #include <limits.h>
7 : #include <ctype.h>
8 : #include "sdp_os_defs.h"
9 : #include "sdp.h"
10 : #include "sdp_private.h"
11 :
12 : #include "CSFLog.h"
13 :
14 : #define MKI_BUF_LEN 4
15 :
16 : static const char* logTag = "sdp_utils";
17 :
18 0 : sdp_mca_t *sdp_alloc_mca (uint32_t line) {
19 : sdp_mca_t *mca_p;
20 :
21 : /* Allocate resource for new media stream. */
22 0 : mca_p = (sdp_mca_t *)SDP_MALLOC(sizeof(sdp_mca_t));
23 0 : if (mca_p == NULL) {
24 0 : return (NULL);
25 : }
26 : /* Initialize mca structure */
27 0 : mca_p->media = SDP_MEDIA_INVALID;
28 0 : mca_p->conn.nettype = SDP_NT_INVALID;
29 0 : mca_p->conn.addrtype = SDP_AT_INVALID;
30 0 : mca_p->conn.conn_addr[0] = '\0';
31 0 : mca_p->conn.is_multicast = FALSE;
32 0 : mca_p->conn.ttl = 0;
33 0 : mca_p->conn.num_of_addresses = 0;
34 0 : mca_p->transport = SDP_TRANSPORT_INVALID;
35 0 : mca_p->port = SDP_INVALID_VALUE;
36 0 : mca_p->num_ports = SDP_INVALID_VALUE;
37 0 : mca_p->vpi = SDP_INVALID_VALUE;
38 0 : mca_p->vci = 0;
39 0 : mca_p->vcci = SDP_INVALID_VALUE;
40 0 : mca_p->cid = SDP_INVALID_VALUE;
41 0 : mca_p->num_payloads = 0;
42 0 : mca_p->sessinfo_found = FALSE;
43 0 : mca_p->encrypt.encrypt_type = SDP_ENCRYPT_INVALID;
44 0 : mca_p->media_attrs_p = NULL;
45 0 : mca_p->next_p = NULL;
46 0 : mca_p->mid = 0;
47 0 : mca_p->bw.bw_data_count = 0;
48 0 : mca_p->bw.bw_data_list = NULL;
49 0 : mca_p->line_number = line;
50 0 : mca_p->sctp_fmt = SDP_SCTP_MEDIA_FMT_UNKNOWN;
51 :
52 0 : return (mca_p);
53 : }
54 :
55 : /*
56 : * next_token
57 : *
58 : * copy token param with chars from str until null, cr, lf, or one of the delimiters is found.
59 : * delimiters at the beginning will be skipped.
60 : * The pointer *string_of_tokens is moved forward to the next token on sucess.
61 : *
62 : */
63 0 : static sdp_result_e next_token(const char **string_of_tokens, char *token, unsigned token_max_len, const char *delim)
64 : {
65 0 : int flag2moveon = 0;
66 : const char *str;
67 : const char *token_end;
68 : const char *next_delim;
69 :
70 0 : if (!string_of_tokens || !*string_of_tokens || !token || !delim) {
71 0 : return SDP_FAILURE;
72 : }
73 :
74 0 : str = *string_of_tokens;
75 0 : token_end = token + token_max_len - 1;
76 :
77 : /* Locate front of token, skipping any delimiters */
78 0 : for ( ; ((*str != '\0') && (*str != '\n') && (*str != '\r')); str++) {
79 0 : flag2moveon = 1; /* Default to move on unless we find a delimiter */
80 0 : for (next_delim=delim; *next_delim; next_delim++) {
81 0 : if (*str == *next_delim) {
82 0 : flag2moveon = 0;
83 0 : break;
84 : }
85 : }
86 0 : if( flag2moveon ) {
87 0 : break; /* We're at the beginning of the token */
88 : }
89 : }
90 :
91 : /* Make sure there's really a token present. */
92 0 : if ((*str == '\0') || (*str == '\n') || (*str == '\r')) {
93 0 : return SDP_EMPTY_TOKEN;
94 : }
95 :
96 : /* Now locate end of token */
97 0 : flag2moveon = 0;
98 :
99 0 : while ((token < token_end) &&
100 0 : (*str != '\0') && (*str != '\n') && (*str != '\r')) {
101 0 : for (next_delim=delim; *next_delim; next_delim++) {
102 0 : if (*str == *next_delim) {
103 0 : flag2moveon = 1;
104 0 : break;
105 : }
106 : }
107 0 : if( flag2moveon ) {
108 0 : break;
109 : } else {
110 0 : *token++ = *str++;
111 : }
112 : }
113 :
114 : /* mark end of token */
115 0 : *token = '\0';
116 :
117 : /* set the string of tokens to the next token */
118 0 : *string_of_tokens = str;
119 :
120 0 : return SDP_SUCCESS;
121 : }
122 :
123 : /*
124 : * verify_sdescriptions_mki
125 : *
126 : * Verifies the syntax of the MKI parameter.
127 : *
128 : * mki = mki-value ":" mki-length
129 : * mki-value = 1*DIGIT
130 : * mki-length = 1*3DIGIT ; range 1..128
131 : *
132 : * Inputs:
133 : * buf - ptr to start of MKI string assumes NULL
134 : * terminated string
135 : * mkiValue - buffer to store the MKI value, assumes calling
136 : * function has provided memory for this.
137 : * mkiLen - integer to store the MKI length
138 : *
139 : * Outputs:
140 : * Returns TRUE if syntax is correct and stores the
141 : * MKI value in mkiVal and stores the length in mkiLen.
142 : * Returns FALSE otherwise.
143 : */
144 :
145 : tinybool
146 0 : verify_sdescriptions_mki (char *buf, char *mkiVal, uint16_t *mkiLen)
147 : {
148 :
149 : char *ptr,
150 : mkiValBuf[SDP_SRTP_MAX_MKI_SIZE_BYTES],
151 : mkiLenBuf[MKI_BUF_LEN];
152 0 : int idx = 0;
153 : unsigned long strtoul_result;
154 : char *strtoul_end;
155 :
156 0 : ptr = buf;
157 : /* MKI must begin with a digit */
158 0 : if (!ptr || (!isdigit((int) *ptr))) {
159 0 : return FALSE;
160 : }
161 :
162 : /* scan until we reach a non-digit or colon */
163 0 : while (*ptr) {
164 0 : if (*ptr == ':') {
165 : /* terminate the MKI value */
166 0 : mkiValBuf[idx] = 0;
167 0 : ptr++;
168 0 : break;
169 0 : } else if ((isdigit((int) *ptr) && (idx < SDP_SRTP_MAX_MKI_SIZE_BYTES-1))) {
170 0 : mkiValBuf[idx++] = *ptr;
171 : } else {
172 0 : return FALSE;
173 : }
174 :
175 0 : ptr++;
176 : }
177 :
178 : /* there has to be a mki length */
179 0 : if (*ptr == 0) {
180 0 : return FALSE;
181 : }
182 :
183 0 : idx = 0;
184 :
185 : /* verify the mki length (max 3 digits) */
186 0 : while (*ptr) {
187 0 : if (isdigit((int) *ptr) && (idx < 3)) {
188 0 : mkiLenBuf[idx++] = *ptr;
189 : } else {
190 0 : return FALSE;
191 : }
192 :
193 0 : ptr++;
194 : }
195 :
196 0 : mkiLenBuf[idx] = 0;
197 :
198 0 : errno = 0;
199 0 : strtoul_result = strtoul(mkiLenBuf, &strtoul_end, 10);
200 :
201 : /* mki len must be between 1..128 */
202 0 : if (errno || mkiLenBuf == strtoul_end || strtoul_result < 1 || strtoul_result > 128) {
203 0 : *mkiLen = 0;
204 0 : return FALSE;
205 : }
206 :
207 0 : *mkiLen = (uint16_t) strtoul_result;
208 0 : sstrncpy(mkiVal, mkiValBuf, MKI_BUF_LEN);
209 :
210 0 : return TRUE;
211 : }
212 :
213 : /*
214 : * verify_srtp_lifetime
215 : *
216 : * Verifies the Lifetime parameter syntax.
217 : *
218 : * lifetime = ["2^"] 1*(DIGIT)
219 : *
220 : * Inputs:
221 : * buf - pointer to start of lifetime string. Assumes string is
222 : * NULL terminated.
223 : * Outputs:
224 : * Returns TRUE if syntax is correct. Returns FALSE otherwise.
225 : */
226 :
227 : tinybool
228 0 : verify_sdescriptions_lifetime (char *buf)
229 : {
230 :
231 : char *ptr;
232 0 : tinybool tokenFound = FALSE;
233 :
234 0 : ptr = buf;
235 0 : if (!ptr || *ptr == 0) {
236 0 : return FALSE;
237 : }
238 :
239 0 : while (*ptr) {
240 0 : if (*ptr == '^') {
241 0 : if (tokenFound) {
242 : /* make sure we don't have multiple ^ */
243 0 : return FALSE;
244 : } else {
245 0 : tokenFound = TRUE;
246 : /* Lifetime is in power of 2 format, make sure first and second
247 : * chars are 2^
248 : */
249 :
250 0 : if (buf[0] != '2' || buf[1] != '^') {
251 0 : return FALSE;
252 : }
253 : }
254 0 : } else if (!isdigit((int) *ptr)) {
255 0 : return FALSE;
256 : }
257 :
258 0 : ptr++;
259 :
260 : }
261 :
262 : /* Make sure if the format is 2^ that there is a number after the ^. */
263 0 : if (tokenFound) {
264 0 : if (strlen(buf) <= 2) {
265 0 : return FALSE;
266 : }
267 : }
268 :
269 0 : return TRUE;
270 : }
271 :
272 :
273 : /*
274 : * sdp_validate_maxprate
275 : *
276 : * This function validates that the string passed in is of the form:
277 : * packet-rate = 1*DIGIT ["." 1*DIGIT]
278 : */
279 : tinybool
280 0 : sdp_validate_maxprate(const char *string_parm)
281 : {
282 0 : tinybool retval = FALSE;
283 :
284 0 : if (string_parm && (*string_parm)) {
285 0 : while (isdigit((int)*string_parm)) {
286 0 : string_parm++;
287 : }
288 :
289 0 : if (*string_parm == '.') {
290 0 : string_parm++;
291 0 : while (isdigit((int)*string_parm)) {
292 0 : string_parm++;
293 : }
294 : }
295 :
296 0 : if (*string_parm == '\0') {
297 0 : retval = TRUE;
298 : } else {
299 0 : retval = FALSE;
300 : }
301 : }
302 :
303 0 : return retval;
304 : }
305 :
306 0 : char *sdp_findchar (const char *ptr, char *char_list)
307 : {
308 : int i;
309 :
310 0 : for (;*ptr != '\0'; ptr++) {
311 0 : for (i=0; char_list[i] != '\0'; i++) {
312 0 : if (*ptr == char_list[i]) {
313 0 : return ((char *)ptr);
314 : }
315 : }
316 : }
317 0 : return ((char *)ptr);
318 : }
319 :
320 : /* Locate the next token in a line. The delim characters are passed in
321 : * as a param. The token also will not go past a new line char or the
322 : * end of the string. Skip any delimiters before the token.
323 : */
324 0 : const char *sdp_getnextstrtok (const char *str, char *tokenstr, unsigned tokenstr_len,
325 : const char *delim, sdp_result_e *result)
326 : {
327 0 : const char *token_list = str;
328 :
329 0 : if (!str || !tokenstr || !delim || !result) {
330 0 : if (result) {
331 0 : *result = SDP_FAILURE;
332 : }
333 0 : return str;
334 : }
335 :
336 0 : *result = next_token(&token_list, tokenstr, tokenstr_len, delim);
337 :
338 0 : return token_list;
339 : }
340 :
341 :
342 :
343 : /* Locate the next null ("-") or numeric token in a string. The delim
344 : * characters are passed in as a param. The token also will not go past
345 : * a new line char or the end of the string. Skip any delimiters before
346 : * the token.
347 : */
348 0 : uint32_t sdp_getnextnumtok_or_null (const char *str, const char **str_end,
349 : const char *delim, tinybool *null_ind,
350 : sdp_result_e *result)
351 : {
352 0 : const char *token_list = str;
353 : char temp_token[SDP_MAX_STRING_LEN];
354 : char *strtoul_end;
355 : unsigned long numval;
356 :
357 0 : if (null_ind) {
358 0 : *null_ind = FALSE;
359 : }
360 :
361 0 : if (!str || !str_end || !delim || !null_ind || !result) {
362 0 : if (result) {
363 0 : *result = SDP_FAILURE;
364 : }
365 0 : return 0;
366 : }
367 :
368 0 : *result = next_token(&token_list, temp_token, sizeof(temp_token), delim);
369 :
370 0 : if (*result != SDP_SUCCESS) {
371 0 : return 0;
372 : }
373 :
374 : /* First see if its the null char ("-") */
375 0 : if (temp_token[0] == '-') {
376 0 : *null_ind = TRUE;
377 0 : *result = SDP_SUCCESS;
378 0 : *str_end = str;
379 0 : return 0;
380 : }
381 :
382 0 : errno = 0;
383 0 : numval = strtoul(temp_token, &strtoul_end, 10);
384 :
385 0 : if (errno || strtoul_end == temp_token || numval > UINT_MAX) {
386 0 : *result = SDP_FAILURE;
387 0 : return 0;
388 : }
389 :
390 0 : *result = SDP_SUCCESS;
391 0 : *str_end = token_list;
392 0 : return (uint32_t) numval;
393 : }
394 :
395 :
396 : /* Locate the next numeric token in a string. The delim characters are
397 : * passed in as a param. The token also will not go past a new line char
398 : * or the end of the string. Skip any delimiters before the token.
399 : */
400 0 : uint32_t sdp_getnextnumtok (const char *str, const char **str_end,
401 : const char *delim, sdp_result_e *result)
402 : {
403 0 : const char *token_list = str;
404 : char temp_token[SDP_MAX_STRING_LEN];
405 : char *strtoul_end;
406 : unsigned long numval;
407 :
408 0 : if (!str || !str_end || !delim || !result) {
409 0 : if (result) {
410 0 : *result = SDP_FAILURE;
411 : }
412 0 : return 0;
413 : }
414 :
415 0 : *result = next_token(&token_list, temp_token, sizeof(temp_token), delim);
416 :
417 0 : if (*result != SDP_SUCCESS) {
418 0 : return 0;
419 : }
420 :
421 0 : errno = 0;
422 0 : numval = strtoul(temp_token, &strtoul_end, 10);
423 :
424 0 : if (errno || strtoul_end == temp_token || numval > UINT_MAX) {
425 0 : *result = SDP_FAILURE;
426 0 : return 0;
427 : }
428 :
429 0 : *result = SDP_SUCCESS;
430 0 : *str_end = token_list;
431 0 : return (uint32_t) numval;
432 : }
433 :
434 :
435 : /* See if the next token in a string is the choose character. The delim
436 : * characters are passed in as a param. The check also will not go past
437 : * a new line char or the end of the string. Skip any delimiters before
438 : * the token.
439 : */
440 0 : tinybool sdp_getchoosetok (const char *str, const char **str_end,
441 : const char *delim, sdp_result_e *result)
442 : {
443 : const char *b;
444 : int flag2moveon;
445 :
446 0 : if ((str == NULL) || (str_end == NULL)) {
447 0 : *result = SDP_FAILURE;
448 0 : return(FALSE);
449 : }
450 :
451 : /* Locate front of token, skipping any delimiters */
452 0 : for ( ; ((*str != '\0') && (*str != '\n') && (*str != '\r')); str++) {
453 0 : flag2moveon = 1; /* Default to move on unless we find a delimiter */
454 0 : for (b=delim; *b; b++) {
455 0 : if (*str == *b) {
456 0 : flag2moveon = 0;
457 0 : break;
458 : }
459 : }
460 0 : if( flag2moveon ) {
461 0 : break; /* We're at the beginning of the token */
462 : }
463 : }
464 :
465 : /* Make sure there's really a token present. */
466 0 : if ((*str == '\0') || (*str == '\n') || (*str == '\r')) {
467 0 : *result = SDP_FAILURE;
468 0 : *str_end = (char *)str;
469 0 : return(FALSE);
470 : }
471 :
472 : /* See if the token is '$' followed by a delimiter char or end of str. */
473 0 : if (*str == '$') {
474 0 : str++;
475 0 : if ((*str == '\0') || (*str == '\n') || (*str == '\r')) {
476 0 : *result = SDP_SUCCESS;
477 : /* skip the choose char in the string. */
478 0 : *str_end = (char *)(str+1);
479 0 : return(TRUE);
480 : }
481 0 : for (b=delim; *b; b++) {
482 0 : if (*str == *b) {
483 0 : *result = SDP_SUCCESS;
484 : /* skip the choose char in the string. */
485 0 : *str_end = (char *)(str+1);
486 0 : return(TRUE);
487 : }
488 : }
489 : }
490 :
491 : /* If the token was not '$' followed by a delim, token is not choose */
492 0 : *result = SDP_SUCCESS;
493 0 : *str_end = (char *)str;
494 0 : return(FALSE);
495 :
496 : }
497 :
498 : /*
499 : * SDP Crypto Utility Functions.
500 : *
501 : * First a few common definitions.
502 : */
503 :
504 : /*
505 : * Constants
506 : *
507 : * crypto_string = The string used to identify the start of sensative
508 : * crypto data.
509 : *
510 : * inline_string = The string used to identify the start of key/salt
511 : * crypto data.
512 : *
513 : * star_string = The string used to overwrite sensative data.
514 : *
515 : * '*_strlen' = The length of '*_string' in bytes (not including '\0')
516 : */
517 : static const char crypto_string[] = "X-crypto:";
518 : static const int crypto_strlen = sizeof(crypto_string) - 1;
519 : static const char inline_string[] = "inline:";
520 : static const int inline_strlen = sizeof(inline_string) - 1;
521 : /* 40 characters is the current maximum for a Base64 encoded key/salt */
522 : static const char star_string[] = "****************************************";
523 : static const int star_strlen = sizeof(star_string) - 1;
524 :
525 : /*
526 : * MIN_CRYPTO_STRING_SIZE_BYTES = This value defines the minimum
527 : * size of a string that could contain a key/salt. This value
528 : * is used to skip out of parsing when there is no reasonable
529 : * assumption that sensative data will be found. The general
530 : * format of a SRTP Key Salt in SDP looks like:
531 : *
532 : * X-crypto:<crypto_suite_name> inline:<master_key_salt>||
533 : *
534 : * if <crypto_suite_name> and <master_key_salt> is at least
535 : * one character and one space is used before the "inline:",
536 : * then this translates to a size of (aligned by collumn from
537 : * the format shown above):
538 : *
539 : * 9+ 1+ 1+7+ 1+ 2 = 21
540 : *
541 : */
542 : #define MIN_CRYPTO_STRING_SIZE_BYTES 21
543 :
544 : /*
545 : * Utility macros
546 : *
547 : * CHAR_IS_WHITESPACE = macro to determine if the passed _test_char
548 : * is whitespace.
549 : *
550 : * SKIP_WHITESPACE = Macro to advance _cptr to the next non-whitespace
551 : * character. _cptr will not be advanced past _max_cptr.
552 : *
553 : * FIND_WHITESPACE = Macro to advance _cptr until whitespace is found.
554 : * _cptr will not be advanced past _max_cptr.
555 : */
556 : #define CHAR_IS_WHITESPACE(_test_char) \
557 : ((((_test_char)==' ')||((_test_char)=='\t'))?1:0)
558 :
559 : #define SKIP_WHITESPACE(_cptr, _max_cptr) \
560 : while ((_cptr)<=(_max_cptr)) { \
561 : if (!CHAR_IS_WHITESPACE(*(_cptr))) break; \
562 : (_cptr)++; \
563 : }
564 :
565 : #define FIND_WHITESPACE(_cptr, _max_cptr) \
566 : while ((_cptr)<=(_max_cptr)) { \
567 : if (CHAR_IS_WHITESPACE(*(_cptr))) break; \
568 : (_cptr)++; \
569 : }
570 :
571 : /* Function: sdp_crypto_debug
572 : * Description: Check the passed buffer for sensitive data that should
573 : * not be output (such as SRTP Master Key/Salt) and output
574 : * the buffer as debug. Sensitive data will be replaced
575 : * with the '*' character(s). This function may be used
576 : * to display very large buffers so this function ensures
577 : * that buginf is not overloaded.
578 : * Parameters: buffer pointer to the message buffer to filter.
579 : * length_bytes size of message buffer in bytes.
580 : * Returns: Nothing.
581 : */
582 0 : void sdp_crypto_debug (char *buffer, ulong length_bytes)
583 : {
584 : char *current, *start;
585 0 : char *last = buffer + length_bytes;
586 : int result;
587 :
588 : /*
589 : * For SRTP Master Key/Salt has the form:
590 : * X-crypto:<crypto_suite_name> inline:<master_key_salt>||
591 : * Where <master_key_salt> is the data to elide (filter).
592 : */
593 0 : for (start=current=buffer;
594 0 : current<=last-MIN_CRYPTO_STRING_SIZE_BYTES;
595 0 : current++) {
596 0 : if ((*current == 'x') || (*current == 'X')) {
597 0 : result = cpr_strncasecmp(current, crypto_string, crypto_strlen);
598 0 : if (!result) {
599 0 : current += crypto_strlen;
600 0 : if (current > last) break;
601 :
602 : /* Skip over crypto suite name */
603 0 : FIND_WHITESPACE(current, last);
604 :
605 : /* Skip over whitespace */
606 0 : SKIP_WHITESPACE(current, last);
607 :
608 : /* identify inline keyword */
609 0 : result = cpr_strncasecmp(current, inline_string, inline_strlen);
610 0 : if (!result) {
611 0 : int star_count = 0;
612 :
613 0 : current += inline_strlen;
614 0 : if (current > last) break;
615 :
616 0 : sdp_dump_buffer(start, current - start);
617 :
618 : /* Hide sensitive key/salt data */
619 0 : while (current<=last) {
620 0 : if (*current == '|' || *current == '\n') {
621 : /* Done, print the stars */
622 0 : while (star_count > star_strlen) {
623 : /*
624 : * This code is only for the case where
625 : * too much base64 data was supplied
626 : */
627 0 : sdp_dump_buffer((char*)star_string, star_strlen);
628 0 : star_count -= star_strlen;
629 : }
630 0 : sdp_dump_buffer((char*)star_string, star_count);
631 0 : break;
632 : } else {
633 0 : star_count++;
634 0 : current++;
635 : }
636 : }
637 : /* Update start pointer */
638 0 : start=current;
639 : }
640 : }
641 : }
642 : }
643 :
644 0 : if (last > start) {
645 : /* Display remainder of buffer */
646 0 : sdp_dump_buffer(start, last - start);
647 : }
648 0 : }
649 :
650 : /*
651 : * sdp_debug_msg_filter
652 : *
653 : * DESCRIPTION
654 : * Check the passed message buffer for sensitive data that should
655 : * not be output (such as SRTP Master Key/Salt). Sensitive data
656 : * will be replaced with the '*' character(s).
657 : *
658 : * PARAMETERS
659 : * buffer: pointer to the message buffer to filter.
660 : *
661 : * length_bytes: size of message buffer in bytes.
662 : *
663 : * RETURN VALUE
664 : * The buffer modified.
665 : */
666 0 : char * sdp_debug_msg_filter (char *buffer, ulong length_bytes)
667 : {
668 : char *current;
669 0 : char *last = buffer + length_bytes;
670 : int result;
671 :
672 0 : SDP_PRINT("\n%s:%d: Eliding sensitive data from debug output",
673 : __FILE__, __LINE__);
674 : /*
675 : * For SRTP Master Key/Salt has the form:
676 : * X-crypto:<crypto_suite_name> inline:<master_key_salt>||
677 : * Where <master_key_salt> is the data to elide (filter).
678 : */
679 0 : for (current=buffer;
680 0 : current<=last-MIN_CRYPTO_STRING_SIZE_BYTES;
681 0 : current++) {
682 0 : if ((*current == 'x') || (*current == 'X')) {
683 0 : result = cpr_strncasecmp(current, crypto_string, crypto_strlen);
684 0 : if (!result) {
685 0 : current += crypto_strlen;
686 0 : if (current > last) break;
687 :
688 : /* Skip over crypto suite name */
689 0 : FIND_WHITESPACE(current, last);
690 :
691 : /* Skip over whitespace */
692 0 : SKIP_WHITESPACE(current, last);
693 :
694 : /* identify inline keyword */
695 0 : result = cpr_strncasecmp(current, inline_string, inline_strlen);
696 0 : if (!result) {
697 0 : current += inline_strlen;
698 0 : if (current > last) break;
699 :
700 : /* Hide sensitive key/salt data */
701 0 : while (current<=last) {
702 0 : if (*current == '|' || *current == '\n') {
703 : /* Done */
704 : break;
705 : } else {
706 0 : *current = '*';
707 0 : current++;
708 : }
709 : }
710 : }
711 : }
712 : }
713 : }
714 :
715 0 : return buffer;
716 : }
717 :
718 :
719 : /* Function: sdp_checkrange
720 : * Description: This checks the range of a ulong value to make sure its
721 : * within the range of 0 and 4Gig. stroul cannot be used since
722 : * for values greater greater than 4G, stroul will either wrap
723 : * around or return ULONG_MAX.
724 : * Parameters: sdp_p Pointer to the sdp structure
725 : * num The number to check the range for
726 : * u_val This variable get populated with the ulong value
727 : * if the number is within the range.
728 : * Returns: tinybool - returns TRUE if the number passed is within the
729 : * range, FALSE otherwise
730 : */
731 0 : tinybool sdp_checkrange (sdp_t *sdp_p, char *num, ulong *u_val)
732 : {
733 : ulong l_val;
734 0 : char *endP = NULL;
735 0 : *u_val = 0;
736 :
737 0 : if (!num || !*num) {
738 0 : return FALSE;
739 : }
740 :
741 0 : if (*num == '-') {
742 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
743 0 : CSFLogError(logTag, "%s ERROR: Parameter value is a negative number: %s",
744 : sdp_p->debug_str, num);
745 : }
746 0 : return FALSE;
747 : }
748 :
749 0 : l_val = strtoul(num, &endP, 10);
750 0 : if (*endP == '\0') {
751 :
752 0 : if (l_val > 4294967295UL) {
753 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
754 0 : CSFLogError(logTag, "%s ERROR: Parameter value: %s is greater than 4294967295",
755 : sdp_p->debug_str, num);
756 : }
757 0 : return FALSE;
758 : }
759 :
760 0 : if (l_val == 4294967295UL) {
761 : /*
762 : * On certain platforms where ULONG_MAX is equivalent to
763 : * 4294967295, strtoul will return ULONG_MAX even if the the
764 : * value of the string is greater than 4294967295. To detect
765 : * that scenario we make an explicit check here.
766 : */
767 0 : if (strcmp("4294967295", num)) {
768 0 : if (sdp_p->debug_flag[SDP_DEBUG_ERRORS]) {
769 0 : CSFLogError(logTag, "%s ERROR: Parameter value: %s is greater than 4294967295",
770 : sdp_p->debug_str, num);
771 : }
772 0 : return FALSE;
773 : }
774 : }
775 : }
776 0 : *u_val = l_val;
777 0 : return TRUE;
778 : }
779 :
780 : #undef CHAR_IS_WHITESPACE
781 : #undef SKIP_WHITESPACE
782 : #undef FIND_WHITESPACE
|