d103120d3e90082bf0a01c306f9341d2599ca7b6
[sip-router] / src / modules / h350 / h350_mod.c
1 /* 
2  * Kamailio H.350 Module
3  *
4  * Copyright (C) 2007 University of North Carolina
5  *
6  * Original author: Christian Schlatter, cs@unc.edu
7  * 
8  *
9  * This file is part of Kamailio, a free SIP server.
10  *
11  * Kamailio is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version
15  *
16  * Kamailio is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License 
22  * along with this program; if not, write to the Free Software 
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24  *
25  */
26
27 #include "../../core/ut.h"
28 #include "../../core/sr_module.h"
29 #include "h350_mod.h"
30 #include "h350_exp_fn.h"
31
32
33 MODULE_VERSION
34
35 /*
36  * Module management function prototypes
37  */
38 static int mod_init(void);
39 static int child_init(int rank);
40
41 /*
42  * fixup functions
43  */
44 static int one_str_pv_elem_fixup(void** param, int param_no);
45 static int h350_auth_lookup_fixup(void** param, int param_no);
46
47 /*
48  * exported functions
49  */
50
51 static int w_h350_sipuri_lookup(struct sip_msg* msg, char* sip_uri, char* s2);
52 static int w_h350_auth_lookup(struct sip_msg* msg, char* digest_username, char* avp_specs);
53 static int w_h350_call_preferences(struct sip_msg* msg, char* avp_name_prefix, char* s2);
54 static int w_h350_service_level(struct sip_msg* msg, char* avp_name_prefix, char* s2);
55
56 /*
57  * Module parameter variables
58  */
59 char* h350_ldap_session = H350_LDAP_SESSION;
60 char* h350_base_dn = H350_BASE_DN;
61 char* h350_search_scope = H350_SEARCH_SCOPE;
62 int h350_search_scope_int = -1;
63
64
65 /*
66  * LDAP API
67  */
68 ldap_api_t ldap_api;
69
70 /*
71  * Exported functions
72  */
73 static cmd_export_t cmds[] = {
74         {"h350_sipuri_lookup",           (cmd_function)w_h350_sipuri_lookup,     1,
75          one_str_pv_elem_fixup, 0,
76          REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
77         {"h350_auth_lookup",             (cmd_function)w_h350_auth_lookup,       2,
78          h350_auth_lookup_fixup, 0,
79          REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
80         {"h350_result_call_preferences", (cmd_function)w_h350_call_preferences,  1,
81          one_str_pv_elem_fixup, 0,
82          REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
83         {"h350_result_service_level",    (cmd_function)w_h350_service_level,     1,
84          one_str_pv_elem_fixup, 0,
85          REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|ONREPLY_ROUTE|LOCAL_ROUTE},
86         {0, 0, 0, 0, 0, 0}
87 };
88
89
90 /*
91  * Exported parameters
92  */
93 static param_export_t params[] = {
94         {"ldap_session",     PARAM_STRING, &h350_ldap_session},
95         {"base_dn",          PARAM_STRING, &h350_base_dn},
96         {"search_scope",     PARAM_STRING, &h350_search_scope},
97         {0, 0, 0}
98 };
99
100
101 /*
102  * Module interface
103  */
104 struct module_exports exports = {
105         "h350", 
106         DEFAULT_DLFLAGS, /* dlopen flags */
107         cmds,       /* Exported functions */
108         params,     /* Exported parameters */
109         0,          /* exported statistics */
110         0,          /* exported MI functions */
111         0,          /* exported pseudo-variables */
112         0,          /* extra processes */
113         mod_init,   /* module initialization function */
114         0,          /* response function */
115         0,          /* destroy function */
116         child_init  /* child initialization function */
117 };
118
119 static int child_init(int rank)
120 {
121         
122         /* don't do anything for non-worker process */
123         if (rank < 1) {
124                 return 0;
125         }
126
127         h350_search_scope_int = ldap_api.ldap_str2scope(h350_search_scope);
128
129         /*
130          * initialize h350_exp_fn
131          */
132         if (h350_exp_fn_init() != 0)
133         {
134                  LM_ERR("h350_exp_fn_init failed\n");
135                  return -1;
136         }
137
138         
139         return 0;
140 }
141
142
143 static int mod_init(void)
144 {
145         /*
146          * load the LDAP API
147          */
148         if (load_ldap_api(&ldap_api) != 0)
149         {
150                 LM_ERR("Unable to load LDAP API - this module requires ldap module\n");
151                 return -1;
152         }
153
154         return 0;
155
156         /*
157          * check module parameters
158          */
159         if (ldap_api.ldap_str2scope(h350_search_scope) == -1)
160         {
161                 LM_ERR("Invalid search_scope [%s]\n", h350_search_scope);
162                 return -1;
163         }
164         
165 }
166
167
168 /*
169  * EXPORTED functions
170  */
171 static int w_h350_sipuri_lookup(struct sip_msg* msg, char* sip_uri, char* s2)
172 {
173         return h350_sipuri_lookup(msg, (pv_elem_t*)sip_uri);
174 }
175
176 static int w_h350_auth_lookup(struct sip_msg* msg, char* digest_username, char* avp_specs)
177 {
178         return h350_auth_lookup(
179                 msg, 
180                 (pv_elem_t*)digest_username, 
181                 (struct h350_auth_lookup_avp_params*)avp_specs);
182 }
183
184 static int w_h350_call_preferences(struct sip_msg* msg, char* avp_name_prefix, char* s2)
185 {
186         return h350_call_preferences(msg, (pv_elem_t*)avp_name_prefix);
187 }
188
189 static int w_h350_service_level(struct sip_msg* msg, char* avp_name_prefix, char* s2)
190 {
191         return h350_service_level(msg, (pv_elem_t*)avp_name_prefix);
192 }
193
194 /*
195  * FIXUP functions
196  */
197
198 static int one_str_pv_elem_fixup(void** param, int param_no)
199 {
200         pv_elem_t *model;
201         str s;
202
203         if (param_no == 1) {
204                 s.s = (char*)*param;
205                 if (s.s==0 || s.s[0]==0) {
206                         model = 0;
207                 } else {
208                         s.len = strlen(s.s);
209                         if (pv_parse_format(&s,&model)<0) {
210                                 LM_ERR("pv_parse_format failed\n");
211                                 return E_OUT_OF_MEM;
212                         }
213                 }
214                 *param = (void*)model;
215         }
216
217         return 0;
218 }
219
220 static int h350_auth_lookup_fixup(void** param, int param_no)
221 {
222         pv_elem_t *model;
223     char *p, *username_avp_spec_str, *pwd_avp_spec_str;
224         str s;
225         struct h350_auth_lookup_avp_params *params;
226
227     if (param_no == 1) 
228         {
229                 s.s = (char*)*param;
230                 if (s.s==0 || s.s[0]==0) {
231             model = 0;
232                 } else {
233             if (pv_parse_format(&s,&model)<0) {
234                 LM_ERR("pv_parse_format failed\n");
235                 return E_OUT_OF_MEM;
236             }
237         }
238         *param = (void*)model;
239     } else if (param_no == 2) {
240                 /*
241                  * parse *param into username_avp_spec_str and pwd_avp_spec_str
242                  */
243                 
244                 username_avp_spec_str = (char*)*param;
245                 if ((pwd_avp_spec_str = strchr(username_avp_spec_str, '/')) == 0)
246                 {
247                         /* no '/' found in username_avp_spec_str */
248                         LM_ERR("invalid second argument [%s]\n", username_avp_spec_str);
249                         return E_UNSPEC;
250                 }
251                 *(pwd_avp_spec_str++) = 0;
252
253                 /*
254                  * parse avp specs into pv_spec_t and store in params
255                  */
256                 params = (struct h350_auth_lookup_avp_params*)pkg_malloc
257                                 (sizeof(struct h350_auth_lookup_avp_params));
258                 if (params == NULL)
259                 {
260                         LM_ERR("no memory\n");
261                         return E_OUT_OF_MEM;
262                 }
263                 memset(params, 0, sizeof(struct h350_auth_lookup_avp_params));
264                 s.s = username_avp_spec_str; s.len = strlen(s.s);
265                 p = pv_parse_spec(&s, &params->username_avp_spec);
266                 if (p == 0)
267                 {
268                         pkg_free(params);
269                         LM_ERR("parse error for [%s]\n", username_avp_spec_str);
270                         return E_UNSPEC;
271                 }
272                 if (params->username_avp_spec.type != PVT_AVP)
273                 {
274                         pkg_free(params);
275                         LM_ERR("invalid AVP specification [%s]\n", username_avp_spec_str);
276                         return E_UNSPEC;
277                 }
278                 s.s = pwd_avp_spec_str; s.len =  strlen(s.s);
279                 p = pv_parse_spec(&s, &params->password_avp_spec);
280                 if (p == 0)
281                 {
282                         pkg_free(params);
283                         LM_ERR("parse error for [%s]\n", pwd_avp_spec_str);
284                         return E_UNSPEC;
285                 }
286                 if (params->password_avp_spec.type != PVT_AVP)
287                 {
288                         pkg_free(params);
289                         LM_ERR("invalid AVP specification [%s]\n", pwd_avp_spec_str);
290                         return E_UNSPEC;
291                 }
292
293                 *param = (void*)params;
294         }
295
296         return 0;
297 }