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
00032
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <sys/types.h>
00043 #include <unistd.h>
00044 #include "../mem/mem.h"
00045 #include "../dprint.h"
00046 #include "../str.h"
00047 #include "../ut.h"
00048 #include "parse_content.h"
00049
00050
00051 #define is_mime_char(_c_) \
00052 (isalpha((int)_c_) || (_c_)=='-' || (_c_)=='+' || (_c_)=='.')
00053 #define is_char_equal(_c_,_cs_) \
00054 ( (isalpha((int)_c_)?(((_c_)|0x20)==(_cs_)):((_c_)==(_cs_)))==1 )
00055
00056
00060 typedef struct type_node_s {
00061 char c;
00062 unsigned char final;
00064 unsigned char nr_sons;
00065 int next;
00066 }type_node_t;
00067
00068
00069 static type_node_t type_tree[] = {
00070 {'t',TYPE_UNKNOWN,1,4},
00071 {'e',TYPE_UNKNOWN,1,-1},
00072 {'x',TYPE_UNKNOWN,1,-1},
00073 {'t',TYPE_TEXT,0,-1},
00074 {'m',TYPE_UNKNOWN,2,19},
00075 {'e',TYPE_UNKNOWN,1,11},
00076 {'s',TYPE_UNKNOWN,1,-1},
00077 {'s',TYPE_UNKNOWN,1,-1},
00078 {'a',TYPE_UNKNOWN,1,-1},
00079 {'g',TYPE_UNKNOWN,1,-1},
00080 {'e',TYPE_MESSAGE,0,-1},
00081 {'u',TYPE_UNKNOWN,1,-1},
00082 {'l',TYPE_UNKNOWN,1,-1},
00083 {'t',TYPE_UNKNOWN,1,-1},
00084 {'i',TYPE_UNKNOWN,1,-1},
00085 {'p',TYPE_UNKNOWN,1,-1},
00086 {'a',TYPE_UNKNOWN,1,-1},
00087 {'r',TYPE_UNKNOWN,1,-1},
00088 {'t',TYPE_MULTIPART,0,-1},
00089 {'a',TYPE_UNKNOWN,1,-1},
00090 {'p',TYPE_UNKNOWN,1,-1},
00091 {'p',TYPE_UNKNOWN,1,-1},
00092 {'l',TYPE_UNKNOWN,1,-1},
00093 {'i',TYPE_UNKNOWN,1,-1},
00094 {'c',TYPE_UNKNOWN,1,-1},
00095 {'a',TYPE_UNKNOWN,1,-1},
00096 {'t',TYPE_UNKNOWN,1,-1},
00097 {'i',TYPE_UNKNOWN,1,-1},
00098 {'o',TYPE_UNKNOWN,1,-1},
00099 {'n',TYPE_APPLICATION,0,-1},
00100 };
00101
00102 static type_node_t subtype_tree[] = {
00103 {'p',SUBTYPE_UNKNOWN,2,13},
00104 {'l',SUBTYPE_UNKNOWN,1,5},
00105 {'a',SUBTYPE_UNKNOWN,1,-1},
00106 {'i',SUBTYPE_UNKNOWN,1,-1},
00107 {'n',SUBTYPE_PLAIN,0,-1},
00108 {'i',SUBTYPE_UNKNOWN,1,-1},
00109 {'d',SUBTYPE_UNKNOWN,1,-1},
00110 {'f',SUBTYPE_UNKNOWN,1,-1},
00111 {'+',TYPE_UNKNOWN,1,-1},
00112 {'x',TYPE_UNKNOWN,1,-1},
00113 {'m',TYPE_UNKNOWN,1,-1},
00114 {'l',SUBTYPE_PIDFXML,0,-1},
00115 {'l',SUBTYPE_PIDFXML,0,-1},
00116 {'s',SUBTYPE_UNKNOWN,1,16},
00117 {'d',SUBTYPE_UNKNOWN,1,-1},
00118 {'p',SUBTYPE_SDP,0,-1},
00119 {'c',SUBTYPE_UNKNOWN,1,34},
00120 {'p',SUBTYPE_UNKNOWN,2,-1},
00121 {'i',SUBTYPE_UNKNOWN,1,29},
00122 {'m',SUBTYPE_CPIM,1,-1},
00123 {'-',SUBTYPE_UNKNOWN,1,-1},
00124 {'p',SUBTYPE_UNKNOWN,1,-1},
00125 {'i',SUBTYPE_UNKNOWN,1,-1},
00126 {'d',SUBTYPE_UNKNOWN,1,-1},
00127 {'f',SUBTYPE_UNKNOWN,1,-1},
00128 {'+',SUBTYPE_UNKNOWN,1,-1},
00129 {'x',SUBTYPE_UNKNOWN,1,-1},
00130 {'m',SUBTYPE_UNKNOWN,1,-1},
00131 {'l',SUBTYPE_CPIM_PIDFXML,0,-1},
00132 {'l',SUBTYPE_UNKNOWN,1,-1},
00133 {'+',TYPE_UNKNOWN,1,-1},
00134 {'x',TYPE_UNKNOWN,1,-1},
00135 {'m',TYPE_UNKNOWN,1,-1},
00136 {'l',SUBTYPE_CPLXML,0,-1},
00137 {'r',SUBTYPE_UNKNOWN,2,48},
00138 {'l',SUBTYPE_UNKNOWN,1,42},
00139 {'m',SUBTYPE_UNKNOWN,1,-1},
00140 {'i',SUBTYPE_UNKNOWN,1,-1},
00141 {'+',TYPE_UNKNOWN,1,-1},
00142 {'x',TYPE_UNKNOWN,1,-1},
00143 {'m',TYPE_UNKNOWN,1,-1},
00144 {'l',SUBTYPE_RLMIXML,0,-1},
00145 {'e',SUBTYPE_UNKNOWN,1,-1},
00146 {'l',SUBTYPE_UNKNOWN,1,-1},
00147 {'a',SUBTYPE_UNKNOWN,1,-1},
00148 {'t',SUBTYPE_UNKNOWN,1,-1},
00149 {'e',SUBTYPE_UNKNOWN,1,-1},
00150 {'d',SUBTYPE_RELATED,0,-1},
00151 {'l',SUBTYPE_UNKNOWN,1,57},
00152 {'p',SUBTYPE_UNKNOWN,1,-1},
00153 {'i',SUBTYPE_UNKNOWN,1,-1},
00154 {'d',SUBTYPE_UNKNOWN,1,-1},
00155 {'f',SUBTYPE_UNKNOWN,1,-1},
00156 {'+',SUBTYPE_UNKNOWN,1,-1},
00157 {'x',SUBTYPE_UNKNOWN,1,-1},
00158 {'m',SUBTYPE_UNKNOWN,1,-1},
00159 {'l',SUBTYPE_LPIDFXML,0,-1},
00160 {'w',SUBTYPE_UNKNOWN,1,72},
00161 {'a',SUBTYPE_UNKNOWN,1,-1},
00162 {'t',SUBTYPE_UNKNOWN,1,-1},
00163 {'c',SUBTYPE_UNKNOWN,1,-1},
00164 {'h',SUBTYPE_UNKNOWN,1,-1},
00165 {'e',SUBTYPE_UNKNOWN,1,-1},
00166 {'r',SUBTYPE_UNKNOWN,1,-1},
00167 {'i',TYPE_UNKNOWN,1,-1},
00168 {'n',TYPE_UNKNOWN,1,-1},
00169 {'f',TYPE_UNKNOWN,1,-1},
00170 {'o',TYPE_UNKNOWN,1,-1},
00171 {'+',TYPE_UNKNOWN,1,-1},
00172 {'x',TYPE_UNKNOWN,1,-1},
00173 {'m',TYPE_UNKNOWN,1,-1},
00174 {'l',SUBTYPE_WATCHERINFOXML,0,-1},
00175 {'x',SUBTYPE_UNKNOWN,2,94},
00176 {'p',SUBTYPE_UNKNOWN,1,81},
00177 {'i',SUBTYPE_UNKNOWN,1,-1},
00178 {'d',SUBTYPE_UNKNOWN,1,-1},
00179 {'f',SUBTYPE_UNKNOWN,1,-1},
00180 {'+',SUBTYPE_UNKNOWN,1,-1},
00181 {'x',SUBTYPE_UNKNOWN,1,-1},
00182 {'m',SUBTYPE_UNKNOWN,1,-1},
00183 {'l',SUBTYPE_XPIDFXML,0,-1},
00184 {'m',SUBTYPE_UNKNOWN,1,-1},
00185 {'l',SUBTYPE_UNKNOWN,1,-1},
00186 {'+',SUBTYPE_UNKNOWN,1,-1},
00187 {'m',SUBTYPE_UNKNOWN,1,-1},
00188 {'s',SUBTYPE_UNKNOWN,1,-1},
00189 {'r',SUBTYPE_UNKNOWN,1,-1},
00190 {'t',SUBTYPE_UNKNOWN,1,-1},
00191 {'c',SUBTYPE_UNKNOWN,1,-1},
00192 {'.',SUBTYPE_UNKNOWN,1,-1},
00193 {'p',SUBTYPE_UNKNOWN,1,-1},
00194 {'i',SUBTYPE_UNKNOWN,1,-1},
00195 {'d',SUBTYPE_UNKNOWN,1,-1},
00196 {'f',SUBTYPE_XML_MSRTC_PIDF,0,-1},
00197 {'e',SUBTYPE_UNKNOWN,1,107},
00198 {'x',SUBTYPE_UNKNOWN,1,-1},
00199 {'t',SUBTYPE_UNKNOWN,1,-1},
00200 {'e',SUBTYPE_UNKNOWN,1,-1},
00201 {'r',SUBTYPE_UNKNOWN,1,-1},
00202 {'n',SUBTYPE_UNKNOWN,1,-1},
00203 {'a',SUBTYPE_UNKNOWN,1,-1},
00204 {'l',SUBTYPE_UNKNOWN,1,-1},
00205 {'-',SUBTYPE_UNKNOWN,1,-1},
00206 {'b',SUBTYPE_UNKNOWN,1,-1},
00207 {'o',SUBTYPE_UNKNOWN,1,-1},
00208 {'d',SUBTYPE_UNKNOWN,1,-1},
00209 {'y',SUBTYPE_EXTERNAL_BODY,0,-1},
00210 {'m',SUBTYPE_UNKNOWN,1,-1},
00211 {'i',SUBTYPE_UNKNOWN,1,-1},
00212 {'x',SUBTYPE_UNKNOWN,1,-1},
00213 {'e',SUBTYPE_UNKNOWN,1,-1},
00214 {'d',SUBTYPE_MIXED,0,-1},
00215 };
00216
00217
00218
00219 char* parse_content_length( char* buffer, char* end, int* length)
00220 {
00221 int number;
00222 char *p;
00223 int size;
00224
00225 p = buffer;
00226
00227 while ( p<end && (*p==' ' || *p=='\t' ||
00228 (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
00229 p++;
00230 if (p==end)
00231 goto error;
00232
00233 size = 0;
00234 number = 0;
00235 while (p<end && *p>='0' && *p<='9') {
00236 number = number*10 + (*p)-'0';
00237 size ++;
00238 p++;
00239 }
00240 if (p==end || size==0)
00241 goto error;
00242
00243 while ( p<end && (*p==' ' || *p=='\t' ||
00244 (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
00245 p++;
00246 if (p==end)
00247 goto error;
00248
00249 if ( (*(p++)!='\n') && (*(p-1)!='\r' || *(p++)!='\n' ) )
00250 goto error;
00251
00252 *length = number;
00253 return p;
00254 error:
00255 LOG(L_ERR,"ERROR:parse_content_length: parse error near char [%d][%c]\n",
00256 *p,*p);
00257 return 0;
00258 }
00259
00260
00261
00262 char* decode_mime_type(char *start, char *end, unsigned int *mime_type)
00263 {
00264 int node;
00265 char *mark;
00266 char *p;
00267 unsigned int type_candidate;
00268
00269 p = start;
00270
00271
00272 while ( p<end && (*p==' ' || *p=='\t' ||
00273 (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
00274 p++;
00275 if (p==end)
00276 goto error;
00277
00278
00279 if (*p=='*') {
00280 *mime_type = TYPE_ALL<<16;
00281 p++;
00282 } else {
00283 node = 0;
00284 mark = p;
00285 type_candidate = TYPE_UNKNOWN;
00286 while (p<end && is_mime_char(*p) ) {
00287 while ( node!=-1 && !is_char_equal(*p,type_tree[node].c) ){
00288 node = type_tree[node].next;
00289 }
00290 if (node!=-1) {
00291 type_candidate = type_tree[node].final;
00292 if (type_tree[node].nr_sons)
00293 node++;
00294 else
00295 node = -1;
00296 } else {
00297
00298
00299
00300 type_candidate = TYPE_UNKNOWN;
00301 }
00302 p++;
00303 }
00304 if (p==end || mark==p)
00305 goto error;
00306 *mime_type = type_candidate<<16;
00307 }
00308
00309
00310 while ( p<end && (*p==' ' || *p=='\t' ||
00311 (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
00312 p++;
00313 if ( p==end || *(p++)!='/')
00314 goto error;
00315
00316
00317 while ( p<end && (*p==' ' || *p=='\t' ||
00318 (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
00319 p++;
00320 if (p==end)
00321 goto error;
00322
00323
00324 if (*p=='*') {
00325 *mime_type |= SUBTYPE_ALL;
00326 p++;
00327 } else {
00328 node = 0;
00329 mark = p;
00330 type_candidate = SUBTYPE_UNKNOWN;
00331 while (p<end && is_mime_char(*p) ) {
00332 while(node!=-1 && !is_char_equal(*p,subtype_tree[node].c) )
00333 node = subtype_tree[node].next;
00334 if (node!=-1) {
00335 type_candidate = subtype_tree[node].final;
00336 if (subtype_tree[node].nr_sons)
00337 node++;
00338 else
00339 node = -1;
00340 } else {
00341
00342
00343
00344 type_candidate = SUBTYPE_UNKNOWN;
00345 }
00346 p++;
00347 }
00348 if (p==mark)
00349 goto error;
00350 *mime_type |= type_candidate;;
00351 }
00352
00353
00354 while ( p<end && (*p==' ' || *p=='\t' ||
00355 (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
00356 p++;
00357
00358
00359
00360 if ( p<end && *p==';' )
00361 for(p++; p<end && *p!=','; p++);
00362
00363
00364 if (p!=end && *p!=',' )
00365 goto error;
00366
00367
00368 if ((*mime_type)>>16==TYPE_ALL && ((*mime_type)&0x00ff)!=SUBTYPE_ALL) {
00369 LOG(L_ERR,"ERROR:decode_mime_type: invalid mime format found "
00370 " <*/submime> in [%.*s]!!\n", (int)(end-start),start);
00371 return 0;
00372 }
00373
00374 return p;
00375 error:
00376 LOG(L_ERR,"ERROR:decode_mime_type: parse error near in [%.*s] char"
00377 "[%d][%c] offset=%d\n", (int)(end-start),start,*p,*p,(int)(p-start));
00378 return 0;
00379 }
00380
00381
00382
00388 int parse_content_type_hdr( struct sip_msg *msg )
00389 {
00390 char *end;
00391 char *ret;
00392 unsigned int mime;
00393
00394
00395 if ( msg->content_type==0 ) {
00396
00397 if ( parse_headers(msg, HDR_CONTENTTYPE_F, 0)==-1)
00398 goto error;
00399 if ( msg->content_type==0 ) {
00400 DBG("DEBUG:parse_content_type_hdr: missing Content-Type"
00401 "header\n");
00402 return 0;
00403 }
00404 }
00405
00406
00407 if ( msg->content_type->parsed!=0)
00408 return get_content_type(msg);
00409
00410
00411 end = msg->content_type->body.s + msg->content_type->body.len;
00412 ret = decode_mime_type(msg->content_type->body.s, end , &mime);
00413 if (ret==0)
00414 goto error;
00415 if (ret!=end) {
00416 LOG(L_ERR,"ERROR:parse_content_type_hdr: CONTENT_TYPE hdr contains "
00417 "more then one mime type :-(!\n");
00418 goto error;
00419 }
00420 if ((mime&0x00ff)==SUBTYPE_ALL || (mime>>16)==TYPE_ALL) {
00421 LOG(L_ERR,"ERROR:parse_content_type_hdr: invalid mime with wildcard "
00422 "'*' in Content-Type hdr!\n");
00423 goto error;
00424 }
00425
00426 msg->content_type->parsed = (void*)(unsigned long)mime;
00427 return mime;
00428
00429 error:
00430 return -1;
00431 }
00432
00433 int parse_accept_body(struct hdr_field *hdr)
00434 {
00435 static unsigned int mimes[MAX_MIMES_NR];
00436 int nr_mimes;
00437 unsigned int mime;
00438 char *end;
00439 char *ret;
00440
00441 if (!hdr) return -1;
00442
00443
00444 if (hdr->parsed!=0) return 1;
00445
00446
00447 ret = hdr->body.s;
00448 end = ret + hdr->body.len;
00449 nr_mimes = 0;
00450 while (1){
00451 ret = decode_mime_type(ret, end , &mime);
00452 if (ret==0)
00453 goto error;
00454
00455 if (nr_mimes==MAX_MIMES_NR) {
00456 LOG(L_ERR,"ERROR:parse_accept_hdr: Accept hdr contains more than"
00457 " %d mime type -> buffer overflow!!\n",MAX_MIMES_NR);
00458 goto error;
00459 }
00460 mimes[nr_mimes++] = mime;
00461
00462 if (ret==end )
00463 break;
00464
00465 if (*ret!=',' || ret+1==end) {
00466 LOG(L_ERR,"ERROR:parse_accept_hdr: parse error between mimes at "
00467 "char <%x> (offset=%d) in <%.*s>!\n",
00468 *ret, (int)(ret-hdr->body.s),
00469 hdr->body.len, hdr->body.s);
00470 goto error;
00471 }
00472
00473 ret++;
00474 }
00475
00476
00477 hdr->parsed = (void*)pkg_malloc((nr_mimes+1)*sizeof(int));
00478 if (hdr->parsed==0) {
00479 LOG(L_ERR,"ERROR:parse_accept: no more pkg memory\n");
00480 goto error;
00481 }
00482 memcpy(hdr->parsed,mimes,nr_mimes*sizeof(int));
00483
00484 ((int*)hdr->parsed)[nr_mimes] = 0;
00485
00486 return 1;
00487 error:
00488 return -1;
00489 }
00490
00495 int parse_accept_hdr( struct sip_msg *msg )
00496 {
00497 static unsigned int mimes[MAX_MIMES_NR];
00498 int nr_mimes;
00499 unsigned int mime;
00500 char *end;
00501 char *ret;
00502
00503
00504 if ( msg->accept==0 ) {
00505
00506 if ( parse_headers(msg, HDR_ACCEPT_F, 0)==-1)
00507 goto error;
00508 if ( msg->accept==0 ) {
00509 DBG("DEBUG:parse_accept_hdr: missing Accept header\n");
00510 return 0;
00511 }
00512 }
00513
00514
00515 if ( msg->accept->parsed!=0)
00516 return 1;
00517
00518
00519 ret = msg->accept->body.s;
00520 end = ret + msg->accept->body.len;
00521 nr_mimes = 0;
00522 while (1){
00523 ret = decode_mime_type(ret, end , &mime);
00524 if (ret==0)
00525 goto error;
00526
00527 if (nr_mimes==MAX_MIMES_NR) {
00528 LOG(L_ERR,"ERROR:parse_accept_hdr: Accept hdr contains more than"
00529 " %d mime type -> buffer overflow!!\n",MAX_MIMES_NR);
00530 goto error;
00531 }
00532 mimes[nr_mimes++] = mime;
00533
00534 if (ret==end )
00535 break;
00536
00537 if (*ret!=',' || ret+1==end) {
00538 LOG(L_ERR,"ERROR:parse_accept_hdr: parse error between mimes at "
00539 "char <%x> (offset=%d) in <%.*s>!\n",
00540 *ret, (int)(ret-msg->accept->body.s),
00541 msg->accept->body.len, msg->accept->body.s);
00542 goto error;
00543 }
00544
00545 ret++;
00546 }
00547
00548
00549 msg->accept->parsed = (void*)pkg_malloc((nr_mimes+1)*sizeof(int));
00550 if (msg->accept->parsed==0) {
00551 LOG(L_ERR,"ERROR:parse_accept_hdr: no more pkg memory\n");
00552 goto error;
00553 }
00554 memcpy(msg->accept->parsed,mimes,nr_mimes*sizeof(int));
00555
00556 ((int*)msg->accept->parsed)[nr_mimes] = 0;
00557
00558 return 1;
00559 error:
00560 return -1;
00561 }
00562