siputils/checks.c

Go to the documentation of this file.
00001 /*
00002  * $Id: checks.c 5701 2009-03-14 12:09:47Z ibc_sf $
00003  *
00004  * Various URI checks and Request URI manipulation
00005  *
00006  * Copyright (C) 2001-2003 FhG Fokus
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License 
00021  * along with this program; if not, write to the Free Software 
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  *
00024  * History:
00025  * --------
00026  * 2003-02-26: Created by janakj
00027  * 2004-03-20: has_totag introduced (jiri)
00028  * 2004-04-14: uri_param and add_uri_param introduced (jih)
00029  */
00030 
00031 #include <string.h>
00032 #include "../../str.h"
00033 #include "../../dprint.h"               /* Debugging */
00034 #include "../../mem/mem.h"
00035 #include "../../parser/digest/digest.h" /* get_authorized_cred */
00036 #include "../../parser/parse_from.h"
00037 #include "../../parser/parse_uri.h"
00038 #include "../../parser/parse_param.h"
00039 #include "../../ut.h"                   /* Handy utilities */
00040 #include "../../db/db.h"                /* Database API */
00041 #include "../../dset.h"
00042 #include "../../pvar.h"
00043 #include "checks.h"
00044 
00045 
00046 /*
00047  * Checks if From includes a To-tag -- good to identify
00048  * if a request creates a new dialog
00049  */
00050 int has_totag(struct sip_msg* _m, char* _foo, char* _bar)
00051 {
00052    str tag;
00053 
00054    if (!_m->to && parse_headers(_m, HDR_TO_F,0)==-1) {
00055       LM_ERR("To parsing failed\n");
00056       return -1;
00057    }
00058    if (!_m->to) {
00059       LM_ERR("no To\n");
00060       return -1;
00061    }
00062    tag=get_to(_m)->tag_value;
00063    if (tag.s==0 || tag.len==0) {
00064       LM_DBG("no totag\n");
00065       return -1;
00066    }
00067    LM_DBG("totag found\n");
00068    return 1;
00069 }
00070 
00071 
00072 /*
00073  * Check if the username matches the username in credentials
00074  */
00075 int is_user(struct sip_msg* _m, char* _user, char* _str2)
00076 {
00077    str* s;
00078    struct hdr_field* h;
00079    auth_body_t* c;
00080 
00081    s = (str*)_user;
00082 
00083    get_authorized_cred(_m->authorization, &h);
00084    if (!h) {
00085       get_authorized_cred(_m->proxy_auth, &h);
00086       if (!h) {
00087          LM_ERR("no authorized credentials found (error in scripts)\n");
00088          LM_ERR("Call {www,proxy}_authorize before calling is_user function !\n");
00089          return -1;
00090       }
00091    }
00092 
00093    c = (auth_body_t*)(h->parsed);
00094 
00095    if (!c->digest.username.user.len) {
00096       LM_DBG("username not found in credentials\n");
00097       return -1;
00098    }
00099 
00100    if (s->len != c->digest.username.user.len) {
00101       LM_DBG("username length does not match\n");
00102       return -1;
00103    }
00104 
00105    if (!memcmp(s->s, c->digest.username.user.s, s->len)) {
00106       LM_DBG("username matches\n");
00107       return 1;
00108    } else {
00109       LM_DBG("username differs\n");
00110       return -1;
00111    }
00112 }
00113 
00114 
00115 /*
00116  * Find if Request URI has a given parameter with no value
00117  */
00118 int uri_param_1(struct sip_msg* _msg, char* _param, char* _str2)
00119 {
00120    return uri_param_2(_msg, _param, (char*)0);
00121 }
00122 
00123 
00124 /*
00125  * Find if Request URI has a given parameter with matching value
00126  */
00127 int uri_param_2(struct sip_msg* _msg, char* _param, char* _value)
00128 {
00129    str *param, *value, t;
00130 
00131    param_hooks_t hooks;
00132    param_t* params;
00133 
00134    param = (str*)_param;
00135    value = (str*)_value;
00136 
00137    if (parse_sip_msg_uri(_msg) < 0) {
00138            LM_ERR("ruri parsing failed\n");
00139            return -1;
00140    }
00141 
00142    t = _msg->parsed_uri.params;
00143 
00144    if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
00145            LM_ERR("ruri parameter parsing failed\n");
00146            return -1;
00147    }
00148 
00149    while (params) {
00150       if ((params->name.len == param->len) &&
00151           (strncmp(params->name.s, param->s, param->len) == 0)) {
00152          if (value) {
00153             if ((value->len == params->body.len) &&
00154                 strncmp(value->s, params->body.s, value->len) == 0) {
00155                goto ok;
00156             } else {
00157                goto nok;
00158             }
00159          } else {
00160             if (params->body.len > 0) {
00161                goto nok;
00162             } else {
00163                goto ok;
00164             }
00165          }
00166       } else {
00167          params = params->next;
00168       }
00169    }
00170    
00171 nok:
00172    free_params(params);
00173    return -1;
00174 
00175 ok:
00176    free_params(params);
00177    return 1;
00178 }
00179 
00180 
00181 
00182 /*
00183  * Adds a new parameter to Request URI
00184  */
00185 int add_uri_param(struct sip_msg* _msg, char* _param, char* _s2)
00186 {
00187    str *param, *cur_uri, new_uri;
00188    struct sip_uri *parsed_uri;
00189    char *at;
00190 
00191    param = (str*)_param;
00192 
00193    if (param->len == 0) {
00194       return 1;
00195    }
00196 
00197    if (parse_sip_msg_uri(_msg) < 0) {
00198            LM_ERR("ruri parsing failed\n");
00199            return -1;
00200    }
00201 
00202    parsed_uri = &(_msg->parsed_uri);
00203 
00204    /* if current ruri has no headers, pad param at the end */
00205    if (parsed_uri->headers.len == 0) {
00206       cur_uri =  GET_RURI(_msg);
00207       new_uri.len = cur_uri->len + param->len + 1;
00208       if (new_uri.len > MAX_URI_SIZE) {
00209          LM_ERR("new ruri too long\n");
00210          return -1;
00211       }
00212       new_uri.s = pkg_malloc(new_uri.len);
00213       if (new_uri.s == 0) {
00214          LM_ERR("add_uri_param(): Memory allocation failure\n");
00215          return -1;
00216       }
00217       memcpy(new_uri.s, cur_uri->s, cur_uri->len);
00218       *(new_uri.s + cur_uri->len) = ';';
00219       memcpy(new_uri.s + cur_uri->len + 1, param->s, param->len);
00220       if (rewrite_uri(_msg, &new_uri ) == 1) {
00221          goto ok;
00222       } else {
00223          goto nok;
00224       }
00225    }
00226 
00227    /* otherwise take the long path */
00228    new_uri.len = 4 +
00229       (parsed_uri->user.len ? parsed_uri->user.len + 1 : 0) +
00230       (parsed_uri->passwd.len ? parsed_uri->passwd.len + 1 : 0) +
00231       parsed_uri->host.len +
00232       (parsed_uri->port.len ? parsed_uri->port.len + 1 : 0) +
00233       parsed_uri->params.len + param->len + 1 +
00234       parsed_uri->headers.len + 1;
00235    if (new_uri.len > MAX_URI_SIZE) {
00236            LM_ERR("new ruri too long\n");
00237       return -1;
00238    }
00239 
00240    new_uri.s = pkg_malloc(new_uri.len);
00241    if (new_uri.s == 0) {
00242       LM_ERR("no more pkg memory\n");
00243       return -1;
00244    }
00245 
00246    at = new_uri.s;
00247    memcpy(at, "sip:", 4);
00248    at = at + 4;
00249    if (parsed_uri->user.len) {
00250       memcpy(at, parsed_uri->user.s, parsed_uri->user.len);
00251       if (parsed_uri->passwd.len) {
00252          *at = ':';
00253          at = at + 1;
00254          memcpy(at, parsed_uri->passwd.s, parsed_uri->passwd.len);
00255          at = at + parsed_uri->passwd.len;
00256       };
00257       *at = '@';
00258       at = at + 1;
00259    }
00260    memcpy(at, parsed_uri->host.s, parsed_uri->host.len);
00261    at = at + parsed_uri->host.len;
00262    if (parsed_uri->port.len) {
00263       *at = ':';
00264       at = at + 1;
00265       memcpy(at, parsed_uri->port.s, parsed_uri->port.len);
00266       at = at + parsed_uri->port.len;
00267    }
00268    memcpy(at, parsed_uri->params.s, parsed_uri->params.len);
00269    at = at + parsed_uri->params.len;
00270    *at = ';';
00271    at = at + 1;
00272    memcpy(at, param->s, param->len);
00273    at = at + param->len;
00274    *at = '?';
00275    at = at + 1;
00276    memcpy(at, parsed_uri->headers.s, parsed_uri->headers.len);
00277 
00278    if (rewrite_uri(_msg, &new_uri) == 1) {
00279       goto ok;
00280    }
00281 
00282 nok:
00283    pkg_free(new_uri.s);
00284    return -1;
00285 
00286 ok:
00287    pkg_free(new_uri.s);
00288    return 1;
00289 }
00290 
00291 
00292 /*
00293  * Converts Request-URI, if it is tel URI, to SIP URI.  Returns 1, if
00294  * conversion succeeded or if no conversion was needed, i.e., Request-URI
00295  * was not tel URI.  Returns -1, if conversion failed.
00296  */
00297 int tel2sip(struct sip_msg* _msg, char* _s1, char* _s2)
00298 {
00299    str *ruri;
00300    str tel_uri;
00301    struct sip_uri *pfuri;
00302    str suri;
00303    char* at;
00304    int i, j;
00305    int in_tel_parameters = 0;
00306 
00307    ruri = GET_RURI(_msg);
00308    
00309    if (ruri->len < 4) return 1;
00310 
00311    if (strncasecmp(ruri->s, "tel:", 4) != 0) return 1;
00312    
00313    tel_uri.s = pkg_malloc(ruri->len);
00314    if (tel_uri.s == 0) {
00315       LM_ERR("no more pkg memory\n");
00316       return -1;
00317    }
00318    
00319    /* Remove visual separators before converting to SIP URI. Don't remove 
00320    visual separators in TEL URI parameters (after the first ";") */
00321    for(i=0,j=0; i < ruri->len; i++) {
00322       if (in_tel_parameters == 0) {
00323          if (ruri->s[i] == ';')
00324             in_tel_parameters = 1;
00325       }
00326       if (in_tel_parameters == 0) {
00327          if (ruri->s[i] != '-' && ruri->s[i] != '.' && ruri->s[i] != '(' && ruri->s[i] != ')')
00328             tel_uri.s[j++] = tolower(ruri->s[i]);
00329       } else {
00330          tel_uri.s[j++] = tolower(ruri->s[i]);
00331       }
00332    }
00333    tel_uri.s[j] = '\0';
00334    tel_uri.len = strlen(tel_uri.s);
00335 
00336    if ((pfuri=parse_from_uri(_msg))==NULL) {
00337       LM_ERR("parsing From header failed\n");
00338       return -1;
00339    }
00340 
00341    suri.len = 4 + tel_uri.len - 4 + 1 + pfuri->host.len + 1 + 10;
00342    suri.s = pkg_malloc(suri.len);
00343    if (suri.s == 0) {
00344       LM_ERR("no more pkg memory\n");
00345       return -1;
00346    }
00347    at = suri.s;
00348    memcpy(at, "sip:", 4);
00349    at = at + 4;
00350    memcpy(at, tel_uri.s + 4, tel_uri.len - 4);
00351    at = at + tel_uri.len - 4;
00352    *at = '@';
00353    at = at + 1;
00354    memcpy(at, pfuri->host.s, pfuri->host.len);
00355    at = at + pfuri->host.len;
00356    *at = ';';
00357    at = at + 1;
00358    memcpy(at, "user=phone", 10);
00359 
00360    if (rewrite_uri(_msg, &suri) == 1) {
00361       pkg_free(suri.s);
00362       return 1;
00363    } else {
00364       pkg_free(suri.s);
00365       return -1;
00366    }
00367 }
00368 
00369 
00370 /*
00371  * Check if parameter is an e164 number.
00372  */
00373 static inline int e164_check(str* _user)
00374 {
00375     int i;
00376     char c;
00377     
00378     if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
00379    for (i = 1; i <= _user->len; i++) {
00380        c = (_user->s)[i];
00381        if (c < '0' && c > '9') return -1;
00382    }
00383    return 1;
00384     }
00385     return -1;
00386 }
00387 
00388 
00389 /*
00390  * Check if user part of URI in pseudo variable is an e164 number
00391  */
00392 int is_uri_user_e164(struct sip_msg* _m, char* _sp, char* _s2)
00393 {
00394     pv_spec_t *sp;
00395     pv_value_t pv_val;
00396     struct sip_uri puri;
00397 
00398     sp = (pv_spec_t *)_sp;
00399 
00400     if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
00401    if (pv_val.flags & PV_VAL_STR) {
00402        if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
00403       LM_DBG("missing uri\n");
00404       return -1;
00405        }
00406        if (parse_uri(pv_val.rs.s, pv_val.rs.len, &puri) < 0) {
00407       LM_ERR("parsing URI failed\n");
00408       return -1;
00409        }
00410        return e164_check(&(puri.user));
00411    } else {
00412        LM_ERR("pseudo variable value is not string\n");
00413        return -1;
00414    }
00415     } else {
00416    LM_ERR("failed to get pseudo variable value\n");
00417    return -1;
00418     }
00419 }

Generated on Thu May 24 12:00:24 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6