everything: shotgun attempt to put PROTO_WS and PROTO_WSS across core and in modules...
[sip-router] / modules / sanity / sanity.c
1 /*
2  * $Id$
3  *
4  * Sanity Checks Module
5  *
6  * Copyright (C) 2006 iptelorg GbmH
7  *
8  * This file is part of ser, a free SIP server.
9  *
10  * ser is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * For a license to use the ser software under conditions
16  * other than those described here, or to purchase support for this
17  * software, please contact iptel.org by e-mail at the following addresses:
18  *    info@iptel.org
19  *
20  * ser is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28  *
29  */
30
31 #include "mod_sanity.h"
32 #include "sanity.h"
33 #include "../../ut.h"
34 #include "../../trim.h"
35 #include "../../data_lump_rpl.h"
36 #include "../../mem/mem.h"
37 #include "../../parser/parse_uri.h"
38 #include "../../parser/parse_expires.h"
39 #include "../../parser/parse_content.h"
40 #include "../../parser/digest/digest.h"
41 #include "../../parser/contact/parse_contact.h"
42 #include "../../parser/parse_to.h"
43 #include "../../parser/parse_from.h"
44
45 #define UNSUPPORTED_HEADER "Unsupported: "
46 #define UNSUPPORTED_HEADER_LEN (sizeof(UNSUPPORTED_HEADER)-1)
47
48
49 /**
50  * wrapper to SL send reply function
51  * - check if it is the case for sending a reply before doing it
52  */
53 int sanity_reply(sip_msg_t *msg, int code, char *reason)
54 {
55         if(msg->first_line.type == SIP_REPLY) {
56                 return 1;
57         }
58
59         if(msg->REQ_METHOD == METHOD_ACK) {
60                 return 1;
61         }
62         if(slb.zreply(msg, code, reason) < 0) {
63                 return -1;
64         }
65         return 0;
66 }
67
68 /* check if the given string is a valid unsigned int value */
69 int str2valid_uint(str* _number, unsigned int* _result) {
70         int i;
71         int result= 0;
72         int equal = 1;
73         char mui[10] = "4294967296";
74
75         *_result = 0;
76         if (_number->len > 10) {
77 #ifdef EXTRA_DEBUG
78                 DBG("valid_uint(): number is too long\n");
79 #endif
80                 return -1;
81         }
82         if (_number->len < 10) {
83                 equal = 0;
84         }
85         for (i=0; i < _number->len; i++) {
86                 if (_number->s[i] < '0' || _number->s[i] > '9') {
87 #ifdef EXTRA_DEBUG
88                         DBG("valid_uint(): number contains non-number char\n");
89 #endif
90                         return -1;
91                 }
92                 if (equal == 1) {
93                         if (_number->s[i] < mui[i]) {
94                                 equal = 0;
95                         }
96                         else if (_number->s[i] > mui[i]) {
97 #ifdef EXTRA_DEBUG
98                                 DBG("valid_uint(): number exceeds uint\n");
99 #endif
100                                 return -1;
101                         }
102                 }
103                 result *= 10;
104                 result += _number->s[i] - '0';
105         }
106         *_result = result;
107         return 0;
108 }
109
110 /* parses the given comma seperated string into a string list */
111 strl* parse_str_list(str* _string) {
112         str input;
113         strl *parsed_list, *pl;
114         char *comma;
115
116         /* make a copy because we trim it */
117         input.s = _string->s;
118         input.len = _string->len;
119
120         trim(&input);
121
122         if (input.len == 0) {
123 #ifdef EXTRA_DEBUG
124                 DBG("parse_str_list: list is empty\n");
125 #endif
126                 return NULL;
127         }
128         parsed_list = pkg_malloc(sizeof(strl));
129         if (parsed_list == NULL) {
130                 LOG(L_ERR, "parse_str_list: OUT OF MEMORY for initial list element\n");
131                 return NULL;
132         }
133         memset(parsed_list, 0, sizeof(strl));
134         parsed_list->string.s = input.s;
135         parsed_list->string.len = input.len;
136
137         comma = q_memchr(input.s, ',', input.len);
138         pl = parsed_list;
139         while (comma != NULL) {
140                 pl->next = pkg_malloc(sizeof(strl));
141                 if (pl->next == NULL) {
142                         LOG(L_ERR, "parse_str_list: OUT OF MEMORY for further list"
143                                         " element\n");
144                         return parsed_list;
145                 }
146                 memset(pl->next, 0, sizeof(strl));
147                 pl->next->string.s = comma + 1;
148                 pl->next->string.len = pl->string.len
149                                                                         - (pl->next->string.s - pl->string.s);
150                 pl->string.len = comma - pl->string.s;
151                 trim_trailing(&(pl->string));
152                 pl = pl->next;
153                 trim_leading(&(pl->string));
154                 comma = q_memchr(pl->string.s, ',', pl->string.len);
155         }
156
157         return parsed_list;
158 }
159
160 /* free the elements of the linked str list */
161 void free_str_list(strl *_list) {
162         strl *cur, *next;
163
164         if (_list != NULL) {
165                 cur = _list;
166                 while (cur != NULL) {
167                         next = cur->next;
168                         pkg_free(cur);
169                         cur = next;
170                 }
171         }
172 }
173
174 int parse_proxyrequire(struct hdr_field* _h) {
175         strl *pr_l;
176
177         if (_h->parsed) {
178                 return 0; /* Already parsed */
179         }
180
181         if ((pr_l = parse_str_list(&(_h->body))) == NULL) {
182                 LOG(L_ERR, "parse_proxy_require(): Error while parsing\n");
183                 return -1;
184         }
185
186         _h->parsed = pr_l;
187         return 0;
188 }
189
190 /* check the SIP version in the request URI */
191 int check_ruri_sip_version(struct sip_msg* _msg) {
192         char *sep;
193         str version;
194
195 #ifdef EXTRA_DEBUG
196         DBG("check_ruri_sip_version entered\n");
197 #endif
198
199         if (_msg->first_line.u.request.version.len != 0) {
200                 sep = q_memchr(_msg->first_line.u.request.version.s, '/',
201                                                 _msg->first_line.u.request.version.len);
202                 if (sep == NULL) {
203                         LOG(L_WARN, "sanity_check(): check_ruri_sip_version():"
204                                         " failed to find / in ruri version\n");
205                         return SANITY_CHECK_FAILED;
206                 }
207                 version.s = sep + 1;
208                 version.len = _msg->first_line.u.request.version.len - (version.s - _msg->first_line.u.request.version.s);
209
210                 if (version.len != SIP_VERSION_TWO_POINT_ZERO_LENGTH ||
211                         (memcmp(version.s, SIP_VERSION_TWO_POINT_ZERO, 
212                                 SIP_VERSION_TWO_POINT_ZERO_LENGTH) != 0)) {
213                         if (_msg->REQ_METHOD != METHOD_ACK) {
214                                 if (sanity_reply(_msg, 505, "Version Not Supported (R-URI)")
215                                                 < 0) {
216                                         LOG(L_WARN, "sanity_check(): check_ruri_sip_version():"
217                                                         " failed to send 505 via sl reply\n");
218                                 }
219                         }
220 #ifdef EXTRA_DEBUG
221                         DBG("check_ruri_sip_version failed\n");
222 #endif
223                         return SANITY_CHECK_FAILED;
224                 }
225         }
226 #ifdef EXTRA_DEBUG
227         DBG("check_ruri_sip_version passed\n");
228 #endif
229         return SANITY_CHECK_PASSED;
230 }
231
232 /* check if the r-uri scheme */
233 int check_ruri_scheme(struct sip_msg* _msg) {
234
235 #ifdef EXTRA_DEBUG
236         DBG("check_ruri_scheme entered\n");
237 #endif
238
239         if (_msg->parsed_uri_ok == 0 &&
240                         parse_sip_msg_uri(_msg) != 1) {
241                 /* unsupported schemes end up here already */
242                 LM_WARN("failed to parse request uri [%.*s]\n",
243                                 GET_RURI(_msg)->len, GET_RURI(_msg)->s);
244         }
245         if (_msg->parsed_uri.type == ERROR_URI_T) {
246                 if (_msg->REQ_METHOD != METHOD_ACK) {
247                         if (sanity_reply(_msg, 416, "Unsupported URI Scheme in Request URI")
248                                         < 0) {
249                                 LOG(L_WARN, "sanity_check(): check_ruri_scheme():"
250                                                 " failed to send 416 via sl reply\n");
251                         }
252                 }
253                 DBG("check_ruri_scheme failed\n");
254                 return SANITY_CHECK_FAILED;
255         }
256 #ifdef EXTRA_DEBUG
257         DBG("check_ruri_scheme passed\n");
258 #endif
259
260         return SANITY_CHECK_PASSED;
261 }
262
263 /* check for the presence of the minimal required headers */
264 int check_required_headers(struct sip_msg* _msg) {
265
266 #ifdef EXTRA_DEBUG
267         DBG("check_required_headers entered\n");
268 #endif
269
270         if (!check_transaction_quadruple(_msg)) {
271                 if (_msg->REQ_METHOD != METHOD_ACK) {
272                         if (sanity_reply(_msg, 400, "Missing Required Header in Request")
273                                         < 0) {
274                                 LOG(L_WARN, "sanity_check(): check_required_headers():"
275                                                 " failed to send 400 via sl reply\n");
276                         }
277                 }
278                 DBG("check_required_headers failed\n");
279                 return SANITY_CHECK_FAILED;
280         }
281         /* TODO: check for other required headers according to request type */
282 #ifdef EXTRA_DEBUG
283         DBG("check_required_headers passed\n");
284 #endif
285
286         return SANITY_CHECK_PASSED;
287 }
288
289 /* check if the SIP version in the Via header is 2.0 */
290 int check_via_sip_version(struct sip_msg* _msg) {
291
292         DBG("sanity_check(): check_via_sip_version(): this is a useless check"
293                         " for now; check the source code comments for details\n");
294         return SANITY_CHECK_PASSED;
295
296         /* FIMXE the Via parser fails already on non-2.0 versions
297          * thus this check makes no sence yet
298         DBG("check_via_sip_version entered\n");
299
300         // FIXME via parser fails on non 2.0 number
301         if (parse_headers(_msg, HDR_VIA1_F, 0) != 0) {
302                 LOG(L_WARN, "sanity_check(): check_via_sip_version():"
303                         " failed to parse the first Via header\n");
304                 return SANITY_CHECK_FAILED;
305         }
306
307         if (_msg->via1->version.len != 3 ||
308                         memcmp(_msg->via1->version.s, SIP_VERSION_TWO_POINT_ZERO, 
309                                         SIP_VERSION_TWO_POINT_ZERO_LENGTH ) != 0) {
310                 if (_msg->REQ_METHOD != METHOD_ACK) {
311                         if (sanity_reply(_msg, 505, "Version Not Supported (Via)") < 0) {
312                                 LOG(L_WARN, "sanity_check(): check_via_sip_version():"
313                                         " failed to send 505 via sl reply\n");
314                         }
315                 }
316                 DBG("check_via_sip_version failed\n");
317                 return SANITY_CHECK_FAILED;
318         }
319 #ifdef EXTRA_DEBUG
320         DBG("check_via_sip_version passed\n");
321 #endif
322
323         return SANITY_CHECK_PASSED;
324         */
325 }
326
327 /* compare the protocol string in the Via header with the transport */
328 int check_via_protocol(struct sip_msg* _msg) {
329
330         DBG("sanity_check(): check_via_protocol(): this is a useless check"
331                         " for now; check the source code comment for details\n");
332         return SANITY_CHECK_PASSED;
333
334         /* FIXME as the Via parser fails already on unknown transports
335          * this function makes no sence yet
336         DBG("check_via_protocol entered\n");
337
338         // FIXME via parser fails on unknown transport
339         if (parse_headers(_msg, HDR_VIA1_F, 0) != 0) {
340                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
341                         " failed to parse the first Via header\n");
342                 return SANITY_CHECK_FAILED;
343         }
344         if (_msg->via1->transport.len != 3 &&
345                         _msg->via1->transport.len != 4) {
346                 if (_msg->REQ_METHOD != METHOD_ACK) {
347                         if (sanity_reply(_msg, 400, "Unsupported Transport in Topmost Via")
348                                         < 0) {
349                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
350                                         " failed to send 400 via sl reply\n");
351                         }
352                 }
353                 DBG("check_via_protocol failed\n");
354                 return SANITY_CHECK_FAILED;
355         }
356         switch (_msg->rcv.proto) {
357                 case PROTO_UDP:
358                         if (memcmp(_msg->via1->transport.s, "UDP", 3) != 0) {
359                                 if (_msg->REQ_METHOD != METHOD_ACK) {
360                                         if (sanity_reply(_msg, 400,
361                                                         "Transport Missmatch in Topmost Via") < 0) {
362                                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
363                                                                 " failed to send 505 via sl reply\n");
364                                         }
365                                 }
366                                 DBG("check_via_protocol failed\n");
367                                 return SANITY_CHECK_FAILED;
368                         }
369                         break;
370                 case PROTO_TCP:
371                         if (memcmp(_msg->via1->transport.s, "TCP", 3) != 0) {
372                                 if (_msg->REQ_METHOD != METHOD_ACK) {
373                                         if (sanity_reply(_msg, 400,
374                                                         "Transport Missmatch in Topmost Via") < 0) {
375                                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
376                                                                 " failed to send 505 via sl reply\n");
377                                         }
378                                 }
379                                 DBG("check_via_protocol failed\n");
380                                 return SANITY_CHECK_FAILED;
381                         }
382                         break;
383                 case PROTO_TLS:
384                         if (memcmp(_msg->via1->transport.s, "TLS", 3) != 0) {
385                                 if (_msg->REQ_METHOD != METHOD_ACK) {
386                                         if (sanity_reply(_msg, 400,
387                                                         "Transport Missmatch in Topmost Via") < 0) {
388                                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
389                                                                 " failed to send 505 via sl reply\n");
390                                         }
391                                 }
392                                 DBG("check_via_protocol failed\n");
393                                 return SANITY_CHECK_FAILED;
394                         }
395                         break;
396                 case PROTO_SCTP:
397                         if (memcmp(_msg->via1->transport.s, "SCTP", 4) != 0) {
398                                 if (_msg->REQ_METHOD != METHOD_ACK) {
399                                         if (sanity_reply(_msg, 400,
400                                                         "Transport Missmatch in Topmost Via") < 0) {
401                                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
402                                                                 " failed to send 505 via sl reply\n");
403                                         }
404                                 }
405                                 DBG("check_via_protocol failed\n");
406                                 return SANITY_CHECK_FAILED;
407                         }
408                         break;
409                 case PROTO_WS:
410                         if (memcmp(_msg->via1->transport.s, "WS", 2) != 0) {
411                                 if (_msg->REQ_METHOD != METHOD_ACK) {
412                                         if (sanity_reply(_msg, 400,
413                                                         "Transport Missmatch in Topmost Via") < 0) {
414                                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
415                                                                 " failed to send 505 via sl reply\n");
416                                         }
417                                 }
418                                 DBG("check_via_protocol failed\n");
419                                 return SANITY_CHECK_FAILED;
420                         }
421                         break;
422                 case PROTO_WSS:
423                         if (memcmp(_msg->via1->transport.s, "WSS", 3) != 0) {
424                                 if (_msg->REQ_METHOD != METHOD_ACK) {
425                                         if (sanity_reply(_msg, 400,
426                                                         "Transport Missmatch in Topmost Via") < 0) {
427                                                 LOG(L_WARN, "sanity_check(): check_via_protocol():"
428                                                                 " failed to send 505 via sl reply\n");
429                                         }
430                                 }
431                                 DBG("check_via_protocol failed\n");
432                                 return SANITY_CHECK_FAILED;
433                         }
434                         break;
435                 default:
436                         LOG(L_WARN, "sanity_check(): check_via_protocol():"
437                                         " unknown protocol in received structure\n");
438                         return SANITY_CHECK_FAILED;
439         }
440 #ifdef EXTRA_DEBUG
441         DBG("check_via_protocol passed\n");
442 #endif
443
444         return SANITY_CHECK_PASSED;
445         */
446 }
447
448 /* compare the method in the CSeq header with the request line value */
449 int check_cseq_method(struct sip_msg* _msg) {
450
451 #ifdef EXTRA_DEBUG
452         DBG("check_cseq_method entered\n");
453 #endif
454
455         if (parse_headers(_msg, HDR_CSEQ_F, 0) != 0) {
456                 LOG(L_WARN, "sanity_check(): check_cseq_method():"
457                                 " failed to parse the CSeq header\n");
458                 return SANITY_CHECK_FAILED;
459         }
460         if (_msg->cseq != NULL && _msg->cseq->parsed != NULL) {
461                 if (((struct cseq_body*)_msg->cseq->parsed)->method.len == 0) {
462                         if (_msg->REQ_METHOD != METHOD_ACK) {
463                                 if (sanity_reply(_msg, 400, "Missing method in CSeq header")
464                                                 < 0) {
465                                         LOG(L_WARN, "sanity_check(): check_cseq_method():"
466                                                         " failed to send 400 via sl reply\n");
467                                 }
468                         }
469                         DBG("check_cseq_method failed (missing method)\n");
470                         return SANITY_CHECK_FAILED;
471                 }
472
473                 if (((struct cseq_body*)_msg->cseq->parsed)->method.len != 
474                                         _msg->first_line.u.request.method.len ||
475                         memcmp(((struct cseq_body*)_msg->cseq->parsed)->method.s, 
476                                 _msg->first_line.u.request.method.s,
477                                 ((struct cseq_body*)_msg->cseq->parsed)->method.len) != 0) {
478                         if (_msg->REQ_METHOD != METHOD_ACK) {
479                                 if (sanity_reply(_msg, 400,
480                                                         "CSeq method does not match request method") < 0) {
481                                         LOG(L_WARN, "sanity_check(): check_cseq_method():"
482                                                         " failed to send 400 via sl reply 2\n");
483                                 }
484                         }
485                         DBG("check_cseq_method failed (non-equal method)\n");
486                         return SANITY_CHECK_FAILED;
487                 }
488         }
489         else {
490                 LOG(L_WARN, "sanity_check(): check_cseq_method():"
491                                 " missing CSeq header\n");
492                 return SANITY_CHECK_FAILED;
493         }
494 #ifdef EXTRA_DEBUG
495         DBG("check_cseq_method passed\n");
496 #endif
497
498         return SANITY_CHECK_PASSED;
499 }
500
501 /* check the number within the CSeq header */
502 int check_cseq_value(struct sip_msg* _msg) {
503         unsigned int cseq;
504
505 #ifdef EXTRA_DEBUG
506         DBG("check_cseq_value entered\n");
507 #endif
508
509         if (parse_headers(_msg, HDR_CSEQ_F, 0) != 0) {
510                 LOG(L_WARN, "sanity_check(): check_cseq_value():"
511                                 " failed to parse the CSeq header\n");
512                 return SANITY_CHECK_FAILED;
513         }
514         if (_msg->cseq != NULL && _msg->cseq->parsed != NULL) {
515                 if (((struct cseq_body*)_msg->cseq->parsed)->number.len == 0) {
516                         if (_msg->REQ_METHOD != METHOD_ACK) {
517                                 if (sanity_reply(_msg, 400, "Missing number in CSeq header")
518                                                 < 0) {
519                                         LOG(L_WARN, "sanity_check(): check_cseq_value():"
520                                                         " failed to send 400 via sl reply\n");
521                                 }
522                         }
523                         return SANITY_CHECK_FAILED;
524                 }
525                 if (str2valid_uint(&((struct cseq_body*)_msg->cseq->parsed)->number,
526                                         &cseq) != 0) {
527                         if (_msg->REQ_METHOD != METHOD_ACK) {
528                                 if (sanity_reply(_msg, 400, "CSeq number is illegal") < 0) {
529                                         LOG(L_WARN, "sanity_check(): check_cseq_value():"
530                                                         " failed to send 400 via sl reply 2\n");
531                                 }
532                         }
533                         DBG("check_cseq_value failed\n");
534                         return SANITY_CHECK_FAILED;
535                 }
536         }
537         else {
538                 LOG(L_WARN, "sanity_check(): check_cseq_method():"
539                                 " missing CSeq header\n");
540                 return SANITY_CHECK_FAILED;
541         }
542 #ifdef EXTRA_DEBUG
543         DBG("check_cseq_value passed\n");
544 #endif
545
546         return SANITY_CHECK_PASSED;
547 }
548
549 /* compare the Content-Length value with the accutal body length */
550 int check_cl(struct sip_msg* _msg) {
551         char *body;
552
553 #ifdef EXTRA_DEBUG
554         DBG("check_cl entered\n");
555 #endif
556
557         if (parse_headers(_msg, HDR_CONTENTLENGTH_F, 0) != 0) {
558                 LOG(L_WARN, "sanity_check(): check_cl():"
559                                 " failed to parse content-length header\n");
560                 return SANITY_CHECK_FAILED;
561         }
562         if (_msg->content_length != NULL) {
563                 //dump_hdr_field(_msg->content_length);
564                 if ((body = get_body(_msg)) == NULL) {
565 #ifdef EXTRA_DEBUG
566                         DBG("check_cl(): no body\n");
567 #endif
568                         return SANITY_CHECK_FAILED;
569                 }
570                 if ((_msg->len - (body - _msg->buf)) != get_content_length(_msg)) {
571                         if (_msg->REQ_METHOD != METHOD_ACK) {
572                                 if (sanity_reply(_msg, 400, "Content-Length mis-match") < 0) {
573                                         LOG(L_WARN, "sanity_check(): check_cl():"
574                                                         " failed to send 400 via sl reply\n");
575                                 }
576                         }
577                         DBG("check_cl failed\n");
578                         return SANITY_CHECK_FAILED;
579                 }
580 #ifdef EXTRA_DEBUG
581                 DBG("check_cl passed\n");
582 #endif
583         }
584 #ifdef EXTRA_DEBUG
585         else {
586                 WARN("check_cl(): content length header missing in request\n");
587         }
588 #endif
589
590         return SANITY_CHECK_PASSED;
591 }
592
593 /* check the number within the Expires header */
594 int check_expires_value(struct sip_msg* _msg) {
595         unsigned int expires;
596
597 #ifdef EXTRA_DEBUG
598         DBG("check_expires_value entered\n");
599 #endif
600
601         if (parse_headers(_msg, HDR_EXPIRES_F, 0) != 0) {
602                 LOG(L_WARN, "sanity_check(): check_expires_value():"
603                                 " failed to parse expires header\n");
604                 return SANITY_CHECK_FAILED;
605         }
606         if (_msg->expires != NULL) {
607                 //dump_hdr_field(_msg->expires);
608                 if (_msg->expires->parsed == NULL &&
609                                 parse_expires(_msg->expires) < 0) {
610                         LOG(L_WARN, "sanity_check(): check_expires_value():"
611                                         " parse_expires failed\n");
612                         return SANITY_CHECK_FAILED;
613                 }
614                 if (((struct exp_body*)_msg->expires->parsed)->text.len == 0) {
615                         if (_msg->REQ_METHOD != METHOD_ACK) {
616                                 if (sanity_reply(_msg, 400, "Missing number in Expires header")
617                                                 < 0) {
618                                         LOG(L_WARN, "sanity_check(): check_expires_value():"
619                                                         " failed to send 400 via sl reply\n");
620                                 }
621                         }
622                         DBG("check_expires_value failed\n");
623                         return SANITY_CHECK_FAILED;
624                 }
625                 if (str2valid_uint(&((struct exp_body*)_msg->expires->parsed)->text, &expires) != 0) {
626                         if (_msg->REQ_METHOD != METHOD_ACK) {
627                                 if (sanity_reply(_msg, 400, "Expires value is illegal") < 0) {
628                                         LOG(L_WARN, "sanity_check(): check_expires_value():"
629                                                         " failed to send 400 via sl reply 2\n");
630                                 }
631                         }
632                         DBG("check_expires_value failed\n");
633                         return SANITY_CHECK_FAILED;
634                 }
635 #ifdef EXTRA_DEBUG
636                 DBG("check_expires_value passed\n");
637 #endif
638         }
639 #ifdef EXTRA_DEBUG
640         else {
641                 DBG("check_expires_value(): no expires header found\n");
642         }
643 #endif
644
645         return SANITY_CHECK_PASSED;
646 }
647
648 /* check the content of the Proxy-Require header */
649 int check_proxy_require(struct sip_msg* _msg) {
650         strl *r_pr, *l_pr;
651         char *u;
652         int u_len;
653
654 #ifdef EXTRA_DEBUG
655         DBG("check_proxy_require entered\n");
656 #endif
657
658         if (parse_headers(_msg, HDR_PROXYREQUIRE_F, 0) != 0) {
659                 LOG(L_WARN, "sanity_check(): check_proxy_require():"
660                                 " failed to parse proxy require header\n");
661                 return SANITY_CHECK_FAILED;
662         }
663         if (_msg->proxy_require != NULL) {
664                 dump_hdr_field(_msg->proxy_require);
665                 if (_msg->proxy_require->parsed == NULL &&
666                                 parse_proxyrequire(_msg->proxy_require) < 0) {
667                         LOG(L_WARN, "sanity_check(): check_proxy_require(): parse_proxy_require failed\n");
668                         return SANITY_CHECK_FAILED;
669                 }
670                 r_pr = _msg->proxy_require->parsed;
671                 while (r_pr != NULL) {
672                         l_pr = proxyrequire_list;
673                         while (l_pr != NULL) {
674 #ifdef EXTRA_DEBUG
675                                 DBG("check_proxy_require(): comparing r='%.*s' l='%.*s'\n",
676                                                 r_pr->string.len, r_pr->string.s, l_pr->string.len,
677                                                 l_pr->string.s);
678 #endif
679                                 if (l_pr->string.len == r_pr->string.len &&
680                                                 /* FIXME tokens are case in-sensitive */
681                                                 memcmp(l_pr->string.s, r_pr->string.s,
682                                                                 l_pr->string.len) == 0) {
683                                         break;
684                                 }
685                                 l_pr = l_pr->next;
686                         }
687                         if (l_pr == NULL) {
688                                 DBG("sanit_check(): check_proxy_require():"
689                                                 " request contains unsupported extension: %.*s\n",
690                                                 r_pr->string.len, r_pr->string.s);
691                                 u_len = UNSUPPORTED_HEADER_LEN + 2 + r_pr->string.len;
692                                 u = pkg_malloc(u_len);
693                                 if (u == NULL) {
694                                         LOG(L_ERR, "sanity_check(): check_proxy_require():"
695                                                         " failed to allocate memory for"
696                                                         " Unsupported header\n");
697                                 }
698                                 else {
699                                         memcpy(u, UNSUPPORTED_HEADER, UNSUPPORTED_HEADER_LEN);
700                                         memcpy(u + UNSUPPORTED_HEADER_LEN, r_pr->string.s,
701                                                         r_pr->string.len);
702                                         memcpy(u + UNSUPPORTED_HEADER_LEN + r_pr->string.len,
703                                                         CRLF, CRLF_LEN);
704                                         add_lump_rpl(_msg, u, u_len, LUMP_RPL_HDR);
705                                 }
706
707                                 if (_msg->REQ_METHOD != METHOD_ACK) {
708                                         if (sanity_reply(_msg, 420, "Bad Extension") < 0) {
709                                                 LOG(L_WARN, "sanity_check(): check_proxy_require():"
710                                                                 " failed to send 420 via sl reply\n");
711                                         }
712                                 }
713 #ifdef EXTRA_DEBUG
714                                 DBG("check_proxy_require failed\n");
715 #endif
716                                 if (u) pkg_free(u);
717                                 return SANITY_CHECK_FAILED;
718                         }
719                         else {
720                                 r_pr = r_pr->next;
721                         }
722                 }
723 #ifdef EXTRA_DEBUG
724                 DBG("check_proxy_require passed\n");
725 #endif
726                 if (_msg->proxy_require->parsed) {
727                         /* TODO we have to free it here, because it is not automatically
728                          * freed when the message freed. Lets hope nobody needs to access
729                          * this header again later on */
730                         free_str_list(_msg->proxy_require->parsed);
731                 }
732         }
733 #ifdef EXTRA_DEBUG
734         else {
735                 DBG("check_proxy_require(): no proxy-require header found\n");
736         }
737 #endif
738
739         return SANITY_CHECK_PASSED;
740 }
741
742 /* check if the typical URI's are parseable */
743 int check_parse_uris(struct sip_msg* _msg, int checks) {
744
745         struct to_body *ft_body = NULL;
746         struct sip_uri uri;
747
748 #ifdef EXTRA_DEBUG
749         DBG("check_parse_uris entered\n");
750 #endif
751
752         /* check R-URI */
753         if (SANITY_URI_CHECK_RURI & checks) {
754 #ifdef EXTRA_DEBUG
755                 DBG("check_parse_uris(): parsing ruri\n");
756 #endif
757                 if (_msg->parsed_uri_ok == 0 &&
758                                 parse_sip_msg_uri(_msg) != 1) {
759                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
760                                         " failed to parse request uri\n");
761                         if (_msg->REQ_METHOD != METHOD_ACK) {
762                                 if (sanity_reply(_msg, 400, "Bad Request URI") < 0) {
763                                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
764                                                         " failed to send 400 via sl reply (bad ruri)\n");
765                                 }
766                         }
767                         return SANITY_CHECK_FAILED;
768                 }
769                 /* FIXME: would it make sense to check here for "mandatory"
770                  * or "requested" parts of the URI? */
771         }
772         /* check From URI */
773         if (SANITY_URI_CHECK_FROM & checks) {
774 #ifdef EXTRA_DEBUG
775                 DBG("check_parse_uris(): looking up From header\n");
776 #endif
777                 if ((!_msg->from && parse_headers(_msg, HDR_FROM_F, 0) != 0)
778                                 || !_msg->from) {
779                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
780                                         " missing from header\n");
781                         if (_msg->REQ_METHOD != METHOD_ACK) {
782                                 if (sanity_reply(_msg, 400, "Missing From Header") < 0) {
783                                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
784                                                 " failed to send 400 via sl reply (missing From)\n");
785                                 }
786                         }
787                         return SANITY_CHECK_FAILED;
788                 }
789                 if (!_msg->from->parsed) {
790 #ifdef EXTRA_DEBUG
791                         DBG("check_parse_uris(): parsing From header\n");
792 #endif
793                         ft_body = pkg_malloc(sizeof(struct to_body));
794                         if (!ft_body) {
795                                 LOG(L_ERR, "sanity_check(): check_parse_uris():"
796                                                 " out of pkg_memory (From)\n");
797                                 return SANITY_CHECK_ERROR;
798                         }
799                         memset(ft_body, 0, sizeof(struct to_body));
800                         parse_to(_msg->from->body.s, _msg->from->body.s + \
801                                         _msg->from->body.len + 1, ft_body);
802                         if (ft_body->error == PARSE_ERROR) {
803                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
804                                                 " failed to parse From header [%.*s]\n",
805                                                 _msg->from->body.len, _msg->from->body.s);
806                                 free_to(ft_body);
807                                 if (_msg->REQ_METHOD != METHOD_ACK) {
808                                         if (sanity_reply(_msg, 400, "Bad From header") < 0) {
809                                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
810                                                                 " failed to send 400 via sl reply"
811                                                                 " (bad from header)\n");
812                                         }
813                                 }
814                                 return SANITY_CHECK_FAILED;
815                         }
816                         _msg->from->parsed = ft_body;
817                         ft_body = NULL;
818                 }
819                 if (((struct to_body*)_msg->from->parsed)->uri.s) {
820 #ifdef EXTRA_DEBUG
821                         DBG("check_parse_uris(): parsing From URI\n");
822 #endif
823                         if (parse_uri(((struct to_body*)_msg->from->parsed)->uri.s, 
824                                         ((struct to_body*)_msg->from->parsed)->uri.len, &uri) != 0) {
825                             LOG(L_WARN, "sanity_check(): check_parse_uris():"
826                                                 " failed to parse From uri\n");
827                             if (_msg->REQ_METHOD != METHOD_ACK) {
828                                 if (sanity_reply(_msg, 400, "Bad From URI") < 0) {
829                                     LOG(L_WARN, "sanity_check(): check_parse_uris():"
830                                                         " failed to send 400 via sl reply"
831                                                         " (bad from uri)\n");
832                                 }
833                             }
834                             return SANITY_CHECK_FAILED;
835                         }
836                         /* FIXME: we should store this parsed struct somewhere so that
837                          * it could be re-used */
838                         /* FIXME 2: would it make sense to check here for "mandatory"
839                          * or "requested" parts of the URI? */
840                 }
841         }
842         /* check To URI */
843         if (SANITY_URI_CHECK_TO & checks) {
844 #ifdef EXTRA_DEBUG
845                 DBG("check_parse_uris(): looking up To header\n");
846 #endif
847                 if ((!_msg->to && parse_headers(_msg, HDR_TO_F, 0) != 0)
848                                 || !_msg->to) {
849                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
850                                         " missing to header\n");
851                         if (_msg->REQ_METHOD != METHOD_ACK) {
852                                 if (sanity_reply(_msg, 400, "Missing To Header") < 0) {
853                                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
854                                                         " failed to send 400 via sl reply (missing To)\n");
855                                 }
856                         }
857                         return SANITY_CHECK_FAILED;
858                 }
859                 /* parse_to is automatically called for HDR_TO_F */
860                 if (!_msg->to->parsed) {
861                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
862                                         " failed to parse To header\n");
863                         if (_msg->REQ_METHOD != METHOD_ACK) {
864                                 if (sanity_reply(_msg, 400, "Bad To URI") < 0) {
865                                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
866                                                         " failed to send 400 via sl reply (bad to uri)\n");
867                                 }
868                         }
869                         return SANITY_CHECK_FAILED;
870                 }
871                 if (((struct to_body*)_msg->to->parsed)->uri.s) {
872 #ifdef EXTRA_DEBUG
873                         DBG("check_parse_uris(): parsing To URI\n");
874 #endif
875                         if (parse_uri(((struct to_body*)_msg->to->parsed)->uri.s, 
876                                         ((struct to_body*)_msg->to->parsed)->uri.len, &uri) != 0) {
877                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
878                                                 " failed to parse To uri\n");
879                                 if (_msg->REQ_METHOD != METHOD_ACK) {
880                                         if (sanity_reply(_msg, 400, "Bad To URI") < 0) {
881                                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
882                                                                 " failed to send 400 via sl reply"
883                                                                 " (bad to uri)\n");
884                                         }
885                                 }
886                                 return SANITY_CHECK_FAILED;
887                         }
888                         /* FIXME: we should store this parsed struct somewhere so that
889                          * it could be re-used */
890                         /* FIXME 2: would it make sense to check here for "mandatory"
891                          * or "requested" parts of the URI? */
892                 }
893         }
894         /* check Contact URI */
895         if (SANITY_URI_CHECK_CONTACT & checks) {
896 #ifdef EXTRA_DEBUG
897                 DBG("check_parse_uris(): looking up Contact header\n");
898 #endif
899                 if ((!_msg->contact && parse_headers(_msg, HDR_CONTACT_F, 0) != 0)
900                                 || !_msg->contact) {
901                         LOG(L_WARN, "sanity_check(): check_parse_uris():"
902                                         " missing contact header\n");
903                 }
904                 if (_msg->contact) {
905 #ifdef EXTRA_DEBUG
906                         DBG("check_parse_uris(): parsing Contact header\n");
907 #endif
908                         if (parse_contact(_msg->contact) < 0) {
909                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
910                                                 " failed to parse Contact header\n");
911                                 if (_msg->REQ_METHOD != METHOD_ACK) {
912                                         if (sanity_reply(_msg, 400, "Bad Contact Header") < 0) {
913                                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
914                                                                 " failed to send 400 via send_reply"
915                                                                 " (bad Contact)\n");
916                                         }
917                                 }
918                                 return SANITY_CHECK_FAILED;
919                         }
920                         if (parse_uri(
921                                 ((struct contact_body*)_msg->contact->parsed)->contacts->uri.s,
922                                 ((struct contact_body*)_msg->contact->parsed)->contacts->uri.len,
923                                 &uri) != 0) {
924                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
925                                                 " failed to parse Contact uri\n");
926                                 if (_msg->REQ_METHOD != METHOD_ACK) {
927                                         if (sanity_reply(_msg, 400, "Bad Contact URI") < 0) {
928                                                 LOG(L_WARN, "sanity_check(): check_parse_uris():"
929                                                                 " failed to send 400 via send_reply"
930                                                                 " (bad Contact uri)\n");
931                                         }
932                                 }
933                                 return SANITY_CHECK_FAILED;
934                         }
935                 }
936         }
937
938 #ifdef EXTRA_DEBUG
939         DBG("check_parse_uris passed\n");
940 #endif
941         return SANITY_CHECK_PASSED;
942 }
943
944
945 /* Make sure that username attribute in all digest credentials
946  * instances has a meaningful value
947  */
948 int check_digest(struct sip_msg* msg, int checks)
949 {
950     struct hdr_field* ptr;
951     dig_cred_t* cred;
952     int ret;
953     int hf_type;
954
955     if (parse_headers(msg, HDR_EOH_F, 0) != 0) {
956         LOG(L_ERR, "sanity_check(): check_digest:"
957                         " failed to parse proxy require header\n");
958         return SANITY_CHECK_FAILED;
959     }
960
961     if (!msg->authorization && !msg->proxy_auth) {
962 #ifdef EXTRA_DEBUG
963         DBG("sanity_check(): check_digest: Nothing to check\n");
964 #endif
965         return SANITY_CHECK_PASSED;
966     }
967
968     if (msg->authorization) {
969         hf_type = HDR_AUTHORIZATION_T;
970         ptr = msg->authorization;
971     } else {
972         hf_type = HDR_PROXYAUTH_T;
973         ptr = msg->proxy_auth;
974     }
975     while(ptr) {
976         if ((ret = parse_credentials(ptr)) != 0) {
977             DBG("sanity_check(): check_digest: Cannot parse credentials: %d\n",
978                                 ret);
979             return SANITY_CHECK_FAILED;
980         }
981
982         cred = &((auth_body_t*)ptr->parsed)->digest;
983
984         if (check_dig_cred(cred) != E_DIG_OK) {
985 #ifdef EXTRA_DEBUG
986             DBG("sanity_check(): check_digest: Digest credentials malformed\n");
987 #endif
988             return SANITY_CHECK_FAILED;
989         }
990
991         if (cred->username.whole.len == 0) {
992 #ifdef EXTRA_DEBUG
993             DBG("sanity_check(): check_digest: Empty username\n");
994 #endif
995             return SANITY_CHECK_FAILED;
996         }
997         
998         if (cred->nonce.len == 0) {
999 #ifdef EXTRA_DEBUG
1000             DBG("sanity_check(): check_digest: Empty nonce attribute\n");
1001 #endif
1002             return SANITY_CHECK_FAILED;
1003         }
1004
1005         if (cred->response.len == 0) {
1006 #ifdef EXTRA_DEBUG
1007             DBG("sanity_check(): check_digest: Empty response attribute\n");
1008 #endif
1009             return SANITY_CHECK_FAILED;
1010         }
1011
1012         do {
1013             ptr = ptr->next;
1014         } while(ptr && ptr->type != hf_type);
1015
1016         if (!ptr && hf_type == HDR_AUTHORIZATION_T) {
1017             hf_type = HDR_PROXYAUTH_T;
1018             ptr = msg->proxy_auth;
1019         }
1020     }
1021
1022     return SANITY_CHECK_PASSED;
1023 }
1024
1025
1026 /* check for the presence of duplicate tag prameters in To/From headers */
1027 int check_duptags(sip_msg_t* _msg)
1028 {
1029         to_body_t *tb;
1030         to_param_t *tp;
1031         int n;
1032
1033         if(parse_from_header(_msg)<0 || parse_to_header(_msg)<0) {
1034                 DBG("check_duptags failed while parsing\n");
1035                 return SANITY_CHECK_FAILED;
1036         }
1037         tb = get_from(_msg);
1038         if(tb->tag_value.s!=NULL) {
1039                 n = 0;
1040                 for(tp = tb->param_lst; tp; tp = tp->next) {
1041                         if(tp->type==TAG_PARAM)
1042                                 n++;
1043                 }
1044                 if(n>1) {
1045                         DBG("check_duptags failed for From header\n");
1046                         return SANITY_CHECK_FAILED;
1047                 }
1048         }
1049         tb = get_to(_msg);
1050         if(tb->tag_value.s!=NULL) {
1051                 n = 0;
1052                 for(tp = tb->param_lst; tp; tp = tp->next) {
1053                         if(tp->type==TAG_PARAM)
1054                                 n++;
1055                 }
1056                 if(n>1) {
1057                         DBG("check_duptags failed for To header\n");
1058                         return SANITY_CHECK_FAILED;
1059                 }
1060         }
1061
1062         return SANITY_CHECK_PASSED;
1063 }
1064
1065