uac/uac.c

Go to the documentation of this file.
00001 /*
00002  * $Id: uac.c 5500 2009-01-23 11:35:02Z carstenbock $
00003  *
00004  * Copyright (C) 2005 Voice Sistem SRL
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * UAC Kamailio-module is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License
00010  * as published by the Free Software Foundation; either version 2
00011  * of the License, or (at your option) any later version.
00012  *
00013  * UAC Kamailio-module 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  *
00023  * History:
00024  * ---------
00025  *  2005-01-31  first version (ramona)
00026  *  2005-08-12  some TM callbacks replaced with RR callback - more efficient;
00027  *              (bogdan)
00028  *  2006-03-02  UAC authentication looks first in AVPs for credential (bogdan)
00029  *  2006-03-03  the RR parameter is encrypted via XOR with a password
00030  *              (bogdan)
00031 
00032  */
00033 
00034 
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 
00039 #include "../../sr_module.h"
00040 #include "../../dprint.h"
00041 #include "../../error.h"
00042 #include "../../pvar.h"
00043 #include "../../mem/mem.h"
00044 #include "../tm/tm_load.h"
00045 #include "../tm/t_hooks.h"
00046 #include "../rr/api.h"
00047 
00048 #include "from.h"
00049 #include "auth.h"
00050 #include "uac_send.h"
00051 
00052 
00053 MODULE_VERSION
00054 
00055 
00056 /* local variable used for init */
00057 static char* from_restore_mode_str = NULL;
00058 static char* auth_username_avp = NULL;
00059 static char* auth_realm_avp = NULL;
00060 static char* auth_password_avp = NULL;
00061 
00062 /* global param variables */
00063 str rr_param = str_init("vsf");
00064 str uac_passwd = str_init("");
00065 int from_restore_mode = FROM_AUTO_RESTORE;
00066 struct tm_binds uac_tmb;
00067 struct rr_binds uac_rrb;
00068 pv_spec_t auth_username_spec;
00069 pv_spec_t auth_realm_spec;
00070 pv_spec_t auth_password_spec;
00071 
00072 static int w_replace_from1(struct sip_msg* msg, char* str, char* str2);
00073 static int w_replace_from2(struct sip_msg* msg, char* str, char* str2);
00074 static int w_restore_from(struct sip_msg* msg,  char* foo, char* bar);
00075 static int w_uac_auth(struct sip_msg* msg, char* str, char* str2);
00076 static int fixup_replace_from1(void** param, int param_no);
00077 static int fixup_replace_from2(void** param, int param_no);
00078 static int mod_init(void);
00079 static void mod_destroy(void);
00080 
00081 
00082 static pv_export_t mod_pvs[] = {
00083    { {"uac_req", sizeof("uac_req")-1}, PVT_OTHER, pv_get_uac_req, pv_set_uac_req,
00084       pv_parse_uac_req_name, 0, 0, 0 },
00085    { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00086 };
00087 
00088 
00089 /* Exported functions */
00090 static cmd_export_t cmds[]={
00091    {"uac_replace_from",  (cmd_function)w_replace_from2,  2, fixup_replace_from2, 0,
00092          REQUEST_ROUTE | BRANCH_ROUTE },
00093    {"uac_replace_from",  (cmd_function)w_replace_from1,  1, fixup_replace_from1, 0,
00094          REQUEST_ROUTE | BRANCH_ROUTE },
00095    {"uac_restore_from",  (cmd_function)w_restore_from,   0,                  0, 0,
00096          REQUEST_ROUTE },
00097    {"uac_auth",          (cmd_function)w_uac_auth,       0,                  0, 0,
00098          FAILURE_ROUTE },
00099    {"uac_req_send",  (cmd_function)uac_req_send,         0,                  0, 0, 
00100       REQUEST_ROUTE | FAILURE_ROUTE |
00101       ONREPLY_ROUTE | BRANCH_ROUTE | ERROR_ROUTE | LOCAL_ROUTE},
00102 
00103    {0,0,0,0,0,0}
00104 };
00105 
00106 
00107 
00108 /* Exported parameters */
00109 static param_export_t params[] = {
00110    {"rr_store_param",    STR_PARAM,                &rr_param.s            },
00111    {"from_restore_mode", STR_PARAM,                &from_restore_mode_str },
00112    {"from_passwd",       STR_PARAM,                &uac_passwd.s          },
00113    {"credential",        STR_PARAM|USE_FUNC_PARAM, (void*)&add_credential },
00114    {"auth_username_avp", STR_PARAM,                &auth_username_avp     },
00115    {"auth_realm_avp",    STR_PARAM,                &auth_realm_avp        },
00116    {"auth_password_avp", STR_PARAM,                &auth_password_avp     },
00117    {0, 0, 0}
00118 };
00119 
00120 
00121 
00122 struct module_exports exports= {
00123    "uac",
00124    DEFAULT_DLFLAGS, /* dlopen flags */
00125    cmds,       /* exported functions */
00126    params,     /* param exports */
00127    0,          /* exported statistics */
00128    0,          /* exported MI functions */
00129    mod_pvs,    /* exported pseudo-variables */
00130    0,          /* extra processes */
00131    mod_init,   /* module initialization function */
00132    0,
00133    mod_destroy,
00134    0  /* per-child init function */
00135 };
00136 
00137 
00138 inline static int parse_auth_avp( char *avp_spec, pv_spec_t *avp, char *txt)
00139 {
00140    str s;
00141    s.s = avp_spec; s.len = strlen(s.s);
00142    if (pv_parse_spec(&s, avp)==NULL) {
00143       LM_ERR("malformed or non AVP %s AVP definition\n",txt);
00144       return -1;
00145    }
00146    return 0;
00147 }
00148 
00149 
00150 static int mod_init(void)
00151 {
00152    if (from_restore_mode_str && *from_restore_mode_str) {
00153       if (strcasecmp(from_restore_mode_str,"none")==0) {
00154          from_restore_mode = FROM_NO_RESTORE;
00155       } else if (strcasecmp(from_restore_mode_str,"manual")==0) {
00156          from_restore_mode = FROM_MANUAL_RESTORE;
00157       } else if (strcasecmp(from_restore_mode_str,"auto")==0) {
00158          from_restore_mode = FROM_AUTO_RESTORE;
00159       } else {
00160          LM_ERR("unsupported value '%s' for from_restore_mode\n",from_restore_mode_str);
00161          goto error;
00162       }
00163    }
00164 
00165    rr_param.len = strlen(rr_param.s);
00166    if (rr_param.len==0 && from_restore_mode!=FROM_NO_RESTORE)
00167    {
00168       LM_ERR("rr_store_param cannot be empty if FROM is restoreable\n");
00169       goto error;
00170    }
00171 
00172    uac_passwd.len = strlen(uac_passwd.s);
00173 
00174    /* parse the auth AVP spesc, if any */
00175    if ( auth_username_avp || auth_password_avp || auth_realm_avp) {
00176       if (!auth_username_avp || !auth_password_avp || !auth_realm_avp) {
00177          LM_ERR("partial definition of auth AVP!");
00178          goto error;
00179       }
00180       if ( parse_auth_avp(auth_realm_avp, &auth_realm_spec, "realm")<0
00181       || parse_auth_avp(auth_username_avp, &auth_username_spec, "username")<0
00182       || parse_auth_avp(auth_password_avp, &auth_password_spec, "password")<0
00183       ) {
00184          goto error;
00185       }
00186    } else {
00187       memset( &auth_realm_spec, 0, sizeof(pv_spec_t));
00188       memset( &auth_password_spec, 0, sizeof(pv_spec_t));
00189       memset( &auth_username_spec, 0, sizeof(pv_spec_t));
00190    }
00191 
00192    /* load the TM API - FIXME it should be loaded only
00193     * if NO_RESTORE and AUTH */
00194    if (load_tm_api(&uac_tmb)!=0) {
00195       LM_ERR("can't load TM API\n");
00196       goto error;
00197    }
00198 
00199    if (from_restore_mode!=FROM_NO_RESTORE) {
00200       /* load the RR API */
00201       if (load_rr_api(&uac_rrb)!=0) {
00202          LM_ERR("can't load RR API\n");
00203          goto error;
00204       }
00205 
00206       if (from_restore_mode==FROM_AUTO_RESTORE) {
00207          /* we need the append_fromtag on in RR */
00208          if (!uac_rrb.append_fromtag) {
00209             LM_ERR("'append_fromtag' RR param is not enabled!"
00210                " - required by AUTO restore mode\n");
00211             goto error;
00212          }
00213          /* get all requests doing loose route */
00214          if (uac_rrb.register_rrcb( rr_checker, 0)!=0) {
00215             LM_ERR("failed to install RR callback\n");
00216             goto error;
00217          }
00218       }
00219    }
00220 
00221    init_from_replacer();
00222 
00223    uac_req_init();
00224 
00225    return 0;
00226 error:
00227    return -1;
00228 }
00229 
00230 
00231 static void mod_destroy(void)
00232 {
00233    destroy_credentials();
00234 }
00235 
00236 
00237 
00238 /************************** fixup functions ******************************/
00239 
00240 static int fixup_replace_from1(void** param, int param_no)
00241 {
00242    pv_elem_t *model;
00243    str s;
00244 
00245    model=NULL;
00246    s.s = (char*)(*param); s.len = strlen(s.s);
00247    if(pv_parse_format(&s, &model)<0)
00248    {
00249       LM_ERR("wrong format[%s]!\n",(char*)(*param));
00250       return E_UNSPEC;
00251    }
00252    if (model==NULL)
00253    {
00254       LM_ERR("empty parameter!\n");
00255       return E_UNSPEC;
00256    }
00257    *param = (void*)model;
00258 
00259    return 0;
00260 }
00261 
00262 
00263 static int fixup_replace_from2(void** param, int param_no)
00264 {
00265    pv_elem_t *model;
00266    char *p;
00267    str s;
00268 
00269    /* convert to str */
00270    s.s = (char*)*param;
00271    s.len = strlen(s.s);
00272 
00273    model=NULL;
00274    if (param_no==1)
00275    {
00276       if (s.len)
00277       {
00278          /* put " around display name */
00279          p = (char*)pkg_malloc(s.len+3);
00280          if (p==0)
00281          {
00282             LM_CRIT("no more pkg mem\n");
00283             return E_OUT_OF_MEM;
00284          }
00285          p[0] = '\"';
00286          memcpy(p+1, s.s, s.len);
00287          p[s.len+1] = '\"';
00288          p[s.len+2] = '\0';
00289          pkg_free(s.s);
00290          s.s = p;
00291          s.len += 2;
00292       }
00293    }
00294    if(s.len!=0)
00295    {
00296       if(pv_parse_format(&s ,&model)<0)
00297       {
00298          LM_ERR("wrong format [%s] for param no %d!\n", s.s, param_no);
00299          pkg_free(s.s);
00300          return E_UNSPEC;
00301       }
00302    }
00303    *param = (void*)model;
00304 
00305    return 0;
00306 }
00307 
00308 
00309 
00310 /************************** wrapper functions ******************************/
00311 
00312 static int w_restore_from(struct sip_msg *msg,  char* foo, char* bar)
00313 {
00314    /* safety checks - must be a request */
00315    if (msg->first_line.type!=SIP_REQUEST) {
00316       LM_ERR("called for something not request\n");
00317       return -1;
00318    }
00319 
00320    return (restore_from(msg,0)==0)?1:-1;
00321 }
00322 
00323 
00324 static int w_replace_from1(struct sip_msg* msg, char* uri, char* str2)
00325 {
00326    str uri_s;
00327 
00328    if(pv_printf_s( msg, (pv_elem_p)uri, &uri_s)!=0)
00329       return -1;
00330    return (replace_from(msg, 0, &uri_s)==0)?1:-1;
00331 }
00332 
00333 
00334 static int w_replace_from2(struct sip_msg* msg, char* dsp, char* uri)
00335 {
00336    str uri_s;
00337    str dsp_s;
00338 
00339    if (dsp!=NULL)
00340    {
00341       if(dsp!=NULL)
00342          if(pv_printf_s( msg, (pv_elem_p)dsp, &dsp_s)!=0)
00343             return -1;
00344    } else {
00345       dsp_s.s = 0;
00346       dsp_s.len = 0;
00347    }
00348 
00349    if(uri!=NULL)
00350    {
00351       if(pv_printf_s( msg, (pv_elem_p)uri, &uri_s)!=0)
00352          return -1;
00353    }
00354 
00355    return (replace_from(msg, &dsp_s, (uri)?&uri_s:0)==0)?1:-1;
00356 }
00357 
00358 
00359 static int w_uac_auth(struct sip_msg* msg, char* str, char* str2)
00360 {
00361    return (uac_auth(msg)==0)?1:-1;
00362 }
00363 
00364 

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