1 /**
2 * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
3 *
4 * This file is part of Kamailio, a free SIP server.
5 *
6 * Kamailio is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
10 *
11 * Kamailio is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /*!
22 * \file
23 * \brief Kamailio uac :: UAC send functions
24 * \ingroup uac
25 * Module: \ref uac
26 */
27
28 #include "../../core/dprint.h"
29 #include "../../core/trim.h"
30 #include "../../core/route.h"
31
32 #include "../../modules/tm/tm_load.h"
33
34 #include "../../core/parser/parse_uri.h"
35 #include "../../core/parser/parse_from.h"
36 #include "../../core/parser/parse_to.h"
37 #include "../../core/parser/contact/parse_contact.h"
38 #include "../../core/fmsg.h"
39 #include "../../core/kemi.h"
40
41 #include "auth.h"
42 #include "auth_hdr.h"
43 #include "uac_send.h"
44 #include "uac_reg.h"
45
46 #define MAX_UACH_SIZE 2048
47 #define MAX_UACB_SIZE 32768
48 #define MAX_UACD_SIZE 128
49
50 /** TM bind */
51 struct tm_binds tmb;
52
53 typedef struct _uac_send_info {
54 unsigned int flags;
55 char b_method[32];
56 str s_method;
57 char b_ruri[MAX_URI_SIZE];
58 str s_ruri;
59 char b_turi[MAX_URI_SIZE];
60 str s_turi;
61 char b_furi[MAX_URI_SIZE];
62 str s_furi;
63 char b_callid[128];
64 str s_callid;
65 char b_hdrs[MAX_UACH_SIZE];
66 str s_hdrs;
67 char b_body[MAX_UACB_SIZE];
68 str s_body;
69 char b_ouri[MAX_URI_SIZE];
70 str s_ouri;
71 char b_sock[MAX_URI_SIZE];
72 str s_sock;
73 char b_auser[128];
74 str s_auser;
75 char b_apasswd[64];
76 str s_apasswd;
77 char b_evparam[MAX_UACD_SIZE];
78 str s_evparam;
79 unsigned int evroute;
80 unsigned int evcode;
81 unsigned int evtype;
82 } uac_send_info_t;
83
84 static struct _uac_send_info _uac_req;
85
86 extern str uac_event_callback;
87
uac_send_info_copy(uac_send_info_t * src,uac_send_info_t * dst)88 void uac_send_info_copy(uac_send_info_t *src, uac_send_info_t *dst)
89 {
90 memcpy(dst, src, sizeof(uac_send_info_t));
91 dst->s_method.s = dst->b_method;
92 dst->s_ruri.s = dst->b_ruri;
93 dst->s_turi.s = dst->b_turi;
94 dst->s_furi.s = dst->b_furi;
95 dst->s_hdrs.s = dst->b_hdrs;
96 dst->s_body.s = dst->b_body;
97 dst->s_ouri.s = dst->b_ouri;
98 dst->s_auser.s = dst->b_auser;
99 dst->s_apasswd.s = dst->b_apasswd;
100 dst->s_callid.s = dst->b_callid;
101 dst->s_sock.s = dst->b_sock;
102 dst->s_evparam.s = dst->b_evparam;
103 }
104
uac_send_info_clone(uac_send_info_t * ur)105 uac_send_info_t *uac_send_info_clone(uac_send_info_t *ur)
106 {
107 uac_send_info_t *tp = NULL;
108 tp = (uac_send_info_t*)shm_malloc(sizeof(uac_send_info_t));
109 if(tp==NULL)
110 {
111 SHM_MEM_ERROR;
112 return NULL;
113 }
114 uac_send_info_copy(ur, tp);
115
116 return tp;
117 }
118
pv_get_uac_req(struct sip_msg * msg,pv_param_t * param,pv_value_t * res)119 int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param,
120 pv_value_t *res)
121 {
122 if(param==NULL || tmb.t_request==NULL)
123 return -1;
124
125 switch(param->pvn.u.isname.name.n)
126 {
127 case 0:
128 return pv_get_uintval(msg, param, res, _uac_req.flags);
129 case 1:
130 if(_uac_req.s_ruri.len<=0)
131 return pv_get_null(msg, param, res);
132 return pv_get_strval(msg, param, res, &_uac_req.s_ruri);
133 case 2:
134 if(_uac_req.s_turi.len<=0)
135 return pv_get_null(msg, param, res);
136 return pv_get_strval(msg, param, res, &_uac_req.s_turi);
137 case 3:
138 if(_uac_req.s_furi.len<=0)
139 return pv_get_null(msg, param, res);
140 return pv_get_strval(msg, param, res, &_uac_req.s_furi);
141 case 4:
142 if(_uac_req.s_hdrs.len<=0)
143 return pv_get_null(msg, param, res);
144 return pv_get_strval(msg, param, res, &_uac_req.s_hdrs);
145 case 5:
146 if(_uac_req.s_body.len<=0)
147 return pv_get_null(msg, param, res);
148 return pv_get_strval(msg, param, res, &_uac_req.s_body);
149 case 6:
150 if(_uac_req.s_ouri.len<=0)
151 return pv_get_null(msg, param, res);
152 return pv_get_strval(msg, param, res, &_uac_req.s_ouri);
153 case 7:
154 if(_uac_req.s_method.len<=0)
155 return pv_get_null(msg, param, res);
156 return pv_get_strval(msg, param, res, &_uac_req.s_method);
157 case 8:
158 return pv_get_uintval(msg, param, res, _uac_req.evroute);
159 case 9:
160 if(_uac_req.s_auser.len<=0)
161 return pv_get_null(msg, param, res);
162 return pv_get_strval(msg, param, res, &_uac_req.s_auser);
163 case 10:
164 if(_uac_req.s_apasswd.len<=0)
165 return pv_get_null(msg, param, res);
166 return pv_get_strval(msg, param, res, &_uac_req.s_apasswd);
167 case 11:
168 if(_uac_req.s_callid.len<=0)
169 return pv_get_null(msg, param, res);
170 return pv_get_strval(msg, param, res, &_uac_req.s_callid);
171 case 12:
172 if(_uac_req.s_sock.len<=0)
173 return pv_get_null(msg, param, res);
174 return pv_get_strval(msg, param, res, &_uac_req.s_sock);
175 case 14:
176 if(_uac_req.s_evparam.len<=0)
177 return pv_get_null(msg, param, res);
178 return pv_get_strval(msg, param, res, &_uac_req.s_evparam);
179 case 15:
180 return pv_get_uintval(msg, param, res, _uac_req.evcode);
181 case 16:
182 return pv_get_uintval(msg, param, res, _uac_req.evtype);
183 default:
184 return pv_get_uintval(msg, param, res, _uac_req.flags);
185 }
186 return 0;
187 }
188
pv_set_uac_req(struct sip_msg * msg,pv_param_t * param,int op,pv_value_t * val)189 int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
190 int op, pv_value_t *val)
191 {
192 pv_value_t *tval;
193
194 if(param==NULL || tmb.t_request==NULL)
195 return -1;
196
197 tval = val;
198 if((tval!=NULL) && (tval->flags&PV_VAL_NULL)) {
199 tval = NULL;
200 }
201 switch(param->pvn.u.isname.name.n)
202 {
203 case 0:
204 if(tval==NULL)
205 {
206 _uac_req.flags = 0;
207 _uac_req.s_ruri.len = 0;
208 _uac_req.s_furi.len = 0;
209 _uac_req.s_turi.len = 0;
210 _uac_req.s_ouri.len = 0;
211 _uac_req.s_hdrs.len = 0;
212 _uac_req.s_body.len = 0;
213 _uac_req.s_method.len = 0;
214 _uac_req.s_callid.len = 0;
215 _uac_req.evroute = 0;
216 _uac_req.evtype = 0;
217 _uac_req.evcode = 0;
218 _uac_req.s_evparam.len = 0;
219 }
220 break;
221 case 1:
222 if(tval==NULL)
223 {
224 _uac_req.s_ruri.len = 0;
225 return 0;
226 }
227 if(!(tval->flags&PV_VAL_STR))
228 {
229 LM_ERR("Invalid value type\n");
230 return -1;
231 }
232 if(tval->rs.len>=MAX_URI_SIZE)
233 {
234 LM_ERR("Value size too big\n");
235 return -1;
236 }
237 memcpy(_uac_req.s_ruri.s, tval->rs.s, tval->rs.len);
238 _uac_req.s_ruri.s[tval->rs.len] = '\0';
239 _uac_req.s_ruri.len = tval->rs.len;
240 break;
241 case 2:
242 if(tval==NULL)
243 {
244 _uac_req.s_turi.len = 0;
245 return 0;
246 }
247 if(!(tval->flags&PV_VAL_STR))
248 {
249 LM_ERR("Invalid value type\n");
250 return -1;
251 }
252 if(tval->rs.len>=MAX_URI_SIZE)
253 {
254 LM_ERR("Value size too big\n");
255 return -1;
256 }
257 memcpy(_uac_req.s_turi.s, tval->rs.s, tval->rs.len);
258 _uac_req.s_turi.s[tval->rs.len] = '\0';
259 _uac_req.s_turi.len = tval->rs.len;
260 break;
261 case 3:
262 if(tval==NULL)
263 {
264 _uac_req.s_furi.len = 0;
265 return 0;
266 }
267 if(!(tval->flags&PV_VAL_STR))
268 {
269 LM_ERR("Invalid value type\n");
270 return -1;
271 }
272 if(tval->rs.len>=MAX_URI_SIZE)
273 {
274 LM_ERR("Value size too big\n");
275 return -1;
276 }
277 memcpy(_uac_req.s_furi.s, tval->rs.s, tval->rs.len);
278 _uac_req.s_furi.s[tval->rs.len] = '\0';
279 _uac_req.s_furi.len = tval->rs.len;
280 break;
281 case 4:
282 if(tval==NULL)
283 {
284 _uac_req.s_hdrs.len = 0;
285 return 0;
286 }
287 if(!(tval->flags&PV_VAL_STR))
288 {
289 LM_ERR("Invalid value type\n");
290 return -1;
291 }
292 if(tval->rs.len>=MAX_UACH_SIZE)
293 {
294 LM_ERR("Value size too big\n");
295 return -1;
296 }
297 memcpy(_uac_req.s_hdrs.s, tval->rs.s, tval->rs.len);
298 _uac_req.s_hdrs.s[tval->rs.len] = '\0';
299 _uac_req.s_hdrs.len = tval->rs.len;
300 break;
301 case 5:
302 if(tval==NULL)
303 {
304 _uac_req.s_body.len = 0;
305 return 0;
306 }
307 if(!(tval->flags&PV_VAL_STR))
308 {
309 LM_ERR("Invalid value type\n");
310 return -1;
311 }
312 if(tval->rs.len>=MAX_UACB_SIZE)
313 {
314 LM_ERR("Value size too big\n");
315 return -1;
316 }
317 memcpy(_uac_req.s_body.s, tval->rs.s, tval->rs.len);
318 _uac_req.s_body.s[tval->rs.len] = '\0';
319 _uac_req.s_body.len = tval->rs.len;
320 break;
321 case 6:
322 if(tval==NULL)
323 {
324 _uac_req.s_ouri.len = 0;
325 return 0;
326 }
327 if(!(tval->flags&PV_VAL_STR))
328 {
329 LM_ERR("Invalid value type\n");
330 return -1;
331 }
332 if(tval->rs.len>=MAX_URI_SIZE)
333 {
334 LM_ERR("Value size too big\n");
335 return -1;
336 }
337 memcpy(_uac_req.s_ouri.s, tval->rs.s, tval->rs.len);
338 _uac_req.s_ouri.s[tval->rs.len] = '\0';
339 _uac_req.s_ouri.len = tval->rs.len;
340 break;
341 case 7:
342 if(tval==NULL)
343 {
344 _uac_req.s_method.len = 0;
345 return 0;
346 }
347 if(!(tval->flags&PV_VAL_STR))
348 {
349 LM_ERR("Invalid value type\n");
350 return -1;
351 }
352 if(tval->rs.len>=32)
353 {
354 LM_ERR("Value size too big\n");
355 return -1;
356 }
357 memcpy(_uac_req.s_method.s, tval->rs.s, tval->rs.len);
358 _uac_req.s_method.s[tval->rs.len] = '\0';
359 _uac_req.s_method.len = tval->rs.len;
360 break;
361 case 8:
362 if(tval==NULL)
363 {
364 _uac_req.evroute = 0;
365 return 0;
366 }
367 if(!(tval->flags&PV_VAL_INT))
368 {
369 LM_ERR("Invalid value type\n");
370 return -1;
371 }
372 _uac_req.evroute = tval->ri;
373 break;
374 case 9:
375 if(tval==NULL)
376 {
377 _uac_req.s_auser.len = 0;
378 return 0;
379 }
380 if(!(tval->flags&PV_VAL_STR))
381 {
382 LM_ERR("Invalid auth user type\n");
383 return -1;
384 }
385 if(tval->rs.len>=128)
386 {
387 LM_ERR("Value size too big\n");
388 return -1;
389 }
390 memcpy(_uac_req.s_auser.s, tval->rs.s, tval->rs.len);
391 _uac_req.s_auser.s[tval->rs.len] = '\0';
392 _uac_req.s_auser.len = tval->rs.len;
393 break;
394 case 10:
395 if(tval==NULL)
396 {
397 _uac_req.s_apasswd.len = 0;
398 return 0;
399 }
400 if(!(tval->flags&PV_VAL_STR))
401 {
402 LM_ERR("Invalid auth password type\n");
403 return -1;
404 }
405 if(tval->rs.len>=64)
406 {
407 LM_ERR("Value size too big\n");
408 return -1;
409 }
410 memcpy(_uac_req.s_apasswd.s, tval->rs.s, tval->rs.len);
411 _uac_req.s_apasswd.s[tval->rs.len] = '\0';
412 _uac_req.s_apasswd.len = tval->rs.len;
413 break;
414 case 11:
415 if(tval==NULL)
416 {
417 _uac_req.s_callid.len = 0;
418 return 0;
419 }
420 if(!(tval->flags&PV_VAL_STR))
421 {
422 LM_ERR("Invalid value type\n");
423 return -1;
424 }
425 memcpy(_uac_req.s_callid.s, tval->rs.s, tval->rs.len);
426 _uac_req.s_callid.s[tval->rs.len] = '\0';
427 _uac_req.s_callid.len = tval->rs.len;
428 break;
429 case 12:
430 if(tval==NULL)
431 {
432 _uac_req.s_apasswd.len = 0;
433 return 0;
434 }
435 if(!(tval->flags&PV_VAL_STR))
436 {
437 LM_ERR("Invalid socket pv type\n");
438 return -1;
439 }
440 if(tval->rs.len>=MAX_URI_SIZE)
441 {
442 LM_ERR("Value size too big\n");
443 return -1;
444 }
445 memcpy(_uac_req.s_sock.s, tval->rs.s, tval->rs.len);
446 _uac_req.s_sock.s[tval->rs.len] = '\0';
447 _uac_req.s_sock.len = tval->rs.len;
448 break;
449 case 14:
450 if(tval==NULL)
451 {
452 _uac_req.s_evparam.len = 0;
453 return 0;
454 }
455 if(!(tval->flags&PV_VAL_STR))
456 {
457 LM_ERR("Invalid value type\n");
458 return -1;
459 }
460 if(tval->rs.len>=MAX_UACD_SIZE)
461 {
462 LM_ERR("Value size too big\n");
463 return -1;
464 }
465 memcpy(_uac_req.s_evparam.s, tval->rs.s, tval->rs.len);
466 _uac_req.s_evparam.s[tval->rs.len] = '\0';
467 _uac_req.s_evparam.len = tval->rs.len;
468 break;
469 case 15:
470 if(tval==NULL)
471 {
472 _uac_req.evcode = 0;
473 return 0;
474 }
475 if(!(tval->flags&PV_VAL_INT))
476 {
477 LM_ERR("Invalid value type\n");
478 return -1;
479 }
480 _uac_req.evcode = tval->ri;
481 break;
482 case 16:
483 if(tval==NULL)
484 {
485 _uac_req.evtype = 0;
486 return 0;
487 }
488 if(!(tval->flags&PV_VAL_INT))
489 {
490 LM_ERR("Invalid value type\n");
491 return -1;
492 }
493 _uac_req.evtype = tval->ri;
494 break;
495 }
496 return 0;
497 }
498
pv_parse_uac_req_name(pv_spec_p sp,str * in)499 int pv_parse_uac_req_name(pv_spec_p sp, str *in)
500 {
501 if(sp==NULL || in==NULL || in->len<=0)
502 return -1;
503
504 switch(in->len)
505 {
506 case 3:
507 if(strncmp(in->s, "all", 3)==0)
508 sp->pvp.pvn.u.isname.name.n = 0;
509 else goto error;
510 break;
511 case 4:
512 if(strncmp(in->s, "ruri", 4)==0)
513 sp->pvp.pvn.u.isname.name.n = 1;
514 else if(strncmp(in->s, "turi", 4)==0)
515 sp->pvp.pvn.u.isname.name.n = 2;
516 else if(strncmp(in->s, "furi", 4)==0)
517 sp->pvp.pvn.u.isname.name.n = 3;
518 else if(strncmp(in->s, "hdrs", 4)==0)
519 sp->pvp.pvn.u.isname.name.n = 4;
520 else if(strncmp(in->s, "body", 4)==0)
521 sp->pvp.pvn.u.isname.name.n = 5;
522 else if(strncmp(in->s, "ouri", 4)==0)
523 sp->pvp.pvn.u.isname.name.n = 6;
524 else if(strncmp(in->s, "sock", 4)==0)
525 sp->pvp.pvn.u.isname.name.n = 12;
526 else goto error;
527 break;
528 case 5:
529 if(strncmp(in->s, "auser", 5)==0)
530 sp->pvp.pvn.u.isname.name.n = 9;
531 else goto error;
532 break;
533 case 6:
534 if(strncmp(in->s, "method", 6)==0)
535 sp->pvp.pvn.u.isname.name.n = 7;
536 else if(strncmp(in->s, "callid", 6)==0)
537 sp->pvp.pvn.u.isname.name.n = 11;
538 else if(strncmp(in->s, "evcode", 6)==0)
539 sp->pvp.pvn.u.isname.name.n = 15;
540 else if(strncmp(in->s, "evtype", 6)==0)
541 sp->pvp.pvn.u.isname.name.n = 16;
542 else goto error;
543 break;
544 case 7:
545 if(strncmp(in->s, "evroute", 7)==0)
546 sp->pvp.pvn.u.isname.name.n = 8;
547 else if(strncmp(in->s, "apasswd", 7)==0)
548 sp->pvp.pvn.u.isname.name.n = 10;
549 else if(strncmp(in->s, "evparam", 7)==0)
550 sp->pvp.pvn.u.isname.name.n = 14;
551 else goto error;
552 break;
553 default:
554 goto error;
555 }
556 sp->pvp.pvn.type = PV_NAME_INTSTR;
557 sp->pvp.pvn.u.isname.type = 0;
558
559 return 0;
560
561 error:
562 LM_ERR("unknown uac_req name %.*s\n", in->len, in->s);
563 return -1;
564 }
565
uac_req_init(void)566 void uac_req_init(void)
567 {
568 /* load the TM API */
569 if (load_tm_api(&tmb)!=0) {
570 LM_DBG("can't load TM API - disable it\n");
571 memset(&tmb, 0, sizeof(struct tm_binds));
572 return;
573 }
574 memset(&_uac_req, 0, sizeof(struct _uac_send_info));
575 _uac_req.s_ruri.s = _uac_req.b_ruri;
576 _uac_req.s_furi.s = _uac_req.b_furi;
577 _uac_req.s_turi.s = _uac_req.b_turi;
578 _uac_req.s_ouri.s = _uac_req.b_ouri;
579 _uac_req.s_hdrs.s = _uac_req.b_hdrs;
580 _uac_req.s_body.s = _uac_req.b_body;
581 _uac_req.s_method.s = _uac_req.b_method;
582 _uac_req.s_auser.s = _uac_req.b_auser;
583 _uac_req.s_apasswd.s = _uac_req.b_apasswd;
584 _uac_req.s_callid.s = _uac_req.b_callid;
585 _uac_req.s_sock.s = _uac_req.b_sock;
586 _uac_req.s_evparam.s = _uac_req.b_evparam;
587 return;
588 }
589
uac_send_tmdlg(dlg_t * tmdlg,sip_msg_t * rpl)590 int uac_send_tmdlg(dlg_t *tmdlg, sip_msg_t *rpl)
591 {
592 if(tmdlg==NULL || rpl==NULL)
593 return -1;
594
595 if (parse_headers(rpl, HDR_EOH_F, 0) < 0) {
596 LM_ERR("error while parsing all headers in the reply\n");
597 return -1;
598 }
599 if(parse_to_header(rpl)<0 || parse_from_header(rpl)<0) {
600 LM_ERR("error while parsing From/To headers in the reply\n");
601 return -1;
602 }
603 memset(tmdlg, 0, sizeof(dlg_t));
604
605 str2int(&(get_cseq(rpl)->number), &tmdlg->loc_seq.value);
606 tmdlg->loc_seq.is_set = 1;
607
608 tmdlg->id.call_id = rpl->callid->body;
609 trim(&tmdlg->id.call_id);
610
611 if (get_from(rpl)->tag_value.len) {
612 tmdlg->id.loc_tag = get_from(rpl)->tag_value;
613 }
614 #if 0
615 if (get_to(rpl)->tag_value.len) {
616 tmdlg->id.rem_tag = get_to(rpl)->tag_value;
617 }
618 #endif
619 tmdlg->loc_uri = get_from(rpl)->uri;
620 tmdlg->rem_uri = get_to(rpl)->uri;
621 tmdlg->state= DLG_CONFIRMED;
622 return 0;
623 }
624
625 #define MAX_UACH_SIZE 2048
626
627 /**
628 *
629 */
uac_req_run_event_route(sip_msg_t * msg,uac_send_info_t * tp,int rcode)630 void uac_req_run_event_route(sip_msg_t *msg, uac_send_info_t *tp, int rcode)
631 {
632 char *evrtname = "uac:reply";
633 int rt, backup_rt;
634 struct run_act_ctx ctx;
635 sip_msg_t *fmsg;
636 sr_kemi_eng_t *keng = NULL;
637 int kemi_evroute = 0;
638
639 if(uac_event_callback.s!=NULL && uac_event_callback.len>0) {
640 keng = sr_kemi_eng_get();
641 if(keng==NULL) {
642 LM_DBG("event callback (%s) set, but no cfg engine\n",
643 uac_event_callback.s);
644 return;
645 } else {
646 kemi_evroute = 1;
647 }
648 }
649
650 if (kemi_evroute==0) {
651 rt = route_get(&event_rt, evrtname);
652 if (rt < 0 || event_rt.rlist[rt] == NULL)
653 {
654 LM_DBG("event_route[uac:reply] does not exist\n");
655 return;
656 }
657 }
658
659 uac_send_info_copy(tp, &_uac_req);
660 _uac_req.evcode = rcode;
661 if(msg==NULL)
662 {
663 _uac_req.evtype = 2;
664 fmsg = faked_msg_get_next();
665 } else {
666 _uac_req.evtype = 1;
667 fmsg = msg;
668 }
669
670 backup_rt = get_route_type();
671 set_route_type(REQUEST_ROUTE);
672 init_run_actions_ctx(&ctx);
673
674 if (kemi_evroute==1) {
675 str evrtname = str_init("uac:reply");
676
677 if(sr_kemi_route(keng, fmsg, EVENT_ROUTE,
678 &uac_event_callback, &evrtname)<0) {
679 LM_ERR("error running event route kemi callback\n");
680 }
681 } else {
682 run_top_route(event_rt.rlist[rt], fmsg, 0);
683 }
684 set_route_type(backup_rt);
685 }
686
687 /**
688 * TM resend callback function
689 */
uac_resend_tm_callback(struct cell * t,int type,struct tmcb_params * ps)690 void uac_resend_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
691 {
692 uac_send_info_t *tp = NULL;
693
694 LM_DBG("tm callback with status %d\n", ps->code);
695
696 if(ps->param==NULL || *ps->param==0)
697 {
698 LM_DBG("callback param with message id not received\n");
699 goto done;
700 }
701 tp = (uac_send_info_t*)(*ps->param);
702
703 if(tp->evroute!=0) {
704 uac_req_run_event_route((ps->rpl==FAKED_REPLY)?NULL:ps->rpl,
705 tp, ps->code);
706 }
707
708 done:
709 if(tp!=NULL)
710 shm_free(tp);
711 return;
712
713 }
714
715 /**
716 * TM send callback function
717 */
uac_send_tm_callback(struct cell * t,int type,struct tmcb_params * ps)718 void uac_send_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
719 {
720 int ret;
721 struct hdr_field *hdr;
722 HASHHEX response;
723 str *new_auth_hdr = NULL;
724 static struct authenticate_body auth;
725 struct uac_credential cred;
726 char b_hdrs[MAX_UACH_SIZE];
727 str s_hdrs;
728 uac_req_t uac_r;
729 dlg_t tmdlg;
730 uac_send_info_t *tp = NULL;
731
732 LM_DBG("tm callback with status %d\n", ps->code);
733
734 if(ps->param==NULL || *ps->param==0)
735 {
736 LM_DBG("callback param with message id not received\n");
737 goto done;
738 }
739 tp = (uac_send_info_t*)(*ps->param);
740
741 if(tp->evroute!=0) {
742 uac_req_run_event_route((ps->rpl==FAKED_REPLY)?NULL:ps->rpl,
743 tp, ps->code);
744 }
745
746 if((ps->code != 401 && ps->code != 407) || tp->s_apasswd.len<=0)
747 {
748 LM_DBG("completed with status %d\n", ps->code);
749 goto done;
750 }
751
752 LM_DBG("completed with status %d\n", ps->code);
753
754 hdr = get_autenticate_hdr(ps->rpl, ps->code);
755 if (hdr==0)
756 {
757 LM_ERR("failed to extract authenticate hdr\n");
758 goto error;
759 }
760
761 LM_DBG("auth header body [%.*s]\n",
762 hdr->body.len, hdr->body.s);
763
764 if (parse_authenticate_body(&hdr->body, &auth)<0)
765 {
766 LM_ERR("failed to parse auth hdr body\n");
767 goto error;
768 }
769
770 memset(&cred, 0, sizeof(struct uac_credential));
771 cred.realm = auth.realm;
772 cred.user = tp->s_auser;
773 cred.passwd = tp->s_apasswd;
774
775 do_uac_auth(&tp->s_method, &tp->s_ruri, &cred, &auth, response);
776 new_auth_hdr=build_authorization_hdr(ps->code, &tp->s_ruri, &cred,
777 &auth, response);
778 if (new_auth_hdr==0)
779 {
780 LM_ERR("failed to build authorization hdr\n");
781 goto error;
782 }
783
784 if(tp->s_hdrs.len <= 0) {
785 snprintf(b_hdrs, MAX_UACH_SIZE,
786 "%.*s",
787 new_auth_hdr->len, new_auth_hdr->s);
788 } else {
789 snprintf(b_hdrs, MAX_UACH_SIZE,
790 "%.*s%.*s",
791 tp->s_hdrs.len, tp->s_hdrs.s,
792 new_auth_hdr->len, new_auth_hdr->s);
793 }
794
795 s_hdrs.s = b_hdrs; s_hdrs.len = strlen(s_hdrs.s);
796 pkg_free(new_auth_hdr->s);
797
798 memset(&uac_r, 0, sizeof(uac_r));
799 if(uac_send_tmdlg(&tmdlg, ps->rpl)<0)
800 {
801 LM_ERR("failed to build tm dialog\n");
802 goto error;
803 }
804 tmdlg.rem_target = tp->s_ruri;
805 if(tp->s_ouri.len>0)
806 tmdlg.dst_uri = tp->s_ouri;
807 uac_r.method = &tp->s_method;
808 uac_r.headers = &s_hdrs;
809 uac_r.body = (tp->s_body.len <= 0) ? NULL : &tp->s_body;
810 uac_r.ssock = (tp->s_sock.len <= 0) ? NULL : &tp->s_sock;
811 uac_r.dialog = &tmdlg;
812 uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
813 if(tp->evroute!=0) {
814 /* Callback function */
815 uac_r.cb = uac_resend_tm_callback;
816 /* Callback parameter */
817 uac_r.cbp = (void*)tp;
818 }
819 ret = tmb.t_request_within(&uac_r);
820
821 if(ret<0) {
822 LM_ERR("failed to send request with authentication\n");
823 goto error;
824 }
825
826 if(tp->evroute!=0) {
827 return;
828 }
829
830 done:
831 error:
832 if(tp!=NULL)
833 shm_free(tp);
834 return;
835 }
836
837
uac_req_send(void)838 int uac_req_send(void)
839 {
840 int ret;
841 uac_req_t uac_r;
842 uac_send_info_t *tp = NULL;
843
844 if(_uac_req.s_ruri.len<=0 || _uac_req.s_method.len == 0
845 || tmb.t_request==NULL)
846 return -1;
847
848 memset(&uac_r, '\0', sizeof(uac_r));
849 uac_r.method = &_uac_req.s_method;
850 uac_r.headers = (_uac_req.s_hdrs.len <= 0) ? NULL : &_uac_req.s_hdrs;
851 uac_r.body = (_uac_req.s_body.len <= 0) ? NULL : &_uac_req.s_body;
852
853 if (_uac_req.s_sock.s != NULL && _uac_req.s_sock.len > 0) {
854 uac_r.ssock = &_uac_req.s_sock;
855 } else if(uac_default_socket.s != NULL && uac_default_socket.len > 0) {
856 uac_r.ssock = &uac_default_socket;
857 }
858
859 if((_uac_req.s_auser.len > 0 && _uac_req.s_apasswd.len>0)
860 || (_uac_req.evroute > 0))
861 {
862 tp = uac_send_info_clone(&_uac_req);
863 if(tp==NULL)
864 {
865 LM_ERR("cannot clone the uac structure\n");
866 return -1;
867 }
868
869 uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
870 /* Callback function */
871 uac_r.cb = uac_send_tm_callback;
872 /* Callback parameter */
873 uac_r.cbp = (void*)tp;
874 }
875 uac_r.callid = (_uac_req.s_callid.len <= 0) ? NULL : &_uac_req.s_callid;
876 ret = tmb.t_request(&uac_r, /* UAC Req */
877 &_uac_req.s_ruri, /* Request-URI */
878 (_uac_req.s_turi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_turi, /* To */
879 (_uac_req.s_furi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_furi, /* From */
880 (_uac_req.s_ouri.len<=0)?NULL:&_uac_req.s_ouri /* outbound uri */
881 );
882
883 if(ret<0) {
884 if(tp!=NULL)
885 shm_free(tp);
886 return -1;
887 }
888 return 1;
889 }
890
w_uac_req_send(struct sip_msg * msg,char * s1,char * s2)891 int w_uac_req_send(struct sip_msg *msg, char *s1, char *s2)
892 {
893 return uac_req_send();
894 }
895
ki_uac_req_send(sip_msg_t * msg)896 int ki_uac_req_send(sip_msg_t *msg)
897 {
898 return uac_req_send();
899 }
900