Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / siproxd / src / security.c
1 /*
2     Copyright (C) 2002-2005  Thomas Ries <tries@gmx.net>
3
4     This file is part of Siproxd.
5     
6     Siproxd is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10     
11     Siproxd is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15     
16     You should have received a copy of the GNU General Public License
17     along with Siproxd; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19 */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <netinet/in.h>
29
30 #include <osipparser2/osip_parser.h>
31
32 #include "siproxd.h"
33 #include "log.h"
34
35 static char const ident[]="$Id: security.c,v 1.19 2005/01/08 10:05:13 hb9xar Exp $";
36
37 /*
38  * do security and integrity checks on the received packet
39  * (raw buffer, \0 terminated)
40  *
41  * RETURNS
42  *      STS_SUCCESS if ok 
43  *      STS_FAILURE if the packed did not pass the checks
44  */
45 int security_check_raw(char *sip_buffer, int size) {
46    char *p1=NULL, *p2=NULL;
47
48    DEBUGC(DBCLASS_BABBLE,"security_check_raw: size=%i", size);
49    /*
50     * empiric: size must be >= 16 bytes
51     *   2 byte <CR><LF> packets have been seen in the wild
52     */
53    if (size<SEC_MINLEN) return STS_FAILURE;
54
55    /*
56     * make sure no line (up to the next CRLF) is longer than allowed
57     * empiric: a line should not be longer than 256 characters
58     * (libosip may die with "virtual memory exhausted" otherwise)
59     * Ref: protos test suite c07-sip-r2.jar, test case 203
60     */
61    for (p1=sip_buffer; (p1+SEC_MAXLINELEN) < (sip_buffer+size); p1=p2+1) {
62       p2=strchr(p1, 10);
63       if ((p2 == 0) ||                  /* no CRLF found */
64           (p2-p1) > SEC_MAXLINELEN) {   /* longer than allowed */
65          DEBUGC(DBCLASS_SIP,"security_check_raw: line too long or no "
66                             "CRLF found");
67          return STS_FAILURE;
68       }
69    }
70
71
72    /* As libosip2 is *VERY* sensitive to corrupt input data, we need to
73       do more stuff here. For example, libosip2 can be crashed (with a
74       "<port_malloc.c> virtual memory exhausted" error - God knows why)
75       by sending the following few bytes. It will die in osip_message_parse()
76       ---BUFFER DUMP follows---
77         6e 74 2f 38 30 30 30 0d 0a 61 3d 66 6d 74 70 3a nt/8000..a=fmtp:
78         31 30 31 20 30 2d 31 35 0d 0a                   101 0-15..      
79       ---end of BUFFER DUMP---
80
81       By looking at the code in osip_message_parse.c, I'd guess it is
82       the 'only one space present' that leads to a faulty size
83       calculation (VERY BIG NUMBER), which in turn then dies inside 
84       osip_malloc.
85       So, we need at least 2 spaces to survive that code part of libosip2.
86     */
87    p1 = strchr(sip_buffer, ' ');
88    if (p1 && ((p1+1) < (sip_buffer+size))) {
89       p2 = strchr(p1+1, ' ');
90    } else {
91          DEBUGC(DBCLASS_SIP,"security_check_raw: found no space");
92          return STS_FAILURE;
93    }
94    if (p2==NULL) {
95          DEBUGC(DBCLASS_SIP,"security_check_raw: found only one space");
96          return STS_FAILURE;
97    }
98     
99
100    /* TODO: still way to go here ... */
101    return STS_SUCCESS;
102 }
103
104
105 /*
106  * do security and integrity checks on the received packet
107  * (parsed buffer)
108  *
109  * RETURNS
110  *      STS_SUCCESS if ok 
111  *      STS_FAILURE if the packed did not pass the checks
112  */
113 int security_check_sip(sip_ticket_t *ticket){
114    osip_message_t *sip=ticket->sipmsg;
115    if (MSG_IS_REQUEST(sip)) {
116       /* check for existing SIP URI in request */
117       if ((sip->req_uri == NULL) || (sip->req_uri->scheme == NULL)) {
118          ERROR("security check failed: NULL SIP URI");
119          return STS_FAILURE;
120       }
121
122       /* check SIP URI scheme */
123       if (osip_strcasecmp(sip->req_uri->scheme, "sip")) {
124          ERROR("security check failed: unknown scheme: %s",
125                sip->req_uri->scheme);
126          return STS_FAILURE;
127       }
128    }
129
130    /*
131     * Check existence of mandatory headers
132     *
133
134 Rosenberg, et. al.          Standards Track                   [Page 161]
135 \f
136 RFC 3261            SIP: Session Initiation Protocol           June 2002
137
138       Header field          where   proxy ACK BYE CAN INV OPT REG
139       ___________________________________________________________
140       Accept                  R            -   o   -   o   m*  o
141       Accept                 2xx           -   -   -   o   m*  o
142       Accept                 415           -   c   -   c   c   c
143       Accept-Encoding         R            -   o   -   o   o   o
144       Accept-Encoding        2xx           -   -   -   o   m*  o
145       Accept-Encoding        415           -   c   -   c   c   c
146       Accept-Language         R            -   o   -   o   o   o
147       Accept-Language        2xx           -   -   -   o   m*  o
148       Accept-Language        415           -   c   -   c   c   c
149       Alert-Info              R      ar    -   -   -   o   -   -
150       Alert-Info             180     ar    -   -   -   o   -   -
151       Allow                   R            -   o   -   o   o   o
152       Allow                  2xx           -   o   -   m*  m*  o
153       Allow                   r            -   o   -   o   o   o
154       Allow                  405           -   m   -   m   m   m
155       Authentication-Info    2xx           -   o   -   o   o   o
156       Authorization           R            o   o   o   o   o   o
157       Call-ID                 c       r    m   m   m   m   m   m
158       Call-Info                      ar    -   -   -   o   o   o
159       Contact                 R            o   -   -   m   o   o
160       Contact                1xx           -   -   -   o   -   -
161       Contact                2xx           -   -   -   m   o   o
162       Contact                3xx      d    -   o   -   o   o   o
163       Contact                485           -   o   -   o   o   o
164       Content-Disposition                  o   o   -   o   o   o
165       Content-Encoding                     o   o   -   o   o   o
166       Content-Language                     o   o   -   o   o   o
167       Content-Length                 ar    t   t   t   t   t   t
168       Content-Type                         *   *   -   *   *   *
169       CSeq                    c       r    m   m   m   m   m   m
170       Date                            a    o   o   o   o   o   o
171       Error-Info           300-699    a    -   o   o   o   o   o
172       Expires                              -   -   -   o   -   o
173       From                    c       r    m   m   m   m   m   m
174       In-Reply-To             R            -   -   -   o   -   -
175       Max-Forwards            R      amr   m   m   m   m   m   m
176       Min-Expires            423           -   -   -   -   -   m
177       MIME-Version                         o   o   -   o   o   o
178       Organization                   ar    -   -   -   o   o   o
179
180              Table 2: Summary of header fields, A--O
181
182
183
184
185
186
187 Rosenberg, et. al.          Standards Track                   [Page 162]
188 \f
189 RFC 3261            SIP: Session Initiation Protocol           June 2002
190
191
192    Header field              where       proxy ACK BYE CAN INV OPT REG
193    ___________________________________________________________________
194    Priority                    R          ar    -   -   -   o   -   -
195    Proxy-Authenticate         407         ar    -   m   -   m   m   m
196    Proxy-Authenticate         401         ar    -   o   o   o   o   o
197    Proxy-Authorization         R          dr    o   o   -   o   o   o
198    Proxy-Require               R          ar    -   o   -   o   o   o
199    Record-Route                R          ar    o   o   o   o   o   -
200    Record-Route             2xx,18x       mr    -   o   o   o   o   -
201    Reply-To                                     -   -   -   o   -   -
202    Require                                ar    -   c   -   c   c   c
203    Retry-After          404,413,480,486         -   o   o   o   o   o
204                             500,503             -   o   o   o   o   o
205                             600,603             -   o   o   o   o   o
206    Route                       R          adr   c   c   c   c   c   c
207    Server                      r                -   o   o   o   o   o
208    Subject                     R                -   -   -   o   -   -
209    Supported                   R                -   o   o   m*  o   o
210    Supported                  2xx               -   o   o   m*  m*  o
211    Timestamp                                    o   o   o   o   o   o
212    To                        c(1)          r    m   m   m   m   m   m
213    Unsupported                420               -   m   -   m   m   m
214    User-Agent                                   o   o   o   o   o   o
215    Via                         R          amr   m   m   m   m   m   m
216    Via                        rc          dr    m   m   m   m   m   m
217    Warning                     r                -   o   o   o   o   o
218    WWW-Authenticate           401         ar    -   m   -   m   m   m
219    WWW-Authenticate           407         ar    -   o   -   o   o   o
220
221 */
222
223
224   /*
225    * => Mandatory for ALL requests and responses
226    * Call-ID                 c       r    m   m   m   m   m   m
227    * CSeq                    c       r    m   m   m   m   m   m
228    * From                    c       r    m   m   m   m   m   m
229    * To                      c(1)    r    m   m   m   m   m   m
230    * Via                     R      amr   m   m   m   m   m   m
231    */
232
233   /* check for existing Call-ID header */
234    if ((sip->call_id==NULL)||
235        ((sip->call_id->number==NULL)&&(sip->call_id->host==NULL))) {
236       ERROR("security check failed: NULL Call-Id Header");
237       return STS_FAILURE;
238    }
239
240   /* check for existing CSeq header */
241    if ((sip->cseq==NULL)||
242        (sip->cseq->method==NULL)||(sip->cseq->number==NULL)) {
243       ERROR("security check failed: NULL CSeq Header");
244       return STS_FAILURE;
245    }
246
247    /* check for existing To: header */
248    if ((sip->to==NULL)||
249        (sip->to->url==NULL)||(sip->to->url->host==NULL)) {
250       ERROR("security check failed: NULL To Header");
251       return STS_FAILURE;
252    }
253
254   /* check for existing From: header */
255    if ((sip->from==NULL)||
256        (sip->from->url==NULL)||(sip->from->url->host==NULL)) {
257       ERROR("security check failed: NULL From Header");
258       return STS_FAILURE;
259    }
260
261   /* check for existing Via: header list */
262    if (sip->vias==NULL) {
263       ERROR("security check failed: No Via Headers");
264       return STS_FAILURE;
265    }
266
267
268
269    /* TODO: still way to go here ... */
270    return STS_SUCCESS;
271 }