modules_k/siputils/checks.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * Various URI checks and URI manipulation
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * Copyright (C) 2004-2010 Juha Heinanen
00009  *
00010  * This file is part of SIP-router, a free SIP server.
00011  *
00012  * SIP-router is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version
00016  *
00017  * SIP-router is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License 
00023  * along with this program; if not, write to the Free Software 
00024  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025  *
00026  * History:
00027  * --------
00028  * 2003-02-26: Created by janakj
00029  * 2004-03-20: has_totag introduced (jiri)
00030  * 2004-04-14: uri_param and add_uri_param introduced (jih)
00031  */
00032 
00041 #include <string.h>
00042 #include "../../str.h"
00043 #include "../../dprint.h"               /* Debugging */
00044 #include "../../mem/mem.h"
00045 #include "../../parser/digest/digest.h" /* get_authorized_cred */
00046 #include "../../parser/parse_from.h"
00047 #include "../../parser/parse_uri.h"
00048 #include "../../parser/parse_param.h"
00049 #include "../../ut.h"                   /* Handy utilities */
00050 #include "../../lib/srdb1/db.h"                /* Database API */
00051 #include "../../dset.h"
00052 #include "../../pvar.h"
00053 #include "../../lvalue.h"
00054 #include "../../sr_module.h"
00055 #include "checks.h"
00056 
00060 int w_is_request(struct sip_msg* msg, char *foo, char *bar)
00061 {
00062         if(msg==NULL)
00063                 return -1;
00064 
00065         if(msg->first_line.type == SIP_REQUEST)
00066                 return 1;
00067 
00068         return -1;
00069 }
00070 
00074 int w_is_reply(struct sip_msg* msg, char *foo, char *bar)
00075 {
00076         if(msg==NULL)
00077                 return -1;
00078 
00079         if(msg->first_line.type == SIP_REPLY)
00080                 return 1;
00081 
00082         return -1;
00083 }
00084 
00085 /*
00086  * Checks if From includes a To-tag -- good to identify
00087  * if a request creates a new dialog
00088  */
00089 int has_totag(struct sip_msg* _m, char* _foo, char* _bar)
00090 {
00091         str tag;
00092 
00093         if (!_m->to && parse_headers(_m, HDR_TO_F,0)==-1) {
00094                 LM_ERR("To parsing failed\n");
00095                 return -1;
00096         }
00097         if (!_m->to) {
00098                 LM_ERR("no To\n");
00099                 return -1;
00100         }
00101         tag=get_to(_m)->tag_value;
00102         if (tag.s==0 || tag.len==0) {
00103                 LM_DBG("no totag\n");
00104                 return -1;
00105         }
00106         LM_DBG("totag found\n");
00107         return 1;
00108 }
00109 
00110 
00111 /*
00112  * Check if the username matches the username in credentials
00113  */
00114 int is_user(struct sip_msg* _m, char* _user, char* _str2)
00115 {
00116         str* s;
00117         struct hdr_field* h;
00118         auth_body_t* c;
00119 
00120         s = (str*)_user;
00121 
00122         get_authorized_cred(_m->authorization, &h);
00123         if (!h) {
00124                 get_authorized_cred(_m->proxy_auth, &h);
00125                 if (!h) {
00126                         LM_ERR("no authorized credentials found (error in scripts)\n");
00127                         LM_ERR("Call {www,proxy}_authorize before calling is_user function !\n");
00128                         return -1;
00129                 }
00130         }
00131 
00132         c = (auth_body_t*)(h->parsed);
00133 
00134         if (!c->digest.username.user.len) {
00135                 LM_DBG("username not found in credentials\n");
00136                 return -1;
00137         }
00138 
00139         if (s->len != c->digest.username.user.len) {
00140                 LM_DBG("username length does not match\n");
00141                 return -1;
00142         }
00143 
00144         if (!memcmp(s->s, c->digest.username.user.s, s->len)) {
00145                 LM_DBG("username matches\n");
00146                 return 1;
00147         } else {
00148                 LM_DBG("username differs\n");
00149                 return -1;
00150         }
00151 }
00152 
00153 
00154 /*
00155  * Find if Request URI has a given parameter with no value
00156  */
00157 int uri_param_1(struct sip_msg* _msg, char* _param, char* _str2)
00158 {
00159         return uri_param_2(_msg, _param, (char*)0);
00160 }
00161 
00162 
00163 /*
00164  * Find if Request URI has a given parameter with matching value
00165  */
00166 int uri_param_2(struct sip_msg* _msg, char* _param, char* _value)
00167 {
00168         str *param, *value, t;
00169 
00170         param_hooks_t hooks;
00171         param_t* params;
00172 
00173         param = (str*)_param;
00174         value = (str*)_value;
00175 
00176         if (parse_sip_msg_uri(_msg) < 0) {
00177                 LM_ERR("ruri parsing failed\n");
00178                 return -1;
00179         }
00180 
00181         t = _msg->parsed_uri.params;
00182 
00183         if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
00184                 LM_ERR("ruri parameter parsing failed\n");
00185                 return -1;
00186         }
00187 
00188         while (params) {
00189                 if ((params->name.len == param->len) &&
00190                     (strncmp(params->name.s, param->s, param->len) == 0)) {
00191                         if (value) {
00192                                 if ((value->len == params->body.len) &&
00193                                     strncmp(value->s, params->body.s, value->len) == 0) {
00194                                         goto ok;
00195                                 } else {
00196                                         goto nok;
00197                                 }
00198                         } else {
00199                                 if (params->body.len > 0) {
00200                                         goto nok;
00201                                 } else {
00202                                         goto ok;
00203                                 }
00204                         }
00205                 } else {
00206                         params = params->next;
00207                 }
00208         }
00209         
00210 nok:
00211         free_params(params);
00212         return -1;
00213 
00214 ok:
00215         free_params(params);
00216         return 1;
00217 }
00218 
00219 
00220 
00221 /*
00222  * Adds a new parameter to Request URI
00223  */
00224 int add_uri_param(struct sip_msg* _msg, char* _param, char* _s2)
00225 {
00226         str *param, *cur_uri, new_uri;
00227         struct sip_uri *parsed_uri;
00228         char *at;
00229 
00230         param = (str*)_param;
00231 
00232         if (param->len == 0) {
00233                 return 1;
00234         }
00235 
00236         if (parse_sip_msg_uri(_msg) < 0) {
00237                 LM_ERR("ruri parsing failed\n");
00238                 return -1;
00239         }
00240 
00241         parsed_uri = &(_msg->parsed_uri);
00242 
00243         /* if current ruri has no headers, pad param at the end */
00244         if (parsed_uri->headers.len == 0) {
00245                 cur_uri =  GET_RURI(_msg);
00246                 new_uri.len = cur_uri->len + param->len + 1;
00247                 if (new_uri.len > MAX_URI_SIZE) {
00248                         LM_ERR("new ruri too long\n");
00249                         return -1;
00250                 }
00251                 new_uri.s = pkg_malloc(new_uri.len);
00252                 if (new_uri.s == 0) {
00253                         LM_ERR("add_uri_param(): Memory allocation failure\n");
00254                         return -1;
00255                 }
00256                 memcpy(new_uri.s, cur_uri->s, cur_uri->len);
00257                 *(new_uri.s + cur_uri->len) = ';';
00258                 memcpy(new_uri.s + cur_uri->len + 1, param->s, param->len);
00259                 if (rewrite_uri(_msg, &new_uri ) == 1) {
00260                         goto ok;
00261                 } else {
00262                         goto nok;
00263                 }
00264         }
00265 
00266         /* otherwise take the long path */
00267         new_uri.len = 4 +
00268                 (parsed_uri->user.len ? parsed_uri->user.len + 1 : 0) +
00269                 (parsed_uri->passwd.len ? parsed_uri->passwd.len + 1 : 0) +
00270                 parsed_uri->host.len +
00271                 (parsed_uri->port.len ? parsed_uri->port.len + 1 : 0) +
00272                 parsed_uri->params.len + param->len + 1 +
00273                 parsed_uri->headers.len + 1;
00274         if (new_uri.len > MAX_URI_SIZE) {
00275                 LM_ERR("new ruri too long\n");
00276                 return -1;
00277         }
00278 
00279         new_uri.s = pkg_malloc(new_uri.len);
00280         if (new_uri.s == 0) {
00281                 LM_ERR("no more pkg memory\n");
00282                 return -1;
00283         }
00284 
00285         at = new_uri.s;
00286         memcpy(at, "sip:", 4);
00287         at = at + 4;
00288         if (parsed_uri->user.len) {
00289                 memcpy(at, parsed_uri->user.s, parsed_uri->user.len);
00290                 if (parsed_uri->passwd.len) {
00291                         *at = ':';
00292                         at = at + 1;
00293                         memcpy(at, parsed_uri->passwd.s, parsed_uri->passwd.len);
00294                         at = at + parsed_uri->passwd.len;
00295                 };
00296                 *at = '@';
00297                 at = at + 1;
00298         }
00299         memcpy(at, parsed_uri->host.s, parsed_uri->host.len);
00300         at = at + parsed_uri->host.len;
00301         if (parsed_uri->port.len) {
00302                 *at = ':';
00303                 at = at + 1;
00304                 memcpy(at, parsed_uri->port.s, parsed_uri->port.len);
00305                 at = at + parsed_uri->port.len;
00306         }
00307         memcpy(at, parsed_uri->params.s, parsed_uri->params.len);
00308         at = at + parsed_uri->params.len;
00309         *at = ';';
00310         at = at + 1;
00311         memcpy(at, param->s, param->len);
00312         at = at + param->len;
00313         *at = '?';
00314         at = at + 1;
00315         memcpy(at, parsed_uri->headers.s, parsed_uri->headers.len);
00316 
00317         if (rewrite_uri(_msg, &new_uri) == 1) {
00318                 goto ok;
00319         }
00320 
00321 nok:
00322         pkg_free(new_uri.s);
00323         return -1;
00324 
00325 ok:
00326         pkg_free(new_uri.s);
00327         return 1;
00328 }
00329 
00330 
00331 /*
00332  * Converts URI, if it is tel URI, to SIP URI.  Returns 1, if
00333  * conversion succeeded or if no conversion was needed, i.e., URI was not
00334  * tel URI.  Returns -1, if conversion failed.  Takes SIP URI hostpart from
00335  * second parameter and (if needed) writes the result to third paramater.
00336  */
00337 int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
00338 {
00339     str uri, hostpart, tel_uri, sip_uri;
00340     char *at;
00341     int i, j, in_tel_parameters = 0;
00342     pv_spec_t *res;
00343     pv_value_t res_val;
00344 
00345     /* get parameters */
00346     if (get_str_fparam(&uri, _msg, (fparam_t*)_uri) < 0) {
00347         LM_ERR("failed to get uri value\n");
00348     }
00349     if (get_str_fparam(&hostpart, _msg, (fparam_t*)_hostpart) < 0) {
00350         LM_ERR("failed to get hostpart value\n");
00351     }
00352     res = (pv_spec_t *)_res;
00353 
00354     /* check if anything needs to be done */
00355     if (uri.len < 4) return 1;
00356     if (strncasecmp(uri.s, "tel:", 4) != 0) return 1;
00357     
00358     /* reserve memory for clean tel uri */
00359     tel_uri.s = pkg_malloc(uri.len);
00360     if (tel_uri.s == 0) {
00361         LM_ERR("no more pkg memory\n");
00362         return -1;
00363     }
00364         
00365     /* Remove visual separators before converting to SIP URI. Don't remove 
00366        visual separators in TEL URI parameters (after the first ";") */
00367     for (i=0, j=0; i < uri.len; i++) {
00368         if (in_tel_parameters == 0) {
00369             if (uri.s[i] == ';')
00370                 in_tel_parameters = 1;
00371         }
00372         if (in_tel_parameters == 0) {
00373             if ((uri.s[i] != '-') && (uri.s[i] != '.') && 
00374                 (uri.s[i] != '(') && (uri.s[i] != ')'))
00375                 tel_uri.s[j++] = tolower(uri.s[i]);
00376         } else {
00377             tel_uri.s[j++] = tolower(uri.s[i]);
00378         }
00379     }
00380     tel_uri.s[j] = '\0';
00381     tel_uri.len = strlen(tel_uri.s);
00382 
00383     /* reserve memory for resulting sip uri */
00384     sip_uri.len = 4 + tel_uri.len - 4 + 1 + hostpart.len + 1 + 10;
00385     sip_uri.s = pkg_malloc(sip_uri.len);
00386     if (sip_uri.s == 0) {
00387         LM_ERR("no more pkg memory\n");
00388         pkg_free(tel_uri.s);
00389         return -1;
00390     }
00391 
00392     /* create resulting sip uri */
00393     at = sip_uri.s;
00394     append_str(at, "sip:", 4);
00395     append_str(at, tel_uri.s + 4, tel_uri.len - 4);
00396     append_chr(at, '@');
00397     append_str(at, hostpart.s, hostpart.len);
00398     append_chr(at, ';');
00399     append_str(at, "user=phone", 10);
00400 
00401     /* tel_uri is not needed anymore */
00402     pkg_free(tel_uri.s);
00403 
00404     /* set result pv value and write sip uri to result pv */
00405     res_val.rs = sip_uri;
00406     res_val.flags = PV_VAL_STR;
00407     if (res->setf(_msg, &res->pvp, (int)EQ_T, &res_val) != 0) {
00408         LM_ERR("failed to set result pvar\n");
00409         pkg_free(sip_uri.s);
00410         return -1;
00411     }
00412 
00413     /* free allocated pkg memory and return */
00414     pkg_free(sip_uri.s);
00415     return 1;
00416 }
00417 
00418 
00419 /*
00420  * Check if parameter is an e164 number.
00421  */
00422 static inline int e164_check(str* _user)
00423 {
00424     int i;
00425     char c;
00426     
00427     if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
00428         for (i = 1; i <= _user->len; i++) {
00429             c = (_user->s)[i];
00430             if (c < '0' && c > '9') return -1;
00431         }
00432         return 1;
00433     }
00434     return -1;
00435 }
00436 
00437 
00438 /*
00439  * Check if user part of URI in pseudo variable is an e164 number
00440  */
00441 int is_e164(struct sip_msg* _m, char* _sp, char* _s2)
00442 {
00443     pv_spec_t *sp;
00444     pv_value_t pv_val;
00445 
00446     sp = (pv_spec_t *)_sp;
00447 
00448     if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
00449         if (pv_val.flags & PV_VAL_STR) {
00450             if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
00451                 LM_DBG("missing argument\n");
00452                 return -1;
00453             }
00454             return e164_check(&(pv_val.rs));
00455         } else {
00456             LM_ERR("pseudo variable value is not string\n");
00457             return -1;
00458         }
00459     } else {
00460         LM_ERR("failed to get pseudo variable value\n");
00461         return -1;
00462     }
00463 }
00464 
00465 
00466 /*
00467  * Check if user part of URI in pseudo variable is an e164 number
00468  */
00469 int w_is_uri_user_e164(struct sip_msg* _m, char* _sp, char* _s2)
00470 {
00471     pv_spec_t *sp;
00472     pv_value_t pv_val;
00473 
00474     sp = (pv_spec_t *)_sp;
00475 
00476     if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
00477         if (pv_val.flags & PV_VAL_STR) {
00478             if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
00479                 LM_DBG("missing uri\n");
00480                 return -1;
00481             }
00482             return is_uri_user_e164(&pv_val.rs);
00483         } else {
00484             LM_ERR("pseudo variable value is not string\n");
00485             return -1;
00486         }
00487     } else {
00488         LM_ERR("failed to get pseudo variable value\n");
00489         return -1;
00490     }
00491 }
00492 
00493 
00494 int is_uri_user_e164(str *uri)
00495 {
00496     char *chr;
00497     str user;
00498 
00499     chr = memchr(uri->s, ':', uri->len);
00500     if (chr == NULL) {
00501         LM_ERR("parsing URI failed\n");
00502         return -1;
00503     };
00504     user.s = chr + 1;
00505     chr = memchr(user.s, '@', uri->len - (user.s - uri->s));
00506     if (chr == NULL) return -1;
00507     user.len = chr - user.s;
00508 
00509     return e164_check(&user);
00510 }
00511 
00512 /*
00513  * Set userpart of URI
00514  */
00515 int set_uri_user(struct sip_msg* _m, char* _uri, char* _value)
00516 {
00517     pv_spec_t *uri_pv, *value_pv;
00518     pv_value_t uri_val, value_val, res_val;
00519     str uri, value;
00520     char *at, *colon, *c;
00521     char new_uri[MAX_URI_SIZE + 1];
00522 
00523     uri_pv = (pv_spec_t *)_uri;
00524     if (uri_pv && (pv_get_spec_value(_m, uri_pv, &uri_val) == 0)) {
00525         if (uri_val.flags & PV_VAL_STR) {
00526             if (uri_val.rs.len == 0 || uri_val.rs.s == NULL) {
00527                 LM_ERR("missing uri value\n");
00528                 return -1;
00529             }
00530         } else {
00531             LM_ERR("uri value is not string\n");
00532             return -1;
00533         }
00534     } else {
00535         LM_ERR("failed to get uri value\n");
00536         return -1;
00537     }
00538     uri = uri_val.rs;
00539 
00540     value_pv = (pv_spec_t *)_value;
00541     if (value_pv && (pv_get_spec_value(_m, value_pv, &value_val) == 0)) {
00542         if (value_val.flags & PV_VAL_STR) {
00543             if (value_val.rs.s == NULL) {
00544                 LM_ERR("missing uriuser value\n");
00545                 return -1;
00546             }
00547         } else {
00548             LM_ERR("uriuser value is not string\n");
00549             return -1;
00550         }
00551     } else {
00552         LM_ERR("failed to get uriuser value\n");
00553         return -1;
00554     }
00555     value = value_val.rs;
00556 
00557     colon = strchr(uri.s, ':');
00558     if (colon == NULL) {
00559         LM_ERR("uri does not contain ':' character\n");
00560         return -1;
00561     }
00562     at = strchr(uri.s, '@');
00563     c = &(new_uri[0]);
00564     if (at == NULL) {
00565         if (value.len == 0) return 1;
00566         if (uri.len + value.len > MAX_URI_SIZE) {
00567             LM_ERR("resulting uri would be too large\n");
00568             return -1;
00569         }
00570         append_str(c, uri.s, colon - uri.s + 1);
00571         append_str(c, value.s, value.len);
00572         append_chr(c, '@');
00573         append_str(c, colon + 1, uri.len - (colon - uri.s + 1));
00574         res_val.rs.len = uri.len + value.len + 1;
00575     } else {
00576         if (value.len == 0) {
00577             append_str(c, uri.s, colon - uri.s + 1);
00578             append_str(c, at + 1, uri.len - (at - uri.s + 1));
00579             res_val.rs.len = uri.len - (at - colon);
00580         } else {
00581             if (uri.len + value.len - (at - colon - 1) > MAX_URI_SIZE) {
00582                 LM_ERR("resulting uri would be too large\n");
00583                 return -1;
00584             }
00585             append_str(c, uri.s, colon - uri.s + 1);
00586             append_str(c, value.s, value.len);
00587             append_str(c, at, uri.len - (at - uri.s));
00588             res_val.rs.len = uri.len + value.len - (at - colon - 1);
00589         }
00590     }
00591 
00592     res_val.rs.s = &(new_uri[0]);
00593     LM_DBG("resulting uri: %.*s\n", res_val.rs.len, res_val.rs.s);
00594     res_val.flags = PV_VAL_STR;
00595     uri_pv->setf(_m, &uri_pv->pvp, (int)EQ_T, &res_val);
00596 
00597     return 1;
00598 }
00599 
00600 /*
00601  * Set hostpart of URI
00602  */
00603 int set_uri_host(struct sip_msg* _m, char* _uri, char* _value)
00604 {
00605     pv_spec_t *uri_pv, *value_pv;
00606     pv_value_t uri_val, value_val, res_val;
00607     str uri, value;
00608     char *at, *colon, *c, *next;
00609     unsigned int host_len;
00610     char new_uri[MAX_URI_SIZE + 1];
00611 
00612     uri_pv = (pv_spec_t *)_uri;
00613     if (uri_pv && (pv_get_spec_value(_m, uri_pv, &uri_val) == 0)) {
00614         if (uri_val.flags & PV_VAL_STR) {
00615             if (uri_val.rs.len == 0 || uri_val.rs.s == NULL) {
00616                 LM_ERR("missing uri value\n");
00617                 return -1;
00618             }
00619         } else {
00620             LM_ERR("uri value is not string\n");
00621             return -1;
00622         }
00623     } else {
00624         LM_ERR("failed to get uri value\n");
00625         return -1;
00626     }
00627     uri = uri_val.rs;
00628 
00629     value_pv = (pv_spec_t *)_value;
00630     if (value_pv && (pv_get_spec_value(_m, value_pv, &value_val) == 0)) {
00631         if (value_val.flags & PV_VAL_STR) {
00632             if (value_val.rs.s == NULL) {
00633                 LM_ERR("missing uri value\n");
00634                 return -1;
00635             }
00636         } else {
00637             LM_ERR("uri value is not string\n");
00638             return -1;
00639         }
00640     } else {
00641         LM_ERR("failed to get uri value\n");
00642         return -1;
00643     }
00644     value = value_val.rs;
00645 
00646     if (value.len == 0) {
00647         LM_ERR("hostpart of uri cannot be empty\n");
00648         return -1;
00649     }
00650     if (uri.len + value.len > MAX_URI_SIZE) {
00651         LM_ERR("resulting uri would be too large\n");
00652         return -1;
00653     }
00654 
00655     colon = strchr(uri.s, ':');
00656     if (colon == NULL) {
00657         LM_ERR("uri does not contain ':' character\n");
00658         return -1;
00659     }
00660     c = &(new_uri[0]);
00661     at = strchr(colon + 1, '@');
00662     if (at == NULL) {
00663         next = colon + 1;
00664     } else {
00665         next = at + 1;
00666     }
00667     append_str(c, uri.s, next - uri.s);
00668     host_len = strcspn(next, ":;?");
00669     append_str(c, value.s, value.len);
00670     strcpy(c, next + host_len);
00671     res_val.rs.len = uri.len + value.len - host_len;
00672     res_val.rs.s = &(new_uri[0]);
00673 
00674     LM_DBG("resulting uri: %.*s\n", res_val.rs.len, res_val.rs.s);
00675     res_val.flags = PV_VAL_STR;
00676     uri_pv->setf(_m, &uri_pv->pvp, (int)EQ_T, &res_val);
00677 
00678     return 1;
00679 }