verify.c

Go to the documentation of this file.
00001 /*
00002  * Verification functions
00003  *
00004  * Copyright (C) 2008 Juha Heinanen
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
00021  * USA.
00022  *
00023  */
00024 
00034 #include "../../str.h"
00035 #include "../../lib/kcore/radius.h"
00036 #include "../../usr_avp.h"
00037 #include "../../dprint.h"
00038 #include "../../ut.h"
00039 #include "../../lib/kcore/radius.h"
00040 #include "../../lib/kcore/cmpapi.h"
00041 #include "../../parser/parse_uri.h"
00042 #include "../../parser/parse_from.h"
00043 #include "peering.h"
00044 
00045 
00046 /*
00047  * Extract name and value of an AVP from VALUE_PAIR
00048  */
00049 static inline int extract_avp(VALUE_PAIR* vp, unsigned short *flags,
00050                               int_str *name, int_str *value)
00051 {
00052     static str names, values;
00053     unsigned int r;
00054     char *p;
00055     char *end;
00056 
00057     /* empty? */
00058     if (vp->lvalue==0 || vp->strvalue==0)
00059         goto error;
00060 
00061     p = vp->strvalue;
00062     end = vp->strvalue + vp->lvalue;
00063 
00064     /* get name */
00065     if (*p!='#') {
00066         /* name AVP */
00067         *flags |= AVP_NAME_STR;
00068         names.s = p;
00069     } else {
00070         names.s = ++p;
00071     }
00072 
00073     names.len = 0;
00074     while( p<end && *p!=':' && *p!='#')
00075         p++;
00076     if (names.s==p || p==end) {
00077         LM_ERR("empty AVP name\n");
00078         goto error;
00079     }
00080     names.len = p - names.s;
00081     LM_DBG("AVP name is <%.*s>\n", names.len, names.s);
00082 
00083     /* get value */
00084     if (*p!='#') {
00085         /* string value */
00086         *flags |= AVP_VAL_STR;
00087     }
00088     values.s = ++p;
00089     values.len = end-values.s;
00090     if (values.len==0) {
00091         LM_ERR("Empty AVP value\n");
00092         goto error;
00093     }
00094     LM_DBG("AVP val is <%.*s>\n", values.len, values.s);
00095 
00096     if ( !((*flags)&AVP_NAME_STR) ) {
00097         /* convert name to id*/
00098         if (str2int(&names,&r)!=0 ) {
00099             LM_ERR("invalid AVP ID '%.*s'\n", names.len,names.s);
00100             goto error;
00101         }
00102         name->n = (int)r;
00103     } else {
00104         name->s = names;
00105     }
00106 
00107     if ( !((*flags)&AVP_VAL_STR) ) {
00108         /* convert value to integer */
00109         if (str2int(&values,&r)!=0 ) {
00110             LM_ERR("invalid AVP numerical value '%.*s'\n",
00111                    values.len,values.s);
00112             goto error;
00113         }
00114         value->n = (int)r;
00115     } else {
00116         value->s = values;
00117     }
00118 
00119     return 0;
00120 error:
00121     return -1;
00122 }
00123 
00124 
00125 /*
00126  * Generate AVPs from result of Radius query
00127  */
00128 static int generate_avps(VALUE_PAIR* received)
00129 {
00130     int_str name, val;
00131     unsigned short flags;
00132     VALUE_PAIR *vp;
00133 
00134     vp = received;
00135 
00136     LM_DBG("getting SIP AVPs from avpair %d\n", attrs[A_SIP_AVP].v);
00137 
00138     for(; (vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0)); vp=vp->next) {
00139         flags = 0;
00140         if (extract_avp(vp, &flags, &name, &val) != 0)
00141             continue;
00142         if (add_avp( flags, name, val) < 0) {
00143             LM_ERR("unable to add a new AVP\n");
00144         } else {
00145             LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
00146                    (flags&AVP_NAME_STR)?name.s.len:4,
00147                    (flags&AVP_NAME_STR)?name.s.s:"null",
00148                    (flags&AVP_NAME_STR)?0:name.n,
00149                    (flags&AVP_VAL_STR)?val.s.len:4,
00150                    (flags&AVP_VAL_STR)?val.s.s:"null",
00151                    (flags&AVP_VAL_STR)?0:val.n );
00152         }
00153     }
00154     
00155     return 0;
00156 }
00157 
00158 
00159 /* 
00160  * Send Radius request to verify destination and generate AVPs from
00161  * reply items of positive response.
00162  */
00163 int verify_destination(struct sip_msg* _msg, char* s1, char* s2)
00164 {
00165     VALUE_PAIR* send, *received;
00166     uint32_t service;
00167     static char rad_msg[4096];
00168     int i;
00169 
00170     send = received = 0;
00171 
00172     /* Add Request-URI host A_USER_NAME and user as A_SIP_URI_USER */
00173     if (parse_sip_msg_uri(_msg) < 0) {
00174         LM_ERR("error while parsing Request-URI\n");
00175         return -1;
00176     }
00177     
00178     if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
00179                        _msg->parsed_uri.host.s,
00180                        _msg->parsed_uri.host.len, 0)) {
00181         LM_ERR("error adding PW_USER_NAME\n");
00182         goto err;
00183     }
00184    
00185     if (!rc_avpair_add(rh, &send, attrs[A_SIP_URI_USER].v,
00186                        _msg->parsed_uri.user.s,
00187                        _msg->parsed_uri.user.len, 0)) {
00188         LM_ERR("error adding PW_SIP_URI_USER\n");
00189         goto err;
00190     }
00191 
00192     /* Add From Tag */
00193     if (parse_from_header(_msg) < 0) {
00194         LM_ERR("error while parsing From header field\n");
00195         goto err;
00196     }
00197 
00198     if ((_msg->from==NULL) || (get_from(_msg) == NULL) ||
00199         (get_from(_msg)->tag_value.s == NULL) ||
00200         (get_from(_msg)->tag_value.len <= 0)) {
00201         LM_ERR("error while accessing From header tag\n");
00202         goto err;
00203     }
00204     
00205     if (!rc_avpair_add(rh, &send, attrs[A_SIP_FROM_TAG].v,
00206                        get_from(_msg)->tag_value.s,
00207                        get_from(_msg)->tag_value.len, 0)) {
00208         LM_ERR("error adding PW_SIP_FROM_TAG\n");
00209         goto err;
00210     }
00211 
00212     /* Add Call-Id */
00213     if ((parse_headers(_msg, HDR_CALLID_F, 0) == -1) ||
00214         (_msg->callid == NULL) || (_msg->callid->body.s == NULL) ||
00215         (_msg->callid->body.len <= 0)) {
00216         LM_ERR("error while accessing Call-Id\n");
00217         goto err;
00218     }
00219 
00220     if (!rc_avpair_add(rh, &send, attrs[A_SIP_CALL_ID].v,
00221                        _msg->callid->body.s,
00222                        _msg->callid->body.len, 0)) {
00223         LM_ERR("error adding PW_SIP_CALL_ID\n");
00224         goto err;
00225     }
00226     
00227     /* Add Service-Type */
00228     service = vals[V_SIP_VERIFY_DESTINATION].v;
00229     if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v,
00230                        &service, -1, 0)) {
00231         LM_ERR("error adding PW_SERVICE_TYPE\n");
00232         goto err;
00233     }
00234     
00235     /* Send Request and generate AVPs of positive reply */
00236     if ((i = rc_auth(rh, SIP_PORT, send, &received, rad_msg)) == OK_RC) {
00237         LM_DBG("success\n");
00238         rc_avpair_free(send);
00239         generate_avps(received);
00240         rc_avpair_free(received);
00241         return 1;
00242     } else {
00243 #ifdef REJECT_RC
00244         if (i == REJECT_RC) {
00245             LM_DBG("rejected\n");
00246         } else {
00247             LM_ERR("failure\n");
00248         }
00249         goto err;
00250 #else
00251         LM_DBG("failure\n");
00252         goto err;
00253 #endif
00254     }
00255 
00256 err:
00257     if (send) rc_avpair_free(send);
00258     if (received) rc_avpair_free(received);
00259     return -1;
00260 }
00261 
00262 
00263 /* 
00264  * Send Radius request to verify source.
00265  */
00266 int verify_source(struct sip_msg* _msg, char* s1, char* s2)
00267 {
00268     VALUE_PAIR* send, *received;
00269     struct hdr_field *hf;
00270     uint32_t service;
00271     static char rad_msg[4096];
00272     int i;
00273 
00274     send = received = 0;
00275  
00276     /* Add Request-URI host A_USER_NAME and user as A_SIP_URI_USER */
00277     if (parse_sip_msg_uri(_msg) < 0) {
00278         LM_ERR("error while parsing Request-URI\n");
00279         return -1;
00280     }
00281 
00282     if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v,
00283                        _msg->parsed_uri.host.s,
00284                        _msg->parsed_uri.host.len, 0)) {
00285         LM_ERR("error adding PW_USER_NAME\n");
00286         goto err;
00287     }
00288    
00289     if (!rc_avpair_add(rh, &send, attrs[A_SIP_URI_USER].v,
00290                        _msg->parsed_uri.user.s,
00291                        _msg->parsed_uri.user.len, 0)) {
00292         LM_ERR("error adding PW_SIP_URI_USER\n");
00293         goto err;
00294     }
00295 
00296     /* Add From Tag */
00297     if (parse_from_header(_msg) < 0) {
00298         LM_ERR("error while parsing From header field\n");
00299         goto err;
00300     }
00301 
00302     if ((_msg->from==NULL) || (get_from(_msg) == NULL) ||
00303         (get_from(_msg)->tag_value.s == NULL) ||
00304         (get_from(_msg)->tag_value.len <= 0)) {
00305         LM_ERR("error while accessing From header tag\n");
00306         goto err;
00307     }
00308     
00309     if (!rc_avpair_add(rh, &send, attrs[A_SIP_FROM_TAG].v,
00310                        get_from(_msg)->tag_value.s,
00311                        get_from(_msg)->tag_value.len, 0)) {
00312         LM_ERR("error adding PW_SIP_FROM_TAG\n");
00313         goto err;
00314     }
00315 
00316     /* Add Call-Id */
00317     if ((parse_headers(_msg, HDR_CALLID_F, 0) == -1) ||
00318         (_msg->callid == NULL) || (_msg->callid->body.s == NULL) ||
00319         (_msg->callid->body.len <= 0)) {
00320         LM_ERR("error while accessing Call-Id\n");
00321         goto err;
00322     }
00323 
00324     if (!rc_avpair_add(rh, &send, attrs[A_SIP_CALL_ID].v,
00325                        _msg->callid->body.s,
00326                        _msg->callid->body.len, 0)) {
00327         LM_ERR("error adding PW_SIP_CALL_ID\n");
00328         goto err;
00329     }
00330 
00331     /* Add P-Request-Hash header body */
00332     parse_headers(_msg, HDR_EOH_F, 0);
00333     for (hf = _msg->headers; hf; hf = hf->next) {
00334                 if(cmp_hdrname_strzn(&hf->name, "P-Request-Hash",
00335                         sizeof("P-Request-Hash") - 1) == 0)
00336             break;
00337     }
00338     if (!hf) {
00339         LM_ERR("no P-Request-Hash header field\n");
00340         goto err;
00341     }
00342     if ((hf->body.s == NULL) || (hf->body.len <= 0)) {
00343         LM_ERR("error while accessing P-Request-Hash body\n");
00344         goto err;
00345     }
00346     if (!rc_avpair_add(rh, &send, attrs[A_SIP_REQUEST_HASH].v,
00347                        hf->body.s, hf->body.len, 0)) {
00348         LM_ERR("error adding PW_SIP_REQUEST_HASH\n");
00349         goto err;
00350     }
00351     
00352     /* Add Service-Type */
00353     service = vals[V_SIP_VERIFY_SOURCE].v;
00354     if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v,
00355                        &service, -1, 0)) {
00356         LM_ERR("error adding PW_SERVICE_TYPE\n");
00357         goto err;
00358     }
00359     
00360     /* Send Request and generate AVPs of positive reply */
00361     if ((i = rc_auth(rh, SIP_PORT, send, &received, rad_msg)) == OK_RC) {
00362         LM_DBG("success\n");
00363         rc_avpair_free(send);
00364         rc_avpair_free(received);
00365         return 1;
00366     } else {
00367 #ifdef REJECT_RC
00368         if (i == REJECT_RC) {
00369             LM_DBG("rejected\n");
00370         } else {
00371             LM_ERR("failure\n");
00372         }
00373         goto err;
00374 #else
00375         LM_DBG("failure\n");
00376         goto err;
00377 #endif
00378     }
00379 
00380 err:
00381     if (send) rc_avpair_free(send);
00382     if (received) rc_avpair_free(received);
00383     return -1;
00384 }