rpid.c

Go to the documentation of this file.
00001 /*
00002  * $Id: rpid.c 5211 2008-11-17 20:05:27Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License 
00019  * along with this program; if not, write to the Free Software 
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * --------
00024  * 2003-04-28 rpid contributed by Juha Heinanen added (janakj)
00025  * 2005-05-31 general avp specification added for rpid (bogdan)
00026  */
00027 
00028 /*!
00029  * \file
00030  * \brief Remote-Party-ID related functions
00031  * \ingroup auth
00032  * - Module: \ref auth
00033  */
00034 
00035 #include <string.h>
00036 #include <strings.h>
00037 #include "../../str.h"
00038 #include "../../data_lump.h"
00039 #include "../../dprint.h"
00040 #include "../../mem/mem.h"
00041 #include "../../parser/parse_nameaddr.h"
00042 #include "../../parser/parse_uri.h"
00043 #include "../../parser/parser_f.h"
00044 #include "../../ut.h"
00045 #include "../../pvar.h"
00046 #include "auth_mod.h"
00047 #include "api.h"
00048 #include "rpid.h"
00049 
00050 
00051 #define RPID_HF_NAME "Remote-Party-ID: "
00052 #define RPID_HF_NAME_LEN (sizeof(RPID_HF_NAME) - 1)
00053 
00054 /* rpid AVP specs */
00055 static unsigned short rpid_avp_type;
00056 static int_str rpid_avp_name;
00057 
00058 
00059 /*!
00060  * \brief Parse and set the RPID AVP specs
00061  * \param rpid_avp_param RPID AVP parameter
00062  * \return 0 on success, -1 on failure
00063  */
00064 int init_rpid_avp(char *rpid_avp_param)
00065 {
00066    pv_spec_t avp_spec;
00067    str stmp;
00068    if (rpid_avp_param && *rpid_avp_param) {
00069       stmp.s = rpid_avp_param; stmp.len = strlen(stmp.s);
00070       if (pv_parse_spec(&stmp, &avp_spec)==0
00071             || avp_spec.type!=PVT_AVP) {
00072          LM_ERR("malformed or non AVP %s AVP definition\n", rpid_avp_param);
00073          return -1;
00074       }
00075 
00076       if(pv_get_avp_name(0, &(avp_spec.pvp), &rpid_avp_name,
00077                &rpid_avp_type)!=0)
00078       {
00079          LM_ERR("[%s]- invalid AVP definition\n", rpid_avp_param);
00080          return -1;
00081       }
00082    } else {
00083       rpid_avp_name.n = 0;
00084       rpid_avp_type = 0;
00085    }
00086 
00087    return 0;
00088 }
00089 
00090 
00091 /*!
00092  * \brief Gets the RPID avp specs
00093  * \param rpid_avp_p AVP name
00094  * \param rpid_avp_type_p AVP type
00095  */
00096 void get_rpid_avp( int_str *rpid_avp_p, int *rpid_avp_type_p )
00097 {
00098    *rpid_avp_p = rpid_avp_name;
00099    *rpid_avp_type_p = rpid_avp_type;
00100 }
00101 
00102 
00103 /*!
00104  * \brief Check if user is a E164 number
00105  * \param _user user 
00106  * \note Copy of is_e164 from enum module
00107  * \return 1 if its a E164 number, -1 if not
00108  */
00109 static inline int is_e164(str* _user)
00110 {
00111    int i;
00112    char c;
00113    
00114    if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
00115       for (i = 1; i < _user->len; i++) {
00116          c = (_user->s)[i];
00117          if ((c < '0') || (c > '9')) return -1;
00118       }
00119       return 1;
00120    } else {
00121        return -1;
00122    }
00123 }
00124 
00125 
00126 /*!
00127  * \brief Append RPID helper function
00128  * \param _m SIP message
00129  * \param _s appended string
00130  * \note Copy of append_hf_helper from textops
00131  * \return 0 on success, negative on failure
00132  */
00133 static inline int append_rpid_helper(struct sip_msg* _m, str *_s)
00134 {
00135    struct lump* anchor;
00136    
00137    if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
00138       LM_ERR("failed to parse message\n");
00139       return -1;
00140    }
00141    
00142    anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
00143    if (!anchor) {
00144       LM_ERR("can't get anchor\n");
00145       return -2;
00146    }
00147    
00148    if (!insert_new_lump_before(anchor, _s->s, _s->len, 0)) {
00149       LM_ERR("can't insert lump\n");
00150       return -3;
00151    }
00152 
00153    return 0;
00154 }
00155 
00156 
00157 /*!
00158  * \brief Append RPID header field to the message
00159  * \param _m SIP message
00160  * \param _s1 unused
00161  * \param _s2 unused
00162  * \return 1 on success, -1 on failure
00163  */
00164 int append_rpid_hf(struct sip_msg* _m, char* _s1, char* _s2)
00165 {
00166    struct usr_avp *avp;
00167    str rpid_hf, rpid;
00168    char *at;
00169    int_str val;
00170 
00171    if (rpid_avp_name.n==0) {
00172       LM_ERR("rpid avp not defined\n");
00173       return -1;
00174    }
00175 
00176    if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
00177       LM_DBG("no rpid AVP\n");
00178       return -1;
00179    }
00180 
00181    if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
00182       LM_DBG("empty or non-string rpid, nothing to append\n");
00183       return -1;
00184    }
00185 
00186    rpid = val.s;
00187 
00188    rpid_hf.len = RPID_HF_NAME_LEN + rpid_prefix.len + rpid.len
00189                + rpid_suffix.len + CRLF_LEN;
00190    rpid_hf.s = pkg_malloc(rpid_hf.len);
00191    if (!rpid_hf.s) {
00192       LM_ERR("no memory left\n");
00193       return -1;
00194    }
00195 
00196    at = rpid_hf.s;
00197    memcpy(at, RPID_HF_NAME, RPID_HF_NAME_LEN);
00198    at += RPID_HF_NAME_LEN;
00199 
00200    memcpy(at, rpid_prefix.s, rpid_prefix.len);
00201    at += rpid_prefix.len;
00202 
00203    memcpy(at, rpid.s, rpid.len);
00204    at += rpid.len;
00205 
00206    memcpy(at, rpid_suffix.s, rpid_suffix.len);
00207    at += rpid_suffix.len;
00208 
00209    memcpy(at, CRLF, CRLF_LEN);
00210 
00211    if (append_rpid_helper(_m, &rpid_hf) < 0) {
00212       pkg_free(rpid_hf.s);
00213       return -1;
00214    }
00215 
00216    return 1;
00217 }
00218 
00219 
00220 /*!
00221  * \brief Append RPID header field to the message with parameters
00222  * \param _m SIP message
00223  * \param _prefix prefix
00224  * \param _suffix suffix
00225  * \return 1 on success, -1 on failure
00226  */
00227 int append_rpid_hf_p(struct sip_msg* _m, char* _prefix, char* _suffix)
00228 {
00229    struct usr_avp *avp;
00230    str rpid_hf, rpid;
00231    char* at;
00232    str* p, *s;
00233    int_str val;
00234 
00235    if (rpid_avp_name.n==0) {
00236       LM_ERR("rpid avp not defined\n");
00237       return -1;
00238    }
00239 
00240    if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
00241       LM_DBG("no rpid AVP\n");
00242       return -1;
00243    }
00244 
00245    if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
00246       LM_DBG("empty or non-string rpid, nothing to append\n");
00247       return -1;
00248    }
00249 
00250    rpid = val.s;
00251 
00252    p = (str*)_prefix;
00253    s = (str*)_suffix;
00254 
00255    rpid_hf.len = RPID_HF_NAME_LEN + p->len + rpid.len + s->len + CRLF_LEN;
00256    rpid_hf.s = pkg_malloc(rpid_hf.len);
00257    if (!rpid_hf.s) {
00258       LM_ERR("no pkg memory left\n");
00259       return -1;
00260    }
00261 
00262    at = rpid_hf.s;
00263    memcpy(at, RPID_HF_NAME, RPID_HF_NAME_LEN);
00264    at += RPID_HF_NAME_LEN;
00265 
00266    memcpy(at, p->s, p->len);
00267    at += p->len;
00268 
00269    memcpy(at, rpid.s, rpid.len);
00270    at += rpid.len;
00271 
00272    memcpy(at, s->s, s->len);
00273    at += s->len;
00274 
00275    memcpy(at, CRLF, CRLF_LEN);
00276 
00277    if (append_rpid_helper(_m, &rpid_hf) < 0) {
00278       pkg_free(rpid_hf.s);
00279       return -1;
00280    }
00281 
00282    return 1;
00283 }
00284 
00285 
00286 /*!
00287  * \brief Check if URI in RPID AVP contains an E164 user part
00288  * \param _m SIP message
00289  * \param _s1 unused
00290  * \param _s2 unused
00291  * \return 1 if the URI contains an E164 user part, -1 if not
00292  */
00293 int is_rpid_user_e164(struct sip_msg* _m, char* _s1, char* _s2)
00294 {
00295    struct usr_avp *avp;
00296    name_addr_t parsed;
00297    str tmp, rpid;
00298    struct sip_uri uri;
00299    int_str val;
00300 
00301    if (rpid_avp_name.n==0) {
00302       LM_ERR("rpid avp not defined\n");
00303       return -1;
00304    }
00305 
00306    if ( (avp=search_first_avp( rpid_avp_type , rpid_avp_name, &val, 0))==0 ) {
00307       LM_DBG("no rpid AVP\n");
00308       goto err;
00309    }
00310 
00311    if ( !(avp->flags&AVP_VAL_STR) ||  !val.s.s || !val.s.len) {
00312       LM_DBG("empty or non-string rpid, nothing to append\n");
00313       return -1;
00314    }
00315 
00316    rpid = val.s;
00317 
00318    if (find_not_quoted(&rpid, '<')) {
00319       if (parse_nameaddr(&rpid, &parsed) < 0) {
00320          LM_ERR("failed to parse RPID\n");
00321          goto err;
00322       }
00323       tmp = parsed.uri;
00324    } else {
00325       tmp = rpid;
00326    }
00327 
00328    if (parse_uri(tmp.s, tmp.len, &uri) < 0) {
00329        LM_ERR("failed to parse RPID URI\n");
00330        goto err;
00331    }
00332 
00333    return is_e164(&uri.user);
00334 
00335 err:
00336    return -1;
00337 }
00338 

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