00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "mod_sanity.h"
00032 #include "sanity.h"
00033 #include "../../ut.h"
00034 #include "../../trim.h"
00035 #include "../../data_lump_rpl.h"
00036 #include "../../mem/mem.h"
00037 #include "../../parser/parse_uri.h"
00038 #include "../../parser/parse_expires.h"
00039 #include "../../parser/parse_content.h"
00040 #include "../../parser/digest/digest.h"
00041 #include "../../parser/contact/parse_contact.h"
00042
00043 #define UNSUPPORTED_HEADER "Unsupported: "
00044 #define UNSUPPORTED_HEADER_LEN (sizeof(UNSUPPORTED_HEADER)-1)
00045
00046
00047 int str2valid_uint(str* _number, unsigned int* _result) {
00048 int i;
00049 int result= 0;
00050 int equal = 1;
00051 char mui[10] = "4294967296";
00052
00053 *_result = 0;
00054 if (_number->len > 10) {
00055 #ifdef EXTRA_DEBUG
00056 DBG("valid_uint(): number is too long\n");
00057 #endif
00058 return -1;
00059 }
00060 if (_number->len < 10) {
00061 equal = 0;
00062 }
00063 for (i=0; i < _number->len; i++) {
00064 if (_number->s[i] < '0' || _number->s[i] > '9') {
00065 #ifdef EXTRA_DEBUG
00066 DBG("valid_uint(): number contains non-number char\n");
00067 #endif
00068 return -1;
00069 }
00070 if (equal == 1) {
00071 if (_number->s[i] < mui[i]) {
00072 equal = 0;
00073 }
00074 else if (_number->s[i] > mui[i]) {
00075 #ifdef EXTRA_DEBUG
00076 DBG("valid_uint(): number exceeds uint\n");
00077 #endif
00078 return -1;
00079 }
00080 }
00081 result *= 10;
00082 result += _number->s[i] - '0';
00083 }
00084 *_result = result;
00085 return 0;
00086 }
00087
00088
00089 strl* parse_str_list(str* _string) {
00090 str input;
00091 strl *parsed_list, *pl;
00092 char *comma;
00093
00094
00095 input.s = _string->s;
00096 input.len = _string->len;
00097
00098 trim(&input);
00099
00100 if (input.len == 0) {
00101 #ifdef EXTRA_DEBUG
00102 DBG("parse_str_list: list is empty\n");
00103 #endif
00104 return NULL;
00105 }
00106 parsed_list = pkg_malloc(sizeof(strl));
00107 if (parsed_list == NULL) {
00108 LOG(L_ERR, "parse_str_list: OUT OF MEMORY for initial list element\n");
00109 return NULL;
00110 }
00111 memset(parsed_list, 0, sizeof(strl));
00112 parsed_list->string.s = input.s;
00113 parsed_list->string.len = input.len;
00114
00115 comma = q_memchr(input.s, ',', input.len);
00116 pl = parsed_list;
00117 while (comma != NULL) {
00118 pl->next = pkg_malloc(sizeof(strl));
00119 if (pl->next == NULL) {
00120 LOG(L_ERR, "parse_str_list: OUT OF MEMORY for further list element\n");
00121 return parsed_list;
00122 }
00123 memset(pl->next, 0, sizeof(strl));
00124 pl->next->string.s = comma + 1;
00125 pl->next->string.len = pl->string.len - (pl->next->string.s - pl->string.s);
00126 pl->string.len = comma - pl->string.s;
00127 trim_trailing(&(pl->string));
00128 pl = pl->next;
00129 trim_leading(&(pl->string));
00130 comma = q_memchr(pl->string.s, ',', pl->string.len);
00131 }
00132
00133 return parsed_list;
00134 }
00135
00136
00137 void free_str_list(strl *_list) {
00138 strl *cur, *next;
00139
00140 if (_list != NULL) {
00141 cur = _list;
00142 while (cur != NULL) {
00143 next = cur->next;
00144 pkg_free(cur);
00145 cur = next;
00146 }
00147 }
00148 }
00149
00150 int parse_proxyrequire(struct hdr_field* _h) {
00151 strl *pr_l;
00152
00153 if (_h->parsed) {
00154 return 0;
00155 }
00156
00157 if ((pr_l = parse_str_list(&(_h->body))) == NULL) {
00158 LOG(L_ERR, "parse_proxy_require(): Error while parsing\n");
00159 return -1;
00160 }
00161
00162 _h->parsed = pr_l;
00163 return 0;
00164 }
00165
00166
00167 int check_ruri_sip_version(struct sip_msg* _msg) {
00168 char *sep;
00169 str version;
00170
00171 #ifdef EXTRA_DEBUG
00172 DBG("check_ruri_sip_version entered\n");
00173 #endif
00174
00175 if (_msg->first_line.u.request.version.len != 0) {
00176 sep = q_memchr(_msg->first_line.u.request.version.s, '/',
00177 _msg->first_line.u.request.version.len);
00178 if (sep == NULL) {
00179 LOG(L_WARN, "sanity_check(): check_ruri_sip_version(): failed to find / in ruri version\n");
00180 return SANITY_CHECK_FAILED;
00181 }
00182 version.s = sep + 1;
00183 version.len = _msg->first_line.u.request.version.len - (version.s - _msg->first_line.u.request.version.s);
00184
00185 if (version.len != SIP_VERSION_TWO_POINT_ZERO_LENGTH ||
00186 (memcmp(version.s, SIP_VERSION_TWO_POINT_ZERO,
00187 SIP_VERSION_TWO_POINT_ZERO_LENGTH) != 0)) {
00188 if (_msg->REQ_METHOD != METHOD_ACK) {
00189 if (sl.reply(_msg, 505, "Version Not Supported (R-URI)") == -1) {
00190 LOG(L_WARN, "sanity_check(): check_ruri_sip_version(): failed to send 505 via send_reply\n");
00191 }
00192 }
00193 #ifdef EXTRA_DEBUG
00194 DBG("check_ruri_sip_version failed\n");
00195 #endif
00196 return SANITY_CHECK_FAILED;
00197 }
00198 }
00199 #ifdef EXTRA_DEBUG
00200 DBG("check_ruri_sip_version passed\n");
00201 #endif
00202 return SANITY_CHECK_PASSED;
00203 }
00204
00205
00206 int check_ruri_scheme(struct sip_msg* _msg) {
00207
00208 #ifdef EXTRA_DEBUG
00209 DBG("check_ruri_scheme entered\n");
00210 #endif
00211
00212 if (_msg->parsed_uri_ok == 0 &&
00213 parse_sip_msg_uri(_msg) != 1) {
00214
00215 LOG(L_WARN, "sanity_check(): check_ruri_scheme(): failed to parse request uri\n");
00216 }
00217 if (_msg->parsed_uri.type == ERROR_URI_T) {
00218 if (_msg->REQ_METHOD != METHOD_ACK) {
00219 if (sl.reply(_msg, 416, "Unsupported URI Scheme in Request URI") == -1) {
00220 LOG(L_WARN, "sanity_check(): check_ruri_scheme(): failed to send 416 via send_reply\n");
00221 }
00222 }
00223 DBG("check_ruri_scheme failed\n");
00224 return SANITY_CHECK_FAILED;
00225 }
00226 #ifdef EXTRA_DEBUG
00227 DBG("check_ruri_scheme passed\n");
00228 #endif
00229
00230 return SANITY_CHECK_PASSED;
00231 }
00232
00233
00234 int check_required_headers(struct sip_msg* _msg) {
00235
00236 #ifdef EXTRA_DEBUG
00237 DBG("check_required_headers entered\n");
00238 #endif
00239
00240 if (!check_transaction_quadruple(_msg)) {
00241 if (_msg->REQ_METHOD != METHOD_ACK) {
00242 if (sl.reply(_msg, 400, "Missing Required Header in Request") == -1) {
00243 LOG(L_WARN, "sanity_check(): check_required_headers(): failed to send 400 via send_reply\n");
00244 }
00245 }
00246 DBG("check_required_headers failed\n");
00247 return SANITY_CHECK_FAILED;
00248 }
00249
00250 #ifdef EXTRA_DEBUG
00251 DBG("check_required_headers passed\n");
00252 #endif
00253
00254 return SANITY_CHECK_PASSED;
00255 }
00256
00257
00258 int check_via_sip_version(struct sip_msg* _msg) {
00259
00260 DBG("sanity_check(): check_via_sip_version(): this is a useless check for now; check the source code comments for details\n");
00261 return SANITY_CHECK_PASSED;
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 }
00291
00292
00293 int check_via_protocol(struct sip_msg* _msg) {
00294
00295 DBG("sanity_check(): check_via_protocol(): this is a useless check for now; check the source code comment for details\n");
00296 return SANITY_CHECK_PASSED;
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 }
00373
00374
00375 int check_cseq_method(struct sip_msg* _msg) {
00376
00377 #ifdef EXTRA_DEBUG
00378 DBG("check_cseq_method entered\n");
00379 #endif
00380
00381 if (parse_headers(_msg, HDR_CSEQ_F, 0) != 0) {
00382 LOG(L_WARN, "sanity_check(): check_cseq_method(): failed to parse the CSeq header\n");
00383 return SANITY_CHECK_FAILED;
00384 }
00385 if (_msg->cseq != NULL && _msg->cseq->parsed != NULL) {
00386 if (((struct cseq_body*)_msg->cseq->parsed)->method.len == 0) {
00387 if (_msg->REQ_METHOD != METHOD_ACK) {
00388 if (sl.reply(_msg, 400, "Missing method in CSeq header") == -1) {
00389 LOG(L_WARN, "sanity_check(): check_cseq_method(): failed to send 400 via send_reply\n");
00390 }
00391 }
00392 DBG("check_cseq_method failed (missing method)\n");
00393 return SANITY_CHECK_FAILED;
00394 }
00395
00396 if (((struct cseq_body*)_msg->cseq->parsed)->method.len !=
00397 _msg->first_line.u.request.method.len ||
00398 memcmp(((struct cseq_body*)_msg->cseq->parsed)->method.s,
00399 _msg->first_line.u.request.method.s,
00400 ((struct cseq_body*)_msg->cseq->parsed)->method.len) != 0) {
00401 if (_msg->REQ_METHOD != METHOD_ACK) {
00402 if (sl.reply(_msg, 400, "CSeq method does not match request method") == -1) {
00403 LOG(L_WARN, "sanity_check(): check_cseq_method(): failed to send 400 via send_reply 2\n");
00404 }
00405 }
00406 DBG("check_cseq_method failed (non-equal method)\n");
00407 return SANITY_CHECK_FAILED;
00408 }
00409 }
00410 else {
00411 LOG(L_WARN, "sanity_check(): check_cseq_method(): missing CSeq header\n");
00412 return SANITY_CHECK_FAILED;
00413 }
00414 #ifdef EXTRA_DEBUG
00415 DBG("check_cseq_method passed\n");
00416 #endif
00417
00418 return SANITY_CHECK_PASSED;
00419 }
00420
00421
00422 int check_cseq_value(struct sip_msg* _msg) {
00423 unsigned int cseq;
00424
00425 #ifdef EXTRA_DEBUG
00426 DBG("check_cseq_value entered\n");
00427 #endif
00428
00429 if (parse_headers(_msg, HDR_CSEQ_F, 0) != 0) {
00430 LOG(L_WARN, "sanity_check(): check_cseq_value(): failed to parse the CSeq header\n");
00431 return SANITY_CHECK_FAILED;
00432 }
00433 if (_msg->cseq != NULL && _msg->cseq->parsed != NULL) {
00434 if (((struct cseq_body*)_msg->cseq->parsed)->number.len == 0) {
00435 if (_msg->REQ_METHOD != METHOD_ACK) {
00436 if (sl.reply(_msg, 400, "Missing number in CSeq header") == -1) {
00437 LOG(L_WARN, "sanity_check(): check_cseq_value(): failed to send 400 via send_reply\n");
00438 }
00439 }
00440 return SANITY_CHECK_FAILED;
00441 }
00442 if (str2valid_uint(&((struct cseq_body*)_msg->cseq->parsed)->number, &cseq) != 0) {
00443 if (_msg->REQ_METHOD != METHOD_ACK) {
00444 if (sl.reply(_msg, 400, "CSeq number is illegal") == -1) {
00445 LOG(L_WARN, "sanity_check(): check_cseq_value(): failed to send 400 via send_reply 2\n");
00446 }
00447 }
00448 DBG("check_cseq_value failed\n");
00449 return SANITY_CHECK_FAILED;
00450 }
00451 }
00452 else {
00453 LOG(L_WARN, "sanity_check(): check_cseq_method(): missing CSeq header\n");
00454 return SANITY_CHECK_FAILED;
00455 }
00456 #ifdef EXTRA_DEBUG
00457 DBG("check_cseq_value passed\n");
00458 #endif
00459
00460 return SANITY_CHECK_PASSED;
00461 }
00462
00463
00464 int check_cl(struct sip_msg* _msg) {
00465 char *body;
00466
00467 #ifdef EXTRA_DEBUG
00468 DBG("check_cl entered\n");
00469 #endif
00470
00471 if (parse_headers(_msg, HDR_CONTENTLENGTH_F, 0) != 0) {
00472 LOG(L_WARN, "sanity_check(): check_cl(): failed to parse content-length header\n");
00473 return SANITY_CHECK_FAILED;
00474 }
00475 if (_msg->content_length != NULL) {
00476
00477 if ((body = get_body(_msg)) == NULL) {
00478 #ifdef EXTRA_DEBUG
00479 DBG("check_cl(): no body\n");
00480 #endif
00481 return SANITY_CHECK_FAILED;
00482 }
00483 if ((_msg->len - (body - _msg->buf)) != get_content_length(_msg)) {
00484 if (_msg->REQ_METHOD != METHOD_ACK) {
00485 if (sl.reply(_msg, 400, "Content-Length mis-match") == -1) {
00486 LOG(L_WARN, "sanity_check(): check_cl(): failed to send 400 via send_reply\n");
00487 }
00488 }
00489 DBG("check_cl failed\n");
00490 return SANITY_CHECK_FAILED;
00491 }
00492 #ifdef EXTRA_DEBUG
00493 DBG("check_cl passed\n");
00494 #endif
00495 }
00496 #ifdef EXTRA_DEBUG
00497 else {
00498 WARN("check_cl(): content length header missing in request\n");
00499 }
00500 #endif
00501
00502 return SANITY_CHECK_PASSED;
00503 }
00504
00505
00506 int check_expires_value(struct sip_msg* _msg) {
00507 unsigned int expires;
00508
00509 #ifdef EXTRA_DEBUG
00510 DBG("check_expires_value entered\n");
00511 #endif
00512
00513 if (parse_headers(_msg, HDR_EXPIRES_F, 0) != 0) {
00514 LOG(L_WARN, "sanity_check(): check_expires_value(): failed to parse expires header\n");
00515 return SANITY_CHECK_FAILED;
00516 }
00517 if (_msg->expires != NULL) {
00518
00519 if (_msg->expires->parsed == NULL &&
00520 parse_expires(_msg->expires) < 0) {
00521 LOG(L_WARN, "sanity_check(): check_expires_value(): parse_expires failed\n");
00522 return SANITY_CHECK_FAILED;
00523 }
00524 if (((struct exp_body*)_msg->expires->parsed)->text.len == 0) {
00525 if (_msg->REQ_METHOD != METHOD_ACK) {
00526 if (sl.reply(_msg, 400, "Missing number in Expires header") == -1) {
00527 LOG(L_WARN, "sanity_check(): check_expires_value(): failed to send 400 via send_reply\n");
00528 }
00529 }
00530 DBG("check_expires_value failed\n");
00531 return SANITY_CHECK_FAILED;
00532 }
00533 if (str2valid_uint(&((struct exp_body*)_msg->expires->parsed)->text, &expires) != 0) {
00534 if (_msg->REQ_METHOD != METHOD_ACK) {
00535 if (sl.reply(_msg, 400, "Expires value is illegal") == -1) {
00536 LOG(L_WARN, "sanity_check(): check_expires_value(): failed to send 400 via send_reply 2\n");
00537 }
00538 }
00539 DBG("check_expires_value failed\n");
00540 return SANITY_CHECK_FAILED;
00541 }
00542 #ifdef EXTRA_DEBUG
00543 DBG("check_expires_value passed\n");
00544 #endif
00545 }
00546 #ifdef EXTRA_DEBUG
00547 else {
00548 DBG("check_expires_value(): no expires header found\n");
00549 }
00550 #endif
00551
00552 return SANITY_CHECK_PASSED;
00553 }
00554
00555
00556 int check_proxy_require(struct sip_msg* _msg) {
00557 strl *r_pr, *l_pr;
00558 char *u;
00559 int u_len;
00560
00561 #ifdef EXTRA_DEBUG
00562 DBG("check_proxy_require entered\n");
00563 #endif
00564
00565 if (parse_headers(_msg, HDR_PROXYREQUIRE_F, 0) != 0) {
00566 LOG(L_WARN, "sanity_check(): check_proxy_require(): failed to parse proxy require header\n");
00567 return SANITY_CHECK_FAILED;
00568 }
00569 if (_msg->proxy_require != NULL) {
00570 dump_hdr_field(_msg->proxy_require);
00571 if (_msg->proxy_require->parsed == NULL &&
00572 parse_proxyrequire(_msg->proxy_require) < 0) {
00573 LOG(L_WARN, "sanity_check(): check_proxy_require(): parse_proxy_require failed\n");
00574 return SANITY_CHECK_FAILED;
00575 }
00576 r_pr = _msg->proxy_require->parsed;
00577 while (r_pr != NULL) {
00578 l_pr = proxyrequire_list;
00579 while (l_pr != NULL) {
00580 #ifdef EXTRA_DEBUG
00581 DBG("check_proxy_require(): comparing r='%.*s' l='%.*s'\n", r_pr->string.len, r_pr->string.s, l_pr->string.len, l_pr->string.s);
00582 #endif
00583 if (l_pr->string.len == r_pr->string.len &&
00584
00585 memcmp(l_pr->string.s, r_pr->string.s, l_pr->string.len) == 0) {
00586 break;
00587 }
00588 l_pr = l_pr->next;
00589 }
00590 if (l_pr == NULL) {
00591 DBG("sanit_check(): check_proxy_require(): request contains unsupported extension: %.*s\n", r_pr->string.len, r_pr->string.s);
00592 u_len = UNSUPPORTED_HEADER_LEN + 2 + r_pr->string.len;
00593 u = pkg_malloc(u_len);
00594 if (u == NULL) {
00595 LOG(L_ERR, "sanity_check(): check_proxy_require(): failed to allocate memory for Unsupported header\n");
00596 }
00597 else {
00598 memcpy(u, UNSUPPORTED_HEADER, UNSUPPORTED_HEADER_LEN);
00599 memcpy(u + UNSUPPORTED_HEADER_LEN, r_pr->string.s, r_pr->string.len);
00600 memcpy(u + UNSUPPORTED_HEADER_LEN + r_pr->string.len, CRLF, CRLF_LEN);
00601 add_lump_rpl(_msg, u, u_len, LUMP_RPL_HDR);
00602 }
00603
00604 if (_msg->REQ_METHOD != METHOD_ACK) {
00605 if (sl.reply(_msg, 420, "Bad Extension") == -1) {
00606 LOG(L_WARN, "sanity_check(): check_proxy_require(): failed to send 420 via send_reply\n");
00607 }
00608 }
00609 #ifdef EXTRA_DEBUG
00610 DBG("check_proxy_require failed\n");
00611 #endif
00612 if (u) pkg_free(u);
00613 return SANITY_CHECK_FAILED;
00614 }
00615 else {
00616 r_pr = r_pr->next;
00617 }
00618 }
00619 #ifdef EXTRA_DEBUG
00620 DBG("check_proxy_require passed\n");
00621 #endif
00622 if (_msg->proxy_require->parsed) {
00623
00624
00625
00626 free_str_list(_msg->proxy_require->parsed);
00627 }
00628 }
00629 #ifdef EXTRA_DEBUG
00630 else {
00631 DBG("check_proxy_require(): no proxy-require header found\n");
00632 }
00633 #endif
00634
00635 return SANITY_CHECK_PASSED;
00636 }
00637
00638
00639 int check_parse_uris(struct sip_msg* _msg, int checks) {
00640
00641 struct to_body *ft_body = NULL;
00642 struct sip_uri uri;
00643
00644 #ifdef EXTRA_DEBUG
00645 DBG("check_parse_uris entered\n");
00646 #endif
00647
00648
00649 if (SANITY_URI_CHECK_RURI & checks) {
00650 #ifdef EXTRA_DEBUG
00651 DBG("check_parse_uris(): parsing ruri\n");
00652 #endif
00653 if (_msg->parsed_uri_ok == 0 &&
00654 parse_sip_msg_uri(_msg) != 1) {
00655 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse request uri\n");
00656 if (_msg->REQ_METHOD != METHOD_ACK) {
00657 if (sl.reply(_msg, 400, "Bad Request URI") == -1) {
00658 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad ruri)\n");
00659 }
00660 }
00661 return SANITY_CHECK_FAILED;
00662 }
00663
00664
00665 }
00666
00667 if (SANITY_URI_CHECK_FROM & checks) {
00668 #ifdef EXTRA_DEBUG
00669 DBG("check_parse_uris(): looking up From header\n");
00670 #endif
00671 if ((!_msg->from && parse_headers(_msg, HDR_FROM_F, 0) != 0) || !_msg->from) {
00672 LOG(L_WARN, "sanity_check(): check_parse_uris(): missing from header\n");
00673 if (_msg->REQ_METHOD != METHOD_ACK) {
00674 if (sl.reply(_msg, 400, "Missing From Header") == -1) {
00675 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (missing From)\n");
00676 }
00677 }
00678 return SANITY_CHECK_FAILED;
00679 }
00680 if (!_msg->from->parsed) {
00681 #ifdef EXTRA_DEBUG
00682 DBG("check_parse_uris(): parsing From header\n");
00683 #endif
00684 ft_body = pkg_malloc(sizeof(struct to_body));
00685 if (!ft_body) {
00686 LOG(L_ERR, "sanity_check(): check_parse_uris(): out of pkg_memory (From)\n");
00687 return SANITY_CHECK_ERROR;
00688 }
00689 memset(ft_body, 0, sizeof(struct to_body));
00690 parse_to(_msg->from->body.s, _msg->from->body.s + \
00691 _msg->from->body.len + 1, ft_body);
00692 if (ft_body->error == PARSE_ERROR) {
00693 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse From header\n");
00694 pkg_free(ft_body);
00695 if (_msg->REQ_METHOD != METHOD_ACK) {
00696 if (sl.reply(_msg, 400, "Bad From header") == -1) {
00697 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad from header)\n");
00698 }
00699 }
00700 return SANITY_CHECK_FAILED;
00701 }
00702 _msg->from->parsed = ft_body;
00703 ft_body = NULL;
00704 }
00705 if (((struct to_body*)_msg->from->parsed)->uri.s) {
00706 #ifdef EXTRA_DEBUG
00707 DBG("check_parse_uris(): parsing From URI\n");
00708 #endif
00709 if (parse_uri(((struct to_body*)_msg->from->parsed)->uri.s,
00710 ((struct to_body*)_msg->from->parsed)->uri.len, &uri) != 0) {
00711 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse From uri\n");
00712 if (_msg->REQ_METHOD != METHOD_ACK) {
00713 if (sl.reply(_msg, 400, "Bad From URI") == -1) {
00714 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad from uri)\n");
00715 }
00716 }
00717 return SANITY_CHECK_FAILED;
00718 }
00719
00720
00721
00722
00723 }
00724 }
00725
00726 if (SANITY_URI_CHECK_TO & checks) {
00727 #ifdef EXTRA_DEBUG
00728 DBG("check_parse_uris(): looking up To header\n");
00729 #endif
00730 if ((!_msg->to && parse_headers(_msg, HDR_TO_F, 0) != 0) || !_msg->to) {
00731 LOG(L_WARN, "sanity_check(): check_parse_uris(): missing to header\n");
00732 if (_msg->REQ_METHOD != METHOD_ACK) {
00733 if (sl.reply(_msg, 400, "Missing To Header") == -1) {
00734 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (missing To)\n");
00735 }
00736 }
00737 return SANITY_CHECK_FAILED;
00738 }
00739
00740 if (!_msg->to->parsed) {
00741 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse To header\n");
00742 if (_msg->REQ_METHOD != METHOD_ACK) {
00743 if (sl.reply(_msg, 400, "Bad To URI") == -1) {
00744 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad to uri)\n");
00745 }
00746 }
00747 return SANITY_CHECK_FAILED;
00748 }
00749 if (((struct to_body*)_msg->to->parsed)->uri.s) {
00750 #ifdef EXTRA_DEBUG
00751 DBG("check_parse_uris(): parsing To URI\n");
00752 #endif
00753 if (parse_uri(((struct to_body*)_msg->to->parsed)->uri.s,
00754 ((struct to_body*)_msg->to->parsed)->uri.len, &uri) != 0) {
00755 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse To uri\n");
00756 if (_msg->REQ_METHOD != METHOD_ACK) {
00757 if (sl.reply(_msg, 400, "Bad To URI") == -1) {
00758 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad to uri)\n");
00759 }
00760 }
00761 return SANITY_CHECK_FAILED;
00762 }
00763
00764
00765
00766
00767 }
00768 }
00769
00770 if (SANITY_URI_CHECK_CONTACT & checks) {
00771 #ifdef EXTRA_DEBUG
00772 DBG("check_parse_uris(): looking up Contact header\n");
00773 #endif
00774 if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0) || !_msg->contact) {
00775 LOG(L_WARN, "sanity_check(): check_parse_uris(): missing contact header\n");
00776 }
00777 if (_msg->contact) {
00778 #ifdef EXTRA_DEBUG
00779 DBG("check_parse_uris(): parsing Contact header\n");
00780 #endif
00781 if (parse_contact(_msg->contact) < 0) {
00782 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse Contact header\n");
00783 if (_msg->REQ_METHOD != METHOD_ACK) {
00784 if (sl.reply(_msg, 400, "Bad Contact Header") == -1) {
00785 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad Contact)\n");
00786 }
00787 }
00788 return SANITY_CHECK_FAILED;
00789 }
00790 if (parse_uri(((struct contact_body*)_msg->contact->parsed)->contacts->uri.s,
00791 ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len, &uri) != 0) {
00792 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse Contact uri\n");
00793 if (_msg->REQ_METHOD != METHOD_ACK) {
00794 if (sl.reply(_msg, 400, "Bad Contact URI") == -1) {
00795 LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to send 400 via send_reply (bad Contact uri)\n");
00796 }
00797 }
00798 return SANITY_CHECK_FAILED;
00799 }
00800 }
00801 }
00802
00803 #ifdef EXTRA_DEBUG
00804 DBG("check_parse_uris passed\n");
00805 #endif
00806 return SANITY_CHECK_PASSED;
00807 }
00808
00809
00810
00811
00812
00813 int check_digest(struct sip_msg* msg, int checks)
00814 {
00815 struct hdr_field* ptr;
00816 dig_cred_t* cred;
00817 int ret;
00818 int hf_type;
00819
00820 if (parse_headers(msg, HDR_EOH_F, 0) != 0) {
00821 LOG(L_ERR, "sanity_check(): check_digest: failed to parse proxy require header\n");
00822 return SANITY_CHECK_FAILED;
00823 }
00824
00825 if (!msg->authorization && !msg->proxy_auth) {
00826 #ifdef EXTRA_DEBUG
00827 DBG("sanity_check(): check_digest: Nothing to check\n");
00828 #endif
00829 return SANITY_CHECK_PASSED;
00830 }
00831
00832 if (msg->authorization) {
00833 hf_type = HDR_AUTHORIZATION_T;
00834 ptr = msg->authorization;
00835 } else {
00836 hf_type = HDR_PROXYAUTH_T;
00837 ptr = msg->proxy_auth;
00838 }
00839 while(ptr) {
00840 if ((ret = parse_credentials(ptr)) != 0) {
00841 DBG("sanity_check(): check_digest: Cannot parse credentials: %d\n", ret);
00842 return SANITY_CHECK_FAILED;
00843 }
00844
00845 cred = &((auth_body_t*)ptr->parsed)->digest;
00846
00847 if (check_dig_cred(cred) != E_DIG_OK) {
00848 #ifdef EXTRA_DEBUG
00849 DBG("sanity_check(): check_digest: Digest credentials malformed\n");
00850 #endif
00851 return SANITY_CHECK_FAILED;
00852 }
00853
00854 if (cred->username.whole.len == 0) {
00855 #ifdef EXTRA_DEBUG
00856 DBG("sanity_check(): check_digest: Empty username\n");
00857 #endif
00858 return SANITY_CHECK_FAILED;
00859 }
00860
00861 if (cred->nonce.len == 0) {
00862 #ifdef EXTRA_DEBUG
00863 DBG("sanity_check(): check_digest: Empty nonce attribute\n");
00864 #endif
00865 return SANITY_CHECK_FAILED;
00866 }
00867
00868 if (cred->response.len == 0) {
00869 #ifdef EXTRA_DEBUG
00870 DBG("sanity_check(): check_digest: Empty response attribute\n");
00871 #endif
00872 return SANITY_CHECK_FAILED;
00873 }
00874
00875 do {
00876 ptr = ptr->next;
00877 } while(ptr && ptr->type != hf_type);
00878
00879 if (!ptr && hf_type == HDR_AUTHORIZATION_T) {
00880 hf_type = HDR_PROXYAUTH_T;
00881 ptr = msg->proxy_auth;
00882 }
00883 }
00884
00885 return SANITY_CHECK_PASSED;
00886 }