1 /*
2 	belle-sip - SIP (RFC3261) library.
3 	Copyright (C) 2010  Belledonne Communications SARL
4 
5 	This program is free software: you can redistribute it and/or modify
6 	it under the terms of the GNU General Public License as published by
7 	the Free Software Foundation, either version 2 of the License, or
8 	(at your option) any later version.
9 
10 	This program is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "belle_sip_internal.h"
20 #include "listeningpoint_internal.h"
21 #include "md5.h"
22 #include "belle-sip/message.h"
23 static void  belle_sip_provider_update_or_create_auth_context(belle_sip_provider_t *p,belle_sip_header_call_id_t* call_id,belle_sip_header_www_authenticate_t* authenticate,belle_sip_uri_t *from_uri,const char* realm) ;
24 struct authorization_context {
25 	belle_sip_header_call_id_t* callid;
26 	const char* scheme;
27 	const char* realm;
28 	const char* nonce;
29 	const char* qop;
30 	const char* opaque;
31 	const char* user_id;
32 	const char* algorithm;
33 	int nonce_count;
34 	int is_proxy;
35 };
36 
GET_SET_STRING(authorization_context,realm)37 GET_SET_STRING(authorization_context,realm)
38 GET_SET_STRING(authorization_context,nonce)
39 GET_SET_STRING(authorization_context,qop)
40 GET_SET_STRING(authorization_context,scheme)
41 GET_SET_STRING(authorization_context,opaque)
42 GET_SET_STRING(authorization_context,user_id)
43 GET_SET_STRING(authorization_context,algorithm)
44 GET_SET_INT(authorization_context,nonce_count,int)
45 static authorization_context_t* belle_sip_authorization_create(belle_sip_header_call_id_t* call_id) {
46 	authorization_context_t* result = malloc(sizeof(authorization_context_t));
47 	memset(result,0,sizeof(authorization_context_t));
48 	result->callid=call_id;
49 	belle_sip_object_ref(result->callid);
50 	return result;
51 }
belle_sip_authorization_destroy(authorization_context_t * object)52 void belle_sip_authorization_destroy(authorization_context_t* object) {
53 	DESTROY_STRING(object,scheme);
54 	DESTROY_STRING(object,realm);
55 	DESTROY_STRING(object,nonce);
56 	DESTROY_STRING(object,qop);
57 	DESTROY_STRING(object,opaque);
58 	DESTROY_STRING(object,user_id);
59 	DESTROY_STRING(object,algorithm);
60 	belle_sip_object_unref(object->callid);
61 	belle_sip_free(object);
62 }
63 
finalize_transaction(belle_sip_transaction_t * tr)64 static void finalize_transaction(belle_sip_transaction_t *tr){
65 	belle_sip_transaction_state_t state=belle_sip_transaction_get_state(tr);
66 	if (state!=BELLE_SIP_TRANSACTION_TERMINATED){
67 		belle_sip_message("Transaction [%p] still in state [%s], will force termination.",tr,belle_sip_transaction_state_to_string(state));
68 		belle_sip_transaction_terminate(tr);
69 	}
70 }
71 
finalize_transactions(const belle_sip_list_t * l)72 static void finalize_transactions(const belle_sip_list_t *l){
73 	belle_sip_list_t *copy=belle_sip_list_copy(l);
74 	belle_sip_list_free_with_data(copy,(void (*)(void*))finalize_transaction);
75 }
76 
belle_sip_provider_uninit(belle_sip_provider_t * p)77 static void belle_sip_provider_uninit(belle_sip_provider_t *p){
78 	finalize_transactions(p->client_transactions);
79 	p->client_transactions=NULL;
80 	finalize_transactions(p->server_transactions);
81 	p->server_transactions=NULL;
82 	p->listeners=belle_sip_list_free(p->listeners);
83 	p->internal_listeners=belle_sip_list_free(p->internal_listeners);
84 	p->auth_contexts=belle_sip_list_free_with_data(p->auth_contexts,(void(*)(void*))belle_sip_authorization_destroy);
85 	p->dialogs=belle_sip_list_free_with_data(p->dialogs,belle_sip_object_unref);
86 	p->lps=belle_sip_list_free_with_data(p->lps,belle_sip_object_unref);
87 }
88 
channel_state_changed(belle_sip_channel_listener_t * obj,belle_sip_channel_t * chan,belle_sip_channel_state_t state)89 static void channel_state_changed(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_channel_state_t state){
90 	belle_sip_io_error_event_t ev;
91 	belle_sip_provider_t* prov=BELLE_SIP_PROVIDER(obj);
92 	if (state == BELLE_SIP_CHANNEL_ERROR || state == BELLE_SIP_CHANNEL_DISCONNECTED) {
93 		ev.transport=belle_sip_channel_get_transport_name(chan);
94 		ev.port=chan->peer_port;
95 		ev.host=chan->peer_name;
96 		ev.source=BELLE_SIP_OBJECT(prov);
97 		BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_io_error,&ev);
98 		/*IO error is also relevant for internal listener like refreshers*/
99 		BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->internal_listeners,process_io_error,&ev);
100 		if (!chan->force_close) belle_sip_provider_release_channel(prov,chan);
101 	}
102 }
103 
notify_client_transaction_match(const void * transaction,const void * notify)104 static int notify_client_transaction_match(const void *transaction, const void *notify){
105 	belle_sip_client_transaction_t *tr=(belle_sip_client_transaction_t*)transaction;
106 	belle_sip_request_t *notify_req=(belle_sip_request_t*)notify;
107 	return !belle_sip_client_transaction_is_notify_matching_pending_subscribe(tr,notify_req);
108 }
109 
belle_sip_provider_find_matching_pending_subscribe_client_transaction_from_notify_req(belle_sip_provider_t * prov,belle_sip_request_t * req)110 belle_sip_client_transaction_t * belle_sip_provider_find_matching_pending_subscribe_client_transaction_from_notify_req(belle_sip_provider_t *prov, belle_sip_request_t *req) {
111 	belle_sip_list_t* elem;
112 	if (strcmp("NOTIFY",belle_sip_request_get_method(req)) != 0) {
113 		belle_sip_error("belle_sip_provider_find_matching_pending_subscribe_client_transaction_from_notify_req requires a NOTIFY request, not a [%s], on prov [%p]"
114 						,belle_sip_request_get_method(req)
115 						,prov);
116 	}
117 	elem=belle_sip_list_find_custom(prov->client_transactions,notify_client_transaction_match,req);
118 	return elem?BELLE_SIP_CLIENT_TRANSACTION(elem->data):NULL;
119 }
120 
belle_sip_provider_dispatch_request(belle_sip_provider_t * prov,belle_sip_request_t * req)121 static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, belle_sip_request_t *req){
122 	belle_sip_server_transaction_t *t;
123 	belle_sip_request_event_t ev;
124 	t=belle_sip_provider_find_matching_server_transaction(prov,req);
125 	if (t){
126 		belle_sip_object_ref(t);
127 		belle_sip_server_transaction_on_request(t,req);
128 		belle_sip_object_unref(t);
129 	}else{
130 		const char *method=belle_sip_request_get_method(req);
131 		ev.dialog=NULL;
132 		/* Should we limit to ACK ?  */
133 		/*Search for a dialog if exist */
134 
135 		if (strcmp("CANCEL",method) == 0) {
136 			/* Call leg does not exist */
137 			belle_sip_server_transaction_t *tr = belle_sip_provider_create_server_transaction(prov, req);
138 			belle_sip_server_transaction_send_response(tr, belle_sip_response_create_from_request(req, 481));
139 			return;
140 		}
141 
142 		ev.dialog=belle_sip_provider_find_dialog_from_message(prov,(belle_sip_message_t*)req,1/*request=uas*/);
143 		if (ev.dialog){
144 			if (strcmp("ACK",method)==0){
145 				if (belle_sip_dialog_handle_ack(ev.dialog,req)==-1){
146 					/*absorbed ACK retransmission, ignore */
147 					return;
148 				}
149 			}else if ((strcmp("INVITE",method)==0)&&(ev.dialog->needs_ack)){
150 				belle_sip_dialog_stop_200Ok_retrans(ev.dialog);
151 			}else if (!belle_sip_dialog_is_authorized_transaction(ev.dialog,method)){
152 				belle_sip_server_transaction_t *tr=belle_sip_provider_create_server_transaction(prov,req);
153 				belle_sip_server_transaction_send_response(tr,
154 					belle_sip_response_create_from_request(req,491));
155 				return;
156 			}
157 		} else if (strcmp("NOTIFY",method) == 0) {
158 			/*search for matching subscribe*/
159 			belle_sip_client_transaction_t *sub = belle_sip_provider_find_matching_pending_subscribe_client_transaction_from_notify_req(prov,req);
160 			if (sub) {
161 				belle_sip_message("Found matching subscribe for NOTIFY [%p], creating dialog",req);
162 				ev.dialog=belle_sip_provider_create_dialog_internal(prov,BELLE_SIP_TRANSACTION(sub),FALSE);
163 			}
164 		}
165 
166 		if (prov->unconditional_answer_enabled && strcmp("ACK",method)!=0) { /*always answer predefined value (I.E 480 by default)*/
167 			belle_sip_server_transaction_t *tr=belle_sip_provider_create_server_transaction(prov,req);
168 			belle_sip_server_transaction_send_response(tr,belle_sip_response_create_from_request(req,prov->unconditional_answer));
169 			return;
170 		} else {
171 			ev.source=(belle_sip_object_t*)prov;
172 			ev.server_transaction=NULL;
173 			ev.request=req;
174 			BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_request_event,&ev);
175 		}
176 	}
177 }
178 
179 static belle_sip_list_t*  belle_sip_provider_get_auth_context_by_realm_or_call_id(belle_sip_provider_t *p,belle_sip_header_call_id_t* call_id,belle_sip_uri_t *from_uri,const char* realm);
180 
belle_sip_auth_context_find_by_nonce(const void * elem,const void * nonce_value)181 static int belle_sip_auth_context_find_by_nonce(const void* elem, const void* nonce_value){
182 	authorization_context_t * a = (authorization_context_t*)elem;
183 
184 	return strcmp(a->nonce, (const char*)nonce_value);
185 }
186 
belle_sip_provider_dispatch_response(belle_sip_provider_t * p,belle_sip_response_t * msg)187 static void belle_sip_provider_dispatch_response(belle_sip_provider_t* p, belle_sip_response_t *msg){
188 	belle_sip_client_transaction_t *t;
189 	t=belle_sip_provider_find_matching_client_transaction(p,msg);
190 
191 	/*good opportunity to cleanup auth context if answer = 401|407|403*/
192 
193 	switch (belle_sip_response_get_status_code(msg)) {
194 	case 401:
195 	case 403:
196 	case 407: {
197 		if (t!=NULL){
198 			const char* nonce = NULL;
199 			belle_sip_message_t* req = BELLE_SIP_MESSAGE(belle_sip_transaction_get_request((belle_sip_transaction_t*)t));
200 			belle_sip_header_authorization_t* authorization=BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_message_get_header_by_type(req, belle_sip_header_proxy_authorization_t));
201 			if (authorization==NULL) authorization=belle_sip_message_get_header_by_type(req, belle_sip_header_authorization_t);
202 			if (authorization!=NULL){
203 				nonce = belle_sip_header_authorization_get_nonce(authorization);
204 				if (nonce != NULL){
205 					belle_sip_list_t * auth_context_with_nonce = NULL;
206 					while ((auth_context_with_nonce = belle_sip_list_find_custom(p->auth_contexts, belle_sip_auth_context_find_by_nonce, nonce)) != NULL){
207 						belle_sip_authorization_destroy(auth_context_with_nonce->data);
208 						p->auth_contexts = belle_sip_list_delete_link(p->auth_contexts, auth_context_with_nonce);
209 					}
210 				}
211 			}
212 		}
213 		break;
214 	}
215 		default:
216 			if (t!=NULL){
217 				belle_sip_message_t* req = BELLE_SIP_MESSAGE(belle_sip_transaction_get_request((belle_sip_transaction_t*)t));
218 				belle_sip_header_authentication_info_t *authentication_info = belle_sip_message_get_header_by_type(msg,belle_sip_header_authentication_info_t);
219 				belle_sip_list_t *authorization_lst = NULL;
220 				belle_sip_header_call_id_t *call_id = belle_sip_message_get_header_by_type(msg,belle_sip_header_call_id_t);
221 				belle_sip_header_from_t *from = belle_sip_message_get_header_by_type(req,belle_sip_header_from_t);
222 				belle_sip_uri_t *from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)from);
223 				/*searching for authentication headers*/
224 				authorization_lst = belle_sip_list_copy(belle_sip_message_get_headers(BELLE_SIP_MESSAGE(req),BELLE_SIP_AUTHORIZATION));
225 				/*search for proxy authenticate*/
226 				authorization_lst=belle_sip_list_concat(authorization_lst,belle_sip_list_copy(belle_sip_message_get_headers(BELLE_SIP_MESSAGE(req),BELLE_SIP_PROXY_AUTHORIZATION)));
227 				/*update auth contexts with authenticate headers from response*/
228 				for (;authentication_info && authorization_lst!=NULL;authorization_lst=authorization_lst->next) {
229 					belle_sip_header_authorization_t *authorization=BELLE_SIP_HEADER_AUTHORIZATION(authorization_lst->data);
230 					belle_sip_header_www_authenticate_t *www_authenticate = belle_sip_auth_helper_create_www_authenticate(authorization);
231 					belle_sip_header_www_authenticate_set_nonce(www_authenticate, belle_sip_header_authentication_info_get_next_nonce(authentication_info));
232 					belle_sip_message( "Updating auth context for ream [%s] next nonce is going to be [%s]"
233 									  , belle_sip_header_www_authenticate_get_realm(www_authenticate)
234 									  , belle_sip_header_authentication_info_get_next_nonce(authentication_info));
235 					belle_sip_provider_update_or_create_auth_context(p
236 																	 , call_id
237 																	 , www_authenticate
238 																	 , from_uri
239 																	 ,belle_sip_header_www_authenticate_get_realm(www_authenticate));
240 					belle_sip_object_unref(www_authenticate);
241 				}
242 				if (authorization_lst)
243 					belle_sip_list_free(authorization_lst);
244 			}
245 
246 	}
247 	if (t){ /*In some re-connection case, specially over udp, transaction may be found, but without associated channel*/
248 		if (t->base.channel == NULL) {
249 			belle_sip_channel_t *chan;
250 			belle_sip_message("Transaction [%p] does not have any channel associated, searching for a new one",t);
251 			chan=belle_sip_provider_get_channel(p,t->next_hop); /*might be faster to get channel directly from upper level*/
252 			if (chan){
253 				belle_sip_object_ref(chan);
254 				belle_sip_channel_add_listener(chan,BELLE_SIP_CHANNEL_LISTENER(t));
255 				t->base.channel=chan;
256 			}
257 		}
258 	}
259 
260 	/*
261 	 * If a transaction is found and have a channel, pass it to the transaction and let it decide what to do.
262 	 * Else notifies directly.
263 	 */
264 	if (t && t->base.channel){
265 		/*since the add_response may indirectly terminate the transaction, we need to guarantee the transaction is not freed
266 		 * until full completion*/
267 		belle_sip_object_ref(t);
268 		belle_sip_client_transaction_add_response(t,msg);
269 		belle_sip_object_unref(t);
270 	}else{
271 		belle_sip_response_event_t event;
272 		event.source=(belle_sip_object_t*)p;
273 		event.client_transaction=NULL;
274 		event.dialog=NULL;
275 		event.response=msg;
276 		BELLE_SIP_PROVIDER_INVOKE_LISTENERS(p->listeners,process_response_event,&event);
277 	}
278 }
279 
belle_sip_provider_dispatch_message(belle_sip_provider_t * prov,belle_sip_message_t * msg)280 void belle_sip_provider_dispatch_message(belle_sip_provider_t *prov, belle_sip_message_t *msg){
281 
282 	if (TRUE
283 #ifndef BELLE_SIP_DONT_CHECK_HEADERS_IN_MESSAGE
284 			&& belle_sip_message_check_headers(msg)
285 #endif
286 	){
287 		if (belle_sip_message_is_request(msg)){
288 			belle_sip_provider_dispatch_request(prov,(belle_sip_request_t*)msg);
289 		}else{
290 			belle_sip_provider_dispatch_response(prov,(belle_sip_response_t*)msg);
291 		}
292 	}else{
293 		/* incorrect message received, answer bad request if it was a request.*/
294 		if (belle_sip_message_is_request(msg)){
295 			belle_sip_response_t *resp=belle_sip_response_create_from_request(BELLE_SIP_REQUEST(msg),400);
296 			if (resp){
297 				belle_sip_provider_send_response(prov,resp);
298 			}
299 		}/*otherwise what can we do ?*/
300 	}
301 	belle_sip_object_unref(msg);
302 }
303 
304 /*
305  * takes example on 16.11 of RFC3261
306  */
compute_hash_from_invariants(belle_sip_message_t * msg,char * branchid,size_t branchid_size,const char * initial)307 static void compute_hash_from_invariants(belle_sip_message_t *msg, char *branchid, size_t branchid_size, const char *initial){
308 	md5_state_t ctx;
309 	char tmp[256]={0};
310 	uint8_t digest[16];
311 
312 	belle_sip_header_call_id_t* callid_hdr = belle_sip_message_get_header_by_type(msg,belle_sip_header_call_id_t);
313 	belle_sip_header_cseq_t*      cseq_hdr = belle_sip_message_get_header_by_type(msg,belle_sip_header_cseq_t);
314 	belle_sip_header_from_t*      from_hdr = belle_sip_message_get_header_by_type(msg,belle_sip_header_from_t);
315 	belle_sip_header_to_t*          to_hdr = belle_sip_message_get_header_by_type(msg,belle_sip_header_to_t);
316 
317 	unsigned int    cseq = cseq_hdr   ? belle_sip_header_cseq_get_seq_number(cseq_hdr)   : 0;
318 	const char   *callid = callid_hdr ? belle_sip_header_call_id_get_call_id(callid_hdr) : "";
319 	const char *from_tag = from_hdr   ? belle_sip_header_from_get_tag(from_hdr)          : "";
320 	const char   *to_tag = to_hdr     ? belle_sip_header_to_get_tag(to_hdr)              : "";
321 
322 	belle_sip_uri_t *requri=NULL;
323 	belle_sip_header_via_t *via=NULL;
324 	belle_sip_header_via_t *prev_via=NULL;
325 	const belle_sip_list_t *vias=belle_sip_message_get_headers(msg,"via");
326 	int is_request=belle_sip_message_is_request(msg);
327 
328 	if (vias){
329 		via=(belle_sip_header_via_t*)vias->data;
330 		if (vias->next){
331 			prev_via=(belle_sip_header_via_t*)vias->next->data;
332 		}
333 	}
334 
335 	if (is_request){
336 		requri=belle_sip_request_get_uri(BELLE_SIP_REQUEST(msg));
337 	}
338 
339 	belle_sip_md5_init(&ctx);
340 	if (initial)
341 		belle_sip_md5_append(&ctx,(uint8_t*)initial,(int)strlen(initial));
342 	if (requri){
343 		size_t offset=0;
344 		belle_sip_object_marshal((belle_sip_object_t*)requri,tmp,sizeof(tmp)-1,&offset);
345 		belle_sip_md5_append(&ctx,(uint8_t*)tmp,(int)strlen(tmp));
346 	}
347 	if (from_tag)
348 		belle_sip_md5_append(&ctx,(uint8_t*)from_tag,(int)strlen(from_tag));
349 	if (to_tag)
350 		belle_sip_md5_append(&ctx,(uint8_t*)to_tag,(int)strlen(to_tag));
351 	belle_sip_md5_append(&ctx,(uint8_t*)callid,(int)strlen(callid));
352 	belle_sip_md5_append(&ctx,(uint8_t*)&cseq,sizeof(cseq));
353 	if (is_request){
354 		if (prev_via){
355 			size_t offset=0;
356 			belle_sip_object_marshal((belle_sip_object_t*)prev_via,tmp,sizeof(tmp)-1,&offset);
357 			belle_sip_md5_append(&ctx,(uint8_t*)tmp,(int)offset);
358 		}
359 	}else{
360 		if (via){
361 			size_t offset=0;
362 			belle_sip_object_marshal((belle_sip_object_t*)via,tmp,sizeof(tmp)-1,&offset);
363 			belle_sip_md5_append(&ctx,(uint8_t*)tmp,(int)offset);
364 		}
365 	}
366 	belle_sip_md5_finish(&ctx,digest);
367 	belle_sip_octets_to_text(digest,sizeof(digest),branchid,branchid_size);
368 }
369 
370 /*
371  * RFC2543 10.1.2:
372  * "Responses are mapped to requests by the matching To, From, Call-ID,
373  * CSeq headers and the branch parameter of the first Via header."
374  *
375  * to-tag must not be used because an ACK will contain one while original INVITE will not.
376  * Cseq's method is changed for CANCEL so we must not use it as well.
377 **/
378 
compute_rfc2543_branch(belle_sip_request_t * req,char * branchid,size_t branchid_size)379 static char *compute_rfc2543_branch(belle_sip_request_t *req, char *branchid, size_t branchid_size){
380 	md5_state_t ctx;
381 	unsigned int cseq=belle_sip_header_cseq_get_seq_number(belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t));
382 	uint8_t digest[16];
383 	const char* callid=belle_sip_header_call_id_get_call_id(belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t));
384 	belle_sip_header_via_t *via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t);
385 	const char *v_branch=belle_sip_header_via_get_branch(via);
386 	belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(req,belle_sip_header_from_t);
387 	char *from_str=belle_sip_object_to_string(from);
388 	belle_sip_header_to_t *to=belle_sip_message_get_header_by_type(req,belle_sip_header_to_t);
389 	char *to_str=belle_sip_object_to_string(belle_sip_header_address_get_uri((belle_sip_header_address_t*)to));
390 
391 	belle_sip_md5_init(&ctx);
392 
393 	belle_sip_md5_append(&ctx,(uint8_t*)from_str,(int)strlen(from_str));
394 	belle_sip_md5_append(&ctx,(uint8_t*)to_str,(int)strlen(to_str));
395 	belle_sip_md5_append(&ctx,(uint8_t*)callid,(int)strlen(callid));
396 	belle_sip_md5_append(&ctx,(uint8_t*)&cseq,sizeof(cseq));
397 	belle_sip_free(from_str);
398 	belle_sip_free(to_str);
399 
400 	if (v_branch)
401 		belle_sip_md5_append(&ctx,(uint8_t*)v_branch,(int)strlen(v_branch));
402 
403 	belle_sip_md5_finish(&ctx,digest);
404 	belle_sip_octets_to_text(digest,sizeof(digest),branchid,branchid_size);
405 	return branchid;
406 }
407 
fix_outgoing_via(belle_sip_provider_t * p,belle_sip_channel_t * chan,belle_sip_message_t * msg)408 static void fix_outgoing_via(belle_sip_provider_t *p, belle_sip_channel_t *chan, belle_sip_message_t *msg){
409 	belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header(msg,"via"));
410 	if (p->rport_enabled) belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(via),"rport",NULL);
411 
412 	belle_sip_header_via_set_host(via,chan->local_ip);
413 	belle_sip_header_via_set_port(via,chan->local_port);
414 	belle_sip_header_via_set_protocol(via,"SIP/2.0");
415 	belle_sip_header_via_set_transport(via,belle_sip_channel_get_transport_name(chan));
416 
417 	if (belle_sip_header_via_get_branch(via)==NULL){
418 		/*branch id should not be set random here (stateless forwarding): but rather a hash of message invariants*/
419 		char branchid[24];
420 		char token[BELLE_SIP_BRANCH_ID_LENGTH];
421 		compute_hash_from_invariants(msg,token,sizeof(token),NULL);
422 		snprintf(branchid,sizeof(branchid)-1,BELLE_SIP_BRANCH_MAGIC_COOKIE ".%s",token);
423 		belle_sip_header_via_set_branch(via,branchid);
424 		belle_sip_message("Computing branch id %s for message sent statelessly", branchid);
425 	}
426 }
427 
channel_on_message_headers(belle_sip_channel_listener_t * obj,belle_sip_channel_t * chan,belle_sip_message_t * msg)428 static void channel_on_message_headers(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_message_t *msg){
429 	/*not used*/
430 }
431 
channel_on_message(belle_sip_channel_listener_t * obj,belle_sip_channel_t * chan,belle_sip_message_t * msg)432 static void channel_on_message(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_message_t *msg){
433 	belle_sip_object_ref(msg);
434 	belle_sip_provider_dispatch_message(BELLE_SIP_PROVIDER(obj),msg);
435 }
436 
channel_on_auth_requested(belle_sip_channel_listener_t * obj,belle_sip_channel_t * chan,const char * distinguished_name)437 static int channel_on_auth_requested(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, const char* distinguished_name){
438 	if (BELLE_SIP_IS_INSTANCE_OF(chan,belle_sip_tls_channel_t)) {
439 		belle_sip_provider_t *prov=BELLE_SIP_PROVIDER(obj);
440 		belle_sip_auth_event_t* auth_event = belle_sip_auth_event_create((belle_sip_object_t*)prov,NULL,NULL);
441 		belle_sip_tls_channel_t *tls_chan=BELLE_SIP_TLS_CHANNEL(chan);
442 		auth_event->mode=BELLE_SIP_AUTH_MODE_TLS;
443 		belle_sip_auth_event_set_distinguished_name(auth_event,distinguished_name);
444 		BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_auth_requested,auth_event);
445 		belle_sip_tls_channel_set_client_certificates_chain(tls_chan,auth_event->cert);
446 		belle_sip_tls_channel_set_client_certificate_key(tls_chan,auth_event->key);
447 		belle_sip_auth_event_destroy(auth_event);
448 	}
449 	return 0;
450 }
451 
channel_on_sending(belle_sip_channel_listener_t * obj,belle_sip_channel_t * chan,belle_sip_message_t * msg)452 static void channel_on_sending(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, belle_sip_message_t *msg){
453 	belle_sip_header_contact_t* contact;
454 	belle_sip_header_content_length_t* content_length = (belle_sip_header_content_length_t*)belle_sip_message_get_header(msg,"Content-Length");
455 	belle_sip_uri_t* contact_uri;
456 	const belle_sip_list_t *contacts;
457 	const char *ip=NULL;
458 	int port=0;
459 	belle_sip_provider_t *prov=BELLE_SIP_PROVIDER(obj);
460 
461 	if (belle_sip_message_is_request(msg)){
462 		const belle_sip_list_t *rroutes;
463 		/*probably better to be in channel*/
464 		fix_outgoing_via(prov, chan, msg);
465 
466 		for (rroutes=belle_sip_message_get_headers(msg,"Record-Route");rroutes!=NULL;rroutes=rroutes->next){
467 			belle_sip_header_record_route_t* rr=(belle_sip_header_record_route_t*)rroutes->data;
468 			if (belle_sip_header_record_route_get_auto_outgoing(rr)) {
469 				belle_sip_uri_t *rr_uri = belle_sip_channel_create_routable_uri(chan);
470 				belle_sip_header_address_set_uri((belle_sip_header_address_t*) rr, rr_uri);
471 			}
472 		}
473 	}
474 
475 	for (contacts=belle_sip_message_get_headers(msg,"Contact");contacts!=NULL;contacts=contacts->next){
476 		const char *transport;
477 		contact=(belle_sip_header_contact_t*)contacts->data;
478 
479 		if (belle_sip_header_contact_is_wildcard(contact)) continue;
480 		/* fix the contact if in automatic mode or null uri (for backward compatibility)*/
481 		if (!(contact_uri = belle_sip_header_address_get_uri((belle_sip_header_address_t*)contact))) {
482 			contact_uri = belle_sip_uri_new();
483 			belle_sip_header_address_set_uri((belle_sip_header_address_t*)contact,contact_uri);
484 			belle_sip_header_contact_set_automatic(contact,TRUE);
485 		}else if (belle_sip_uri_get_host(contact_uri)==NULL){
486 			belle_sip_header_contact_set_automatic(contact,TRUE);
487 		}
488 		if (!belle_sip_header_contact_get_automatic(contact)) continue;
489 
490 		if (ip==NULL){
491 			if (prov->nat_helper){
492 				ip=chan->public_ip ? chan->public_ip : chan->local_ip;
493 				port=chan->public_port ? chan->public_port : chan->local_port;
494 				belle_sip_header_contact_set_unknown(contact,!chan->learnt_ip_port);
495 			}else{
496 				ip=chan->local_ip;
497 				port=chan->local_port;
498 			}
499 		}
500 
501 		belle_sip_uri_set_host(contact_uri,ip);
502 		transport=belle_sip_channel_get_transport_name_lower_case(chan);
503 
504 		/* Enforce a transport name in "sip" scheme.
505 		 * RFC3263 (locating SIP servers) says that UDP SHOULD be used in absence of transport parameter,
506 		 * when port or numeric IP are provided. It is a SHOULD, not a must.
507 		 * We need in this case that the automatic Contact exactly matches the socket that is going
508 		 * to be used for sending the messages.
509 		 * TODO: we may need to do the same for sips, but dtls is currently not supported.
510 		 **/
511 
512 		if (!belle_sip_uri_is_secure(contact_uri))
513 			belle_sip_uri_set_transport_param(contact_uri,transport);
514 
515 		if (port!=belle_sip_listening_point_get_well_known_port(transport)) {
516 			belle_sip_uri_set_port(contact_uri,port);
517 		}else{
518 			belle_sip_uri_set_port(contact_uri,0);
519 		}
520 	}
521 
522 /*
523  * According to RFC3261, content-length is mandatory for stream based transport, but optional for datagram transport.
524  * However some servers (opensips) are confused when they receive a SIP/UDP packet without Content-Length (they shouldn't).
525  */
526 	if (!content_length
527 		&& belle_sip_message_get_body_size(msg) == 0 /*if body present, content_length is automatically added at channel level*/
528 #ifndef BELLE_SIP_FORCE_CONTENT_LENGTH
529 		&& strcasecmp("udp",belle_sip_channel_get_transport_name(chan))!=0
530 #endif
531 	) {
532 		content_length = belle_sip_header_content_length_create(0);
533 		belle_sip_message_add_header(msg,(belle_sip_header_t*)content_length);
534 	}
535 }
536 
537 BELLE_SIP_IMPLEMENT_INTERFACE_BEGIN(belle_sip_provider_t,belle_sip_channel_listener_t)
538 	channel_state_changed,
539 	channel_on_message_headers,
540 	channel_on_message,
541 	channel_on_sending,
542 	channel_on_auth_requested
543 BELLE_SIP_IMPLEMENT_INTERFACE_END
544 
545 BELLE_SIP_DECLARE_IMPLEMENTED_INTERFACES_1(belle_sip_provider_t,belle_sip_channel_listener_t);
546 
547 BELLE_SIP_INSTANCIATE_VPTR(belle_sip_provider_t,belle_sip_object_t,belle_sip_provider_uninit,NULL,NULL,FALSE);
548 
belle_sip_provider_new(belle_sip_stack_t * s,belle_sip_listening_point_t * lp)549 belle_sip_provider_t *belle_sip_provider_new(belle_sip_stack_t *s, belle_sip_listening_point_t *lp){
550 	belle_sip_provider_t *p=belle_sip_object_new(belle_sip_provider_t);
551 	p->stack=s;
552 	p->rport_enabled=1;
553 	p->unconditional_answer = 480;
554 	if (lp) belle_sip_provider_add_listening_point(p,lp);
555 	return p;
556 }
557 
558 /* This function is used by a proxy to set its call side record route.
559  * It must be called before adding any VIA header to the message. */
belle_sip_provider_create_inbound_record_route(belle_sip_provider_t * p,belle_sip_request_t * req)560 belle_sip_uri_t *belle_sip_provider_create_inbound_record_route(belle_sip_provider_t *p, belle_sip_request_t *req) {
561 	belle_sip_uri_t* origin = belle_sip_request_extract_origin(req);
562 	belle_sip_hop_t *hop = belle_sip_hop_new_from_uri(origin);
563 	belle_sip_channel_t *inChan = belle_sip_provider_get_channel(p, hop);
564 	return belle_sip_channel_create_routable_uri(inChan);
565 }
566 
_belle_sip_provider_find_channel_using_routable(belle_sip_provider_t * p,const belle_sip_uri_t * routable_uri)567 static belle_sip_channel_t* _belle_sip_provider_find_channel_using_routable(belle_sip_provider_t *p, const belle_sip_uri_t* routable_uri) {
568 	const char *transport;
569 	belle_sip_listening_point_t *lp;
570 	belle_sip_list_t *elem;
571 	belle_sip_channel_t *chan;
572 	belle_sip_uri_t* chan_uri;
573 
574 	if (!routable_uri) return NULL;
575 
576 	transport = belle_sip_uri_is_secure(routable_uri) ? "TLS" : belle_sip_uri_get_transport_param(routable_uri);
577 	lp = belle_sip_provider_get_listening_point(p, transport);
578 	if (!lp) return NULL;
579 
580 
581 	for(elem=lp->channels; elem ;elem=elem->next){
582 		chan=(belle_sip_channel_t*)elem->data;
583 		chan_uri = belle_sip_channel_create_routable_uri(chan);
584 		if (belle_sip_uri_get_port(routable_uri) == belle_sip_uri_get_port(chan_uri) &&
585 			0 == strcmp(belle_sip_uri_get_host(routable_uri), belle_sip_uri_get_host(chan_uri))) {
586 			return chan;
587 		}
588 	}
589 	return NULL;
590 }
591 
592 /*
593  * This function is not efficient at all, REVISIT.
594  * Its goal is to determine whether a routable (route or record route) matches the local provider instance.
595  * In order to do that, we go through all the channels and ask them their routable uri, and see if it matches the uri passed in argument.
596  * This creates a lot of temporary objects and iterates through a potentially long list of routables.
597  * Some more efficient solutions could be:
598  * 1- insert a magic cookie parameter in each routable created by the provider, so that recognition is immediate.
599  *    Drawback: use of non-standard, possibly conflicting parameter.
600  * 2- check the listening point's uri first (but need to match the ip address to any local ip if it is INADDR_ANY), then use belle_sip_listening_point_get_channel()
601  *    to see if a channel is matching.
602  *    belle_sip_listening_point_get_channel() is not optimized currently but will have to be, so at least we leverage on something that will be optimized.
603 **/
belle_sip_provider_is_us(belle_sip_provider_t * p,belle_sip_uri_t * uri)604 int belle_sip_provider_is_us(belle_sip_provider_t *p, belle_sip_uri_t* uri) {
605 	belle_sip_channel_t* chan = _belle_sip_provider_find_channel_using_routable(p, uri);
606 	return !!chan;
607 }
608 
609 
belle_sip_provider_add_listening_point(belle_sip_provider_t * p,belle_sip_listening_point_t * lp)610 int belle_sip_provider_add_listening_point(belle_sip_provider_t *p, belle_sip_listening_point_t *lp){
611 	if (lp == NULL) {
612 		belle_sip_error("Cannot add NULL lp to provider [%p]",p);
613 		return -1;
614 	}
615 	belle_sip_listening_point_set_channel_listener(lp,BELLE_SIP_CHANNEL_LISTENER(p));
616 	p->lps=belle_sip_list_append(p->lps,belle_sip_object_ref(lp));
617 	return 0;
618 }
619 
belle_sip_provider_remove_listening_point(belle_sip_provider_t * p,belle_sip_listening_point_t * lp)620 void belle_sip_provider_remove_listening_point(belle_sip_provider_t *p, belle_sip_listening_point_t *lp) {
621 	p->lps=belle_sip_list_remove(p->lps,lp);
622 	belle_sip_object_unref(lp);
623 	return;
624 }
625 
belle_sip_provider_get_listening_point(belle_sip_provider_t * p,const char * transport)626 belle_sip_listening_point_t *belle_sip_provider_get_listening_point(belle_sip_provider_t *p, const char *transport){
627 	belle_sip_list_t *l;
628 	for(l=p->lps;l!=NULL;l=l->next){
629 		belle_sip_listening_point_t *lp=(belle_sip_listening_point_t*)l->data;
630 		if (strcasecmp(belle_sip_listening_point_get_transport(lp),transport)==0)
631 			return lp;
632 	}
633 	return NULL;
634 }
635 
belle_sip_provider_get_listening_points(belle_sip_provider_t * p)636 const belle_sip_list_t *belle_sip_provider_get_listening_points(belle_sip_provider_t *p){
637 	return p->lps;
638 }
639 
belle_sip_provider_add_internal_sip_listener(belle_sip_provider_t * p,belle_sip_listener_t * l,int prepend)640 void belle_sip_provider_add_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l, int prepend){
641 	if (prepend)
642 		p->internal_listeners=belle_sip_list_prepend(p->internal_listeners,l);
643 	else
644 		p->internal_listeners=belle_sip_list_append(p->internal_listeners,l);
645 }
646 
belle_sip_provider_remove_internal_sip_listener(belle_sip_provider_t * p,belle_sip_listener_t * l)647 void belle_sip_provider_remove_internal_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l){
648 	p->internal_listeners=belle_sip_list_remove(p->internal_listeners,l);
649 }
650 
belle_sip_provider_add_sip_listener(belle_sip_provider_t * p,belle_sip_listener_t * l)651 void belle_sip_provider_add_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l){
652 	p->listeners=belle_sip_list_append(p->listeners,l);
653 }
654 
belle_sip_provider_remove_sip_listener(belle_sip_provider_t * p,belle_sip_listener_t * l)655 void belle_sip_provider_remove_sip_listener(belle_sip_provider_t *p, belle_sip_listener_t *l){
656 	p->listeners=belle_sip_list_remove(p->listeners,l);
657 }
658 
belle_sip_provider_create_call_id(const belle_sip_provider_t * prov)659 belle_sip_header_call_id_t * belle_sip_provider_create_call_id(const belle_sip_provider_t *prov){
660 	belle_sip_header_call_id_t *cid=belle_sip_header_call_id_new();
661 	char tmp[11];
662 	belle_sip_header_call_id_set_call_id(cid,belle_sip_random_token(tmp,sizeof(tmp)));
663 	return cid;
664 }
665 
belle_sip_provider_create_dialog(belle_sip_provider_t * prov,belle_sip_transaction_t * t)666 belle_sip_dialog_t * belle_sip_provider_create_dialog(belle_sip_provider_t *prov, belle_sip_transaction_t *t) {
667 	return belle_sip_provider_create_dialog_internal(prov,t,TRUE);
668 }
669 
belle_sip_provider_create_dialog_internal(belle_sip_provider_t * prov,belle_sip_transaction_t * t,unsigned int check_last_resp)670 belle_sip_dialog_t * belle_sip_provider_create_dialog_internal(belle_sip_provider_t *prov, belle_sip_transaction_t *t,unsigned int check_last_resp){
671 	belle_sip_dialog_t *dialog=NULL;
672 
673 	if (check_last_resp && t->last_response){
674 		int code=belle_sip_response_get_status_code(t->last_response);
675 		if (code>=200 && code<300){
676 			belle_sip_fatal("You must not create dialog after sending the response that establish the dialog.");
677 			return NULL;
678 		}
679 	}
680 	dialog=belle_sip_dialog_new(t);
681 	if (dialog) {
682 		belle_sip_transaction_set_dialog(t,dialog);
683 		belle_sip_provider_add_dialog(prov,dialog);
684 	}
685 	return dialog;
686 }
687 
688 /*find a dialog given the call id, local-tag and to-tag*/
belle_sip_provider_find_dialog(const belle_sip_provider_t * prov,const char * call_id,const char * local_tag,const char * remote_tag)689 belle_sip_dialog_t* belle_sip_provider_find_dialog(const belle_sip_provider_t *prov, const char* call_id, const char* local_tag, const char* remote_tag) {
690 	belle_sip_list_t* iterator;
691 	belle_sip_dialog_t*returned_dialog=NULL;
692 
693 	if (call_id == NULL || local_tag == NULL || remote_tag == NULL) {
694 		return NULL;
695 	}
696 
697 	for(iterator=prov->dialogs;iterator!=NULL;iterator=iterator->next) {
698 		belle_sip_dialog_t* dialog=(belle_sip_dialog_t*)iterator->data;
699 		dialog=(belle_sip_dialog_t*)iterator->data;
700 		/*ignore dialog in state BELLE_SIP_DIALOG_NULL, is it really the correct things to do*/
701 		if (belle_sip_dialog_get_state(dialog) != BELLE_SIP_DIALOG_NULL && _belle_sip_dialog_match(dialog,call_id,local_tag,remote_tag)) {
702 			if (!returned_dialog)
703 				returned_dialog=dialog;
704 			else
705 				belle_sip_fatal("More than 1 dialog is matching, check your app");
706 		}
707 	}
708 	return returned_dialog;
709 }
710 
711 /*finds an existing dialog for an outgoing or incoming message */
belle_sip_provider_find_dialog_from_message(belle_sip_provider_t * prov,belle_sip_message_t * msg,int as_uas)712 belle_sip_dialog_t *belle_sip_provider_find_dialog_from_message(belle_sip_provider_t *prov, belle_sip_message_t *msg, int as_uas){
713 	belle_sip_header_call_id_t *call_id;
714 	belle_sip_header_from_t *from;
715 	belle_sip_header_to_t *to;
716 	const char *from_tag;
717 	const char *to_tag;
718 	const char *call_id_value;
719 	const char *local_tag,*remote_tag;
720 
721 	if (belle_sip_message_is_request(msg)){
722 		belle_sip_request_t *req=BELLE_SIP_REQUEST(msg);
723 		if (req->dialog)
724 			return req->dialog;
725 	}
726 
727 	to=belle_sip_message_get_header_by_type(msg,belle_sip_header_to_t);
728 
729 	if (to==NULL || (to_tag=belle_sip_header_to_get_tag(to))==NULL){
730 		/* a request without to tag cannot be part of a dialog */
731 		return NULL;
732 	}
733 
734 	call_id=belle_sip_message_get_header_by_type(msg,belle_sip_header_call_id_t);
735 	from=belle_sip_message_get_header_by_type(msg,belle_sip_header_from_t);
736 
737 	if (call_id==NULL || from==NULL || (from_tag=belle_sip_header_from_get_tag(from))==NULL) return NULL;
738 
739 	call_id_value=belle_sip_header_call_id_get_call_id(call_id);
740 	local_tag=as_uas ? to_tag : from_tag;
741 	remote_tag=as_uas ? from_tag : to_tag;
742 	return belle_sip_provider_find_dialog(prov,call_id_value,local_tag,remote_tag);
743 }
744 
belle_sip_provider_add_dialog(belle_sip_provider_t * prov,belle_sip_dialog_t * dialog)745 void belle_sip_provider_add_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog){
746 	prov->dialogs=belle_sip_list_prepend(prov->dialogs,belle_sip_object_ref(dialog));
747 }
748 
notify_dialog_terminated(belle_sip_dialog_terminated_event_t * ev)749 static void notify_dialog_terminated(belle_sip_dialog_terminated_event_t* ev) {
750 	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_DIALOG(ev->dialog,process_dialog_terminated,ev);
751 	belle_sip_object_unref(ev->dialog);
752 	belle_sip_free(ev);
753 }
754 
belle_sip_provider_remove_dialog(belle_sip_provider_t * prov,belle_sip_dialog_t * dialog)755 void belle_sip_provider_remove_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog){
756 	belle_sip_dialog_terminated_event_t* ev=belle_sip_malloc(sizeof(belle_sip_dialog_terminated_event_t));
757 	ev->source=prov;
758 	ev->dialog=dialog;
759 	ev->is_expired=dialog->is_expired;
760 	prov->dialogs=belle_sip_list_remove(prov->dialogs,dialog);
761 	belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(prov->stack)
762 					,(belle_sip_callback_t) notify_dialog_terminated
763 					, ev);
764 
765 }
766 
belle_sip_provider_create_client_transaction(belle_sip_provider_t * prov,belle_sip_request_t * req)767 belle_sip_client_transaction_t *belle_sip_provider_create_client_transaction(belle_sip_provider_t *prov, belle_sip_request_t *req){
768 	const char *method=belle_sip_request_get_method(req);
769 	belle_sip_client_transaction_t *t;
770 	belle_sip_client_transaction_t *inv_transaction;
771 	if (strcmp(method,"INVITE")==0)
772 		t=(belle_sip_client_transaction_t*)belle_sip_ict_new(prov,req);
773 	else if (strcmp(method,"ACK")==0){
774 		belle_sip_error("belle_sip_provider_create_client_transaction() cannot be used for ACK requests.");
775 		return NULL;
776 	} else {
777 		t=(belle_sip_client_transaction_t*)belle_sip_nict_new(prov,req);
778 		if (strcmp(method,"CANCEL")==0){
779 			/*force next hop*/
780 			inv_transaction=belle_sip_provider_find_matching_client_transaction_from_req(prov,req);
781 			if (inv_transaction && inv_transaction->next_hop) {
782 				/*found corresponding ict, taking next hop*/
783 				/*9.1 Client Behavior
784 				 * The destination address,
785 				   port, and transport for the CANCEL MUST be identical to those used to
786 				   send the original request.*/
787 				t->next_hop=(belle_sip_hop_t*)belle_sip_object_ref(inv_transaction->next_hop);
788 			} else {
789 				belle_sip_error ("No corresponding ict nor dest found for cancel request attached to transaction [%p]",t);
790 			}
791 		}
792 	}
793 	belle_sip_transaction_set_dialog((belle_sip_transaction_t*)t,belle_sip_provider_find_dialog_from_message(prov,(belle_sip_message_t*)req,FALSE));
794 	belle_sip_request_set_dialog(req,NULL);/*get rid of the reference to the dialog, which is no longer needed in the message.
795 					This is to avoid circular references.*/
796 	return t;
797 }
798 
belle_sip_provider_create_server_transaction(belle_sip_provider_t * prov,belle_sip_request_t * req)799 belle_sip_server_transaction_t *belle_sip_provider_create_server_transaction(belle_sip_provider_t *prov, belle_sip_request_t *req){
800 	belle_sip_server_transaction_t* t;
801 	belle_sip_response_t *resp = NULL;
802 	if (strcmp(belle_sip_request_get_method(req),"INVITE")==0){
803 		t=(belle_sip_server_transaction_t*)belle_sip_ist_new(prov,req);
804 		/*create a 100 Trying response to immediately stop client retransmissions*/
805 		resp=belle_sip_response_create_from_request(req,100);
806 
807 	}else if (strcmp(belle_sip_request_get_method(req),"ACK")==0){
808 		belle_sip_error("Creating a server transaction for an ACK is not a good idea, probably");
809 		return NULL;
810 	}else
811 		t=(belle_sip_server_transaction_t*)belle_sip_nist_new(prov,req);
812 	belle_sip_transaction_set_dialog((belle_sip_transaction_t*)t,belle_sip_provider_find_dialog_from_message(prov,(belle_sip_message_t*)req,TRUE));
813 	belle_sip_provider_add_server_transaction(prov,t);
814 	if (resp){
815 		/*the response must be sent after the server transaction is refd by belle_sip_provider_add_server_transaction , otherwise
816 		 * through callbacks we'll reach a point where it is unrefed before leaving from this function*/
817 		belle_sip_server_transaction_send_response(t, resp);
818 	}
819 	return t;
820 }
821 
belle_sip_provider_get_sip_stack(belle_sip_provider_t * p)822 belle_sip_stack_t *belle_sip_provider_get_sip_stack(belle_sip_provider_t *p){
823 	return p->stack;
824 }
825 
belle_sip_provider_get_channel(belle_sip_provider_t * p,const belle_sip_hop_t * hop)826 belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const belle_sip_hop_t *hop){
827 	belle_sip_list_t *l;
828 	belle_sip_listening_point_t *candidate=NULL,*lp;
829 	belle_sip_channel_t *chan;
830 
831 	if (hop->transport!=NULL) {
832 		for(l=p->lps;l!=NULL;l=l->next){
833 			lp=(belle_sip_listening_point_t*)l->data;
834 			if (strcasecmp(belle_sip_listening_point_get_transport(lp),hop->transport)==0){
835 				chan=belle_sip_listening_point_get_channel(lp,hop);
836 				if (chan) {
837 					belle_sip_channel_check_dns_reusability(chan);
838 					return chan;
839 				}
840 				candidate=lp;
841 			}
842 		}
843 		if (candidate){
844 			chan=belle_sip_listening_point_create_channel(candidate,hop);
845 			if (!chan) belle_sip_error("Could not create channel to [%s://%s:%i]",hop->transport,hop->host,hop->port);
846 			return chan;
847 		}
848 	}
849 	belle_sip_error("No listening point matching for [%s://%s:%i]",hop->transport,hop->host,hop->port);
850 	return NULL;
851 }
852 
belle_sip_provider_release_channel(belle_sip_provider_t * p,belle_sip_channel_t * chan)853 void belle_sip_provider_release_channel(belle_sip_provider_t *p, belle_sip_channel_t *chan){
854 	belle_sip_listening_point_remove_channel(chan->lp,chan);
855 }
856 
belle_sip_provider_clean_channels(belle_sip_provider_t * p)857 void belle_sip_provider_clean_channels(belle_sip_provider_t *p){
858 	belle_sip_list_t *l;
859 	belle_sip_listening_point_t *lp;
860 
861 	for(l=p->lps;l!=NULL;l=l->next){
862 		lp=(belle_sip_listening_point_t*)l->data;
863 		belle_sip_listening_point_clean_channels(lp);
864 	}
865 }
866 
belle_sip_provider_send_request(belle_sip_provider_t * p,belle_sip_request_t * req)867 void belle_sip_provider_send_request(belle_sip_provider_t *p, belle_sip_request_t *req){
868 	belle_sip_hop_t* hop;
869 	belle_sip_channel_t *chan;
870 	hop=belle_sip_stack_get_next_hop(p->stack,req);
871 	chan=belle_sip_provider_get_channel(p,hop);
872 	if (chan) {
873 		belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(req));
874 	}
875 }
876 
belle_sip_provider_send_response(belle_sip_provider_t * p,belle_sip_response_t * resp)877 void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_response_t *resp){
878 	belle_sip_hop_t* hop;
879 	belle_sip_channel_t *chan;
880 	belle_sip_header_to_t *to=(belle_sip_header_to_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"to");
881 
882 	if (belle_sip_response_get_status_code(resp)!=100 && to && belle_sip_header_to_get_tag(to)==NULL){
883 		char token[BELLE_SIP_TAG_LENGTH];
884 		compute_hash_from_invariants((belle_sip_message_t*)resp,token,sizeof(token),"tag");
885 		belle_sip_header_to_set_tag(to,token);
886 	}
887 	hop=belle_sip_response_get_return_hop(resp);
888 	if (hop){
889 		chan=belle_sip_provider_get_channel(p,hop);
890 		if (chan) belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(resp));
891 		belle_sip_object_unref(hop);
892 	}
893 }
894 
895 
896 /*private provider API*/
897 
belle_sip_provider_set_transaction_terminated(belle_sip_provider_t * p,belle_sip_transaction_t * t)898 void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t){
899 	belle_sip_transaction_terminated_event_t ev;
900 
901 	BELLE_SIP_OBJECT_VPTR(t,belle_sip_transaction_t)->on_terminate(t);
902 	ev.source=t->provider;
903 	ev.transaction=t;
904 	ev.is_server_transaction=BELLE_SIP_IS_INSTANCE_OF(t,belle_sip_server_transaction_t);
905 	BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(t,process_transaction_terminated,&ev);
906 	if (!ev.is_server_transaction){
907 		belle_sip_provider_remove_client_transaction(p,(belle_sip_client_transaction_t*)t);
908 	}else{
909 		belle_sip_provider_remove_server_transaction(p,(belle_sip_server_transaction_t*)t);
910 	}
911 }
912 
belle_sip_provider_add_client_transaction(belle_sip_provider_t * prov,belle_sip_client_transaction_t * t)913 void belle_sip_provider_add_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t){
914 	prov->client_transactions=belle_sip_list_prepend(prov->client_transactions,belle_sip_object_ref(t));
915 }
916 
917 struct client_transaction_matcher{
918 	const char *branchid;
919 	const char *method;
920 };
921 
client_transaction_match(const void * p_tr,const void * p_matcher)922 static int client_transaction_match(const void *p_tr, const void *p_matcher){
923 	belle_sip_client_transaction_t *tr=(belle_sip_client_transaction_t*)p_tr;
924 	struct client_transaction_matcher *matcher=(struct client_transaction_matcher*)p_matcher;
925 	const char *req_method=belle_sip_request_get_method(tr->base.request);
926 	if (strcmp(matcher->branchid,tr->base.branch_id)==0 && strcmp(matcher->method,req_method)==0) return 0;
927 	return -1;
928 }
929 
belle_sip_provider_find_matching_client_transaction(belle_sip_provider_t * prov,belle_sip_response_t * resp)930 belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transaction(belle_sip_provider_t *prov,
931 																				   belle_sip_response_t *resp){
932 	struct client_transaction_matcher matcher;
933 	belle_sip_header_via_t *via=(belle_sip_header_via_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"via");
934 	belle_sip_header_cseq_t *cseq=(belle_sip_header_cseq_t*)belle_sip_message_get_header((belle_sip_message_t*)resp,"cseq");
935 	belle_sip_client_transaction_t *ret=NULL;
936 	belle_sip_list_t *elem;
937 	if (via==NULL){
938 		belle_sip_warning("Response has no via.");
939 		return NULL;
940 	}
941 	if (cseq==NULL){
942 		belle_sip_warning("Response has no cseq.");
943 		return NULL;
944 	}
945 	matcher.branchid=belle_sip_header_via_get_branch(via);
946 	matcher.method=belle_sip_header_cseq_get_method(cseq);
947 	elem=belle_sip_list_find_custom(prov->client_transactions,client_transaction_match,&matcher);
948 	if (elem){
949 		ret=(belle_sip_client_transaction_t*)elem->data;
950 		belle_sip_message("Found transaction matching response.");
951 	}
952 	return ret;
953 }
954 
belle_sip_provider_remove_client_transaction(belle_sip_provider_t * prov,belle_sip_client_transaction_t * t)955 void belle_sip_provider_remove_client_transaction(belle_sip_provider_t *prov, belle_sip_client_transaction_t *t){
956 	belle_sip_list_t* elem=belle_sip_list_find(prov->client_transactions,t);
957 	if (elem) {
958 		prov->client_transactions=belle_sip_list_delete_link(prov->client_transactions,elem);
959 		belle_sip_object_unref(t);
960 	} else {
961 		belle_sip_error("trying to remove transaction [%p] not part of provider [%p]",t,prov);
962 	}
963 
964 }
965 
belle_sip_provider_add_server_transaction(belle_sip_provider_t * prov,belle_sip_server_transaction_t * t)966 void belle_sip_provider_add_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t){
967 	prov->server_transactions=belle_sip_list_prepend(prov->server_transactions,belle_sip_object_ref(t));
968 }
969 
970 struct transaction_matcher{
971 	const char *branchid;
972 	const char *method;
973 	const char *sentby;
974 	int is_ack_or_cancel;
975 };
976 
transaction_match(const void * p_tr,const void * p_matcher)977 static int transaction_match(const void *p_tr, const void *p_matcher){
978 	belle_sip_transaction_t *tr=(belle_sip_transaction_t*)p_tr;
979 	struct transaction_matcher *matcher=(struct transaction_matcher*)p_matcher;
980 	const char *req_method=belle_sip_request_get_method(tr->request);
981 	if (strcmp(matcher->branchid,tr->branch_id)==0){
982 		if (strcmp(matcher->method,req_method)==0) return 0;
983 		if (matcher->is_ack_or_cancel && strcmp(req_method,"INVITE")==0) return 0;
984 	}
985 	return -1;
986 }
987 
belle_sip_provider_find_matching_transaction(belle_sip_list_t * transactions,belle_sip_request_t * req)988 belle_sip_transaction_t * belle_sip_provider_find_matching_transaction(belle_sip_list_t *transactions, belle_sip_request_t *req){
989 	struct transaction_matcher matcher;
990 	belle_sip_header_via_t *via=(belle_sip_header_via_t*)belle_sip_message_get_header((belle_sip_message_t*)req,"via");
991 	belle_sip_transaction_t *ret=NULL;
992 	belle_sip_list_t *elem=NULL;
993 	const char *branch;
994 	char token[BELLE_SIP_BRANCH_ID_LENGTH];
995 
996 
997 	matcher.method=belle_sip_request_get_method(req);
998 	matcher.is_ack_or_cancel=(strcmp(matcher.method,"ACK")==0 || strcmp(matcher.method,"CANCEL")==0);
999 
1000 	if (via!=NULL && (branch=belle_sip_header_via_get_branch(via))!=NULL &&
1001 		strncmp(branch,BELLE_SIP_BRANCH_MAGIC_COOKIE,strlen(BELLE_SIP_BRANCH_MAGIC_COOKIE))==0){
1002 		matcher.branchid=branch;
1003 	}else{
1004 		/*this request comes from an old equipment, we need to compute our own branch for this request.*/
1005 		matcher.branchid=compute_rfc2543_branch(req,token,sizeof(token));
1006 		belle_sip_request_set_rfc2543_branch(req,token);
1007 		belle_sip_message("Message from old RFC2543 stack, computed branch is %s", token);
1008 	}
1009 
1010 	elem=belle_sip_list_find_custom(transactions,transaction_match,&matcher);
1011 
1012 	if (elem){
1013 		ret=(belle_sip_transaction_t*)elem->data;
1014 		belle_sip_message("Found transaction [%p] matching request.",ret);
1015 	}
1016 	return ret;
1017 }
belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t * prov,belle_sip_request_t * req)1018 belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transaction(belle_sip_provider_t *prov, belle_sip_request_t *req) {
1019 	belle_sip_transaction_t *ret=belle_sip_provider_find_matching_transaction(prov->server_transactions,req);
1020 	return ret?BELLE_SIP_SERVER_TRANSACTION(ret):NULL;
1021 }
belle_sip_provider_find_matching_client_transaction_from_req(belle_sip_provider_t * prov,belle_sip_request_t * req)1022 belle_sip_client_transaction_t * belle_sip_provider_find_matching_client_transaction_from_req(belle_sip_provider_t *prov, belle_sip_request_t *req) {
1023 	belle_sip_transaction_t *ret=belle_sip_provider_find_matching_transaction(prov->client_transactions,req);
1024 	return ret?BELLE_SIP_CLIENT_TRANSACTION(ret):NULL;
1025 }
1026 
belle_sip_provider_remove_server_transaction(belle_sip_provider_t * prov,belle_sip_server_transaction_t * t)1027 void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t){
1028 	prov->server_transactions=belle_sip_list_remove(prov->server_transactions,t);
1029 	belle_sip_object_unref(t);
1030 }
1031 
1032 
authorization_context_fill_from_auth(authorization_context_t * auth_context,belle_sip_header_www_authenticate_t * authenticate,belle_sip_uri_t * from_uri)1033 static void authorization_context_fill_from_auth(authorization_context_t* auth_context,belle_sip_header_www_authenticate_t* authenticate,belle_sip_uri_t *from_uri) {
1034 	authorization_context_set_realm(auth_context,belle_sip_header_www_authenticate_get_realm(authenticate));
1035 	if (auth_context->nonce && strcmp(belle_sip_header_www_authenticate_get_nonce(authenticate),auth_context->nonce)!=0) {
1036 		/*new nonce, resetting nounce_count*/
1037 		auth_context->nonce_count=0;
1038 	}
1039 	authorization_context_set_nonce(auth_context,belle_sip_header_www_authenticate_get_nonce(authenticate));
1040 	authorization_context_set_algorithm(auth_context,belle_sip_header_www_authenticate_get_algorithm(authenticate));
1041 	authorization_context_set_qop(auth_context,belle_sip_header_www_authenticate_get_qop_first(authenticate));
1042 	authorization_context_set_scheme(auth_context,belle_sip_header_www_authenticate_get_scheme(authenticate));
1043 	authorization_context_set_opaque(auth_context,belle_sip_header_www_authenticate_get_opaque(authenticate));
1044 	authorization_context_set_user_id(auth_context, from_uri?belle_sip_uri_get_user(from_uri):NULL);
1045 
1046 	if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(authenticate,belle_sip_header_proxy_authenticate_t)) {
1047 		auth_context->is_proxy=1;
1048 	}
1049 }
1050 
1051 
belle_sip_provider_get_auth_context_by_realm_or_call_id(belle_sip_provider_t * p,belle_sip_header_call_id_t * call_id,belle_sip_uri_t * from_uri,const char * realm)1052 static belle_sip_list_t* belle_sip_provider_get_auth_context_by_realm_or_call_id(belle_sip_provider_t *p,belle_sip_header_call_id_t* call_id,belle_sip_uri_t *from_uri,const char* realm) {
1053 	belle_sip_list_t* auth_context_lst=NULL;
1054 	belle_sip_list_t* result=NULL;
1055 	authorization_context_t* auth_context;
1056 
1057 	for (auth_context_lst=p->auth_contexts;auth_context_lst!=NULL;auth_context_lst=auth_context_lst->next) {
1058 		auth_context=(authorization_context_t*)auth_context_lst->data;
1059 		if (belle_sip_header_call_id_equals(auth_context->callid,call_id) ) {
1060 			result=belle_sip_list_append(result,auth_context_lst->data);
1061 		}
1062 	}
1063 
1064 	/* According to the RFC3261 22.3, if the outbound proxy realm is set, we could reuse its nonce value:
1065 	 * "If a UA receives a Proxy-Authenticate header field value in a 401/407
1066 	 * response to a request with a particular Call-ID, it should
1067 	 * incorporate credentials for that realm in all subsequent requests
1068 	 * that contain the same Call-ID.  These credentials MUST NOT be cached
1069 	 * across dialogs; however, if a UA is configured with the realm of its
1070 	 * local outbound proxy, when one exists, then the UA MAY cache
1071 	 * credentials for that realm across dialogs."
1072 	*/
1073 	if (result == NULL){
1074 		const char * from_user=from_uri?belle_sip_uri_get_user(from_uri):NULL;
1075 
1076 		belle_sip_debug("belle_sip_provider_auth: no auth context registered with [call_id=%s], looking for realm..."
1077 			, call_id?belle_sip_header_call_id_get_call_id(call_id):"(null)");
1078 
1079 		for (auth_context_lst=p->auth_contexts;auth_context_lst!=NULL;auth_context_lst=auth_context_lst->next) {
1080 			auth_context=(authorization_context_t*)auth_context_lst->data;
1081 
1082 			belle_sip_debug("belle_sip_provider_auth: \t[realm=%s] [user_id=%s] [call_id=%s]",
1083 				auth_context->realm?auth_context->realm:"(null)",
1084 				auth_context->user_id?auth_context->user_id:"(null)",
1085 				auth_context->callid?belle_sip_header_call_id_get_call_id(auth_context->callid):"(null)"
1086 			);
1087 			/* We also verify that user matches in case of multi-account to avoid use nonce from another account. For a
1088 			 * single user, from_uri user id and realm user id COULD be different but we assume here that this is not the case
1089 			 * in order to avoid adding another field in auth_context struct.
1090 			**/
1091 			if ((realm && strcmp(auth_context->realm,realm)==0)
1092 				&& (from_user && auth_context->user_id && strcmp(auth_context->user_id,from_user)==0)) {
1093 
1094 				result=belle_sip_list_append(result,auth_context_lst->data);
1095 				belle_sip_debug("belle_sip_provider_auth: found a MATCHING realm auth context!");
1096 			}
1097 		}
1098 	}
1099 	return result;
1100 }
1101 
belle_sip_provider_update_or_create_auth_context(belle_sip_provider_t * p,belle_sip_header_call_id_t * call_id,belle_sip_header_www_authenticate_t * authenticate,belle_sip_uri_t * from_uri,const char * realm)1102 static void  belle_sip_provider_update_or_create_auth_context(belle_sip_provider_t *p,belle_sip_header_call_id_t* call_id,belle_sip_header_www_authenticate_t* authenticate,belle_sip_uri_t *from_uri,const char* realm) {
1103 	belle_sip_list_t* auth_context_lst = NULL;
1104 	authorization_context_t* auth_context;
1105 
1106 	for (auth_context_lst=belle_sip_provider_get_auth_context_by_realm_or_call_id(p,call_id,from_uri,realm);auth_context_lst!=NULL;auth_context_lst=auth_context_lst->next) {
1107 		auth_context=(authorization_context_t*)auth_context_lst->data;
1108 		if (strcmp(auth_context->realm,belle_sip_header_www_authenticate_get_realm(authenticate))==0) {
1109 			authorization_context_fill_from_auth(auth_context,authenticate,from_uri);
1110 			if (auth_context_lst) belle_sip_free(auth_context_lst);
1111 			return; /*only one realm is supposed to be found for now*/
1112 		}
1113 	}
1114 
1115 	/*no auth context found, creating one*/
1116 	auth_context=belle_sip_authorization_create(call_id);
1117 	belle_sip_debug("belle_sip_provider_auth: no matching auth context, creating one for [realm=%s][user_id=%s][call_id=%s]"
1118 		, belle_sip_header_www_authenticate_get_realm(authenticate)?belle_sip_header_www_authenticate_get_realm(authenticate):"(null)"
1119 		, from_uri?belle_sip_uri_get_user(from_uri):"(null)"
1120 		, call_id?belle_sip_header_call_id_get_call_id(call_id):"(null)");
1121 	authorization_context_fill_from_auth(auth_context,authenticate,from_uri);
1122 
1123 	p->auth_contexts=belle_sip_list_append(p->auth_contexts,auth_context);
1124 	if (auth_context_lst) belle_sip_free(auth_context_lst);
1125 	return;
1126 }
1127 
1128 
belle_sip_provider_add_authorization(belle_sip_provider_t * p,belle_sip_request_t * request,belle_sip_response_t * resp,belle_sip_uri_t * from_uri,belle_sip_list_t ** auth_infos,const char * realm)1129 int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_request_t* request, belle_sip_response_t *resp,
1130 					 belle_sip_uri_t *from_uri, belle_sip_list_t** auth_infos, const char* realm) {
1131 	belle_sip_header_call_id_t* call_id;
1132 	belle_sip_list_t* auth_context_iterator;
1133 	belle_sip_list_t* authenticate_lst;
1134 	belle_sip_list_t* head;
1135 	belle_sip_header_www_authenticate_t* authenticate;
1136 	belle_sip_header_authorization_t* authorization;
1137 	belle_sip_header_from_t* from;
1138 	belle_sip_auth_event_t* auth_event;
1139 	authorization_context_t* auth_context;
1140 	const char* ha1;
1141 	char computed_ha1[33];
1142 	int result=0;
1143 	const char* request_method;
1144 	/*check params*/
1145 	if (!p || !request) {
1146 		belle_sip_error("belle_sip_provider_add_authorization bad parameters");
1147 		return-1;
1148 	}
1149 	request_method=belle_sip_request_get_method(request);
1150 
1151 	/*22 Usage of HTTP Authentication
1152 		22.1 Framework
1153 		While a server can legitimately challenge most SIP requests, there
1154 		are two requests defined by this document that require special
1155 		handling for authentication: ACK and CANCEL.
1156 		Under an authentication scheme that uses responses to carry values
1157 		used to compute nonces (such as Digest), some problems come up for
1158 		any requests that take no response, including ACK.  For this reason,
1159 		any credentials in the INVITE that were accepted by a server MUST be
1160 		accepted by that server for the ACK.  UACs creating an ACK message
1161 		will duplicate all of the Authorization and Proxy-Authorization
1162 		header field values that appeared in the INVITE to which the ACK
1163 		corresponds.  Servers MUST NOT attempt to challenge an ACK.
1164 
1165 		Although the CANCEL method does take a response (a 2xx), servers MUST
1166 		NOT attempt to challenge CANCEL requests since these requests cannot
1167 		be resubmitted.  Generally, a CANCEL request SHOULD be accepted by a
1168 		server if it comes from the same hop that sent the request being
1169 		canceled (provided that some sort of transport or network layer
1170 		security association, as described in Section 26.2.1, is in place).
1171 	*/
1172 
1173 	if (strcmp("CANCEL",request_method)==0 || strcmp("ACK",request_method)==0) {
1174 		belle_sip_debug("no authorization header needed for method [%s]",request_method);
1175 		return 0;
1176 	}
1177 
1178 	if (from_uri==NULL){
1179 		from = belle_sip_message_get_header_by_type(request,belle_sip_header_from_t);
1180 		from_uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)from);
1181 	}
1182 
1183 	/*get authenticates value from response*/
1184 	if (resp) {
1185 		belle_sip_list_t *it;
1186 		call_id = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(resp),belle_sip_header_call_id_t);
1187 		/*searching for authentication headers*/
1188 		authenticate_lst = belle_sip_list_copy(belle_sip_message_get_headers(BELLE_SIP_MESSAGE(resp),BELLE_SIP_WWW_AUTHENTICATE));
1189 		/*search for proxy authenticate*/
1190 		authenticate_lst=belle_sip_list_concat(authenticate_lst,belle_sip_list_copy(belle_sip_message_get_headers(BELLE_SIP_MESSAGE(resp),BELLE_SIP_PROXY_AUTHENTICATE)));
1191 		/*update auth contexts with authenticate headers from response*/
1192 		for (it=authenticate_lst;it!=NULL;it=it->next) {
1193 			authenticate=BELLE_SIP_HEADER_WWW_AUTHENTICATE(it->data);
1194 			belle_sip_provider_update_or_create_auth_context(p,call_id,authenticate,from_uri,realm);
1195 		}
1196 		belle_sip_list_free(authenticate_lst);
1197 	}
1198 
1199 	/*put authorization header if passwd found*/
1200 	call_id = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_call_id_t);
1201 
1202 	belle_sip_debug("belle_sip_provider_auth: looking an auth context for [method=%s][realm=%s][user_id=%s][call_id=%s]"
1203 		, request_method
1204 		, realm?realm:"(null)"
1205 		, from_uri?belle_sip_uri_get_user(from_uri):"(null)"
1206 		, call_id?belle_sip_header_call_id_get_call_id(call_id):"(null)"
1207 	);
1208 	head=belle_sip_provider_get_auth_context_by_realm_or_call_id(p,call_id,from_uri,realm);
1209 	/*we assume there no existing auth headers*/
1210 	for (auth_context_iterator=head;auth_context_iterator!=NULL;auth_context_iterator=auth_context_iterator->next) {
1211 		/*clear auth info*/
1212 		auth_context=(authorization_context_t*)auth_context_iterator->data;
1213 		auth_event = belle_sip_auth_event_create((belle_sip_object_t*)p,auth_context->realm,from_uri);
1214 		/*put data*/
1215 		/*call listener*/
1216 		BELLE_SIP_PROVIDER_INVOKE_LISTENERS(p->listeners,process_auth_requested,auth_event);
1217 		if (auth_event->passwd || auth_event->ha1) {
1218 			if (!auth_event->userid) {
1219 				/*if no userid, username = userid*/
1220 
1221 				belle_sip_auth_event_set_userid(auth_event,auth_event->username);
1222 			}
1223 			belle_sip_message("Auth info found for [%s] realm [%s]",auth_event->userid,auth_event->realm);
1224 			if (auth_context->is_proxy ||
1225 				(!belle_sip_header_call_id_equals(call_id,auth_context->callid)
1226 						&&realm
1227 						&&strcmp(realm,auth_context->realm)==0
1228 						&&from_uri
1229 						&&strcmp(auth_event->username,belle_sip_uri_get_user(from_uri))==0
1230 						&&strcmp("REGISTER",request_method)!=0)) /* Relying on method name for choosing between authorization and proxy-authorization
1231 						is not very strong but I don't see any better solution as we don't know all the time what type of challange we will have*/{
1232 				authorization=BELLE_SIP_HEADER_AUTHORIZATION(belle_sip_header_proxy_authorization_new());
1233 			} else {
1234 				authorization=belle_sip_header_authorization_new();
1235 			}
1236 			belle_sip_header_authorization_set_scheme(authorization,auth_context->scheme);
1237 			belle_sip_header_authorization_set_realm(authorization,auth_context->realm);
1238 			belle_sip_header_authorization_set_username(authorization,auth_event->userid);
1239 			belle_sip_header_authorization_set_nonce(authorization,auth_context->nonce);
1240 			belle_sip_header_authorization_set_qop(authorization,auth_context->qop);
1241 			belle_sip_header_authorization_set_opaque(authorization,auth_context->opaque);
1242 			belle_sip_header_authorization_set_algorithm(authorization,auth_context->algorithm);
1243 			belle_sip_header_authorization_set_uri(authorization,(belle_sip_uri_t*)belle_sip_request_get_uri(request));
1244 			if (auth_context->qop){
1245 				++auth_context->nonce_count;
1246 				belle_sip_header_authorization_set_nonce_count(authorization,auth_context->nonce_count);
1247 			}
1248 
1249 			if (auth_event->ha1) {
1250 				ha1=auth_event->ha1;
1251 			} else {
1252 				belle_sip_auth_helper_compute_ha1(auth_event->userid,auth_context->realm,auth_event->passwd, computed_ha1);
1253 				ha1=computed_ha1;
1254 			}
1255 			if (belle_sip_auth_helper_fill_authorization(authorization
1256 														,belle_sip_request_get_method(request)
1257 														,ha1)) {
1258 				belle_sip_object_unref(authorization);
1259 			} else
1260 				belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(authorization));
1261 			result=1;
1262 		} else {
1263 			belle_sip_message("No auth info found for call id [%s]",belle_sip_header_call_id_get_call_id(call_id));
1264 		}
1265 		/*provides auth info in any cases, usefull even if found because auth info can contain wrong password*/
1266 		if (auth_infos) {
1267 			/*stored to give user information on realm/username which requires authentications*/
1268 			*auth_infos=belle_sip_list_append(*auth_infos,auth_event);
1269 		} else {
1270 			belle_sip_auth_event_destroy(auth_event);
1271 		}
1272 	}
1273 	belle_sip_list_free(head);
1274 	return result;
1275 }
1276 
belle_sip_provider_set_recv_error(belle_sip_provider_t * prov,int recv_error)1277 void belle_sip_provider_set_recv_error(belle_sip_provider_t *prov, int recv_error) {
1278 	belle_sip_list_t *lps;
1279 	belle_sip_list_t *channels;
1280 	for(lps=prov->lps;lps!=NULL;lps=lps->next){
1281 		for(channels=((belle_sip_listening_point_t*)lps->data)->channels;channels!=NULL;channels=channels->next){
1282 			((belle_sip_channel_t*)channels->data)->simulated_recv_return=recv_error;
1283 			((belle_sip_source_t*)channels->data)->notify_required=(recv_error<=0);
1284 		}
1285 	}
1286 }
belle_sip_provider_enable_rport(belle_sip_provider_t * prov,int enable)1287 void belle_sip_provider_enable_rport(belle_sip_provider_t *prov, int enable) {
1288 	prov->rport_enabled=enable;
1289 }
1290 
belle_sip_provider_is_rport_enabled(belle_sip_provider_t * prov)1291 int belle_sip_provider_is_rport_enabled(belle_sip_provider_t *prov) {
1292 	return prov->rport_enabled;
1293 }
1294 
belle_sip_provider_enable_nat_helper(belle_sip_provider_t * prov,int enabled)1295 void belle_sip_provider_enable_nat_helper(belle_sip_provider_t *prov, int enabled){
1296 	prov->nat_helper=enabled;
1297 }
1298 
belle_sip_provider_nat_helper_enabled(const belle_sip_provider_t * prov)1299 int belle_sip_provider_nat_helper_enabled(const belle_sip_provider_t *prov){
1300 	return prov->nat_helper;
1301 }
belle_sip_provider_enable_unconditional_answer(belle_sip_provider_t * prov,int enable)1302 void belle_sip_provider_enable_unconditional_answer(belle_sip_provider_t *prov, int enable) {
1303 	prov->unconditional_answer_enabled=enable;
1304 }
belle_sip_provider_set_unconditional_answer(belle_sip_provider_t * prov,unsigned short code)1305 void belle_sip_provider_set_unconditional_answer(belle_sip_provider_t *prov, unsigned short code) {
1306 	prov->unconditional_answer=code;
1307 }
1308