void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceModel *presence) { char *contact_info; char *content = NULL; size_t content_length; if (presence){ belle_sip_header_from_t *from=belle_sip_message_get_header_by_type(notify,belle_sip_header_from_t); contact_info=belle_sip_uri_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from))); op->base.root->callbacks.convert_presence_to_xml_requested(op, presence, contact_info, &content); belle_sip_free(contact_info); if (content == NULL) return; } belle_sip_message_remove_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_CONTENT_TYPE); belle_sip_message_remove_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_CONTENT_LENGTH); belle_sip_message_set_body(BELLE_SIP_MESSAGE(notify),NULL,0); if (content){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_content_type_create("application","pidf+xml"))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length=strlen(content)))); belle_sip_message_set_body(BELLE_SIP_MESSAGE(notify),content,content_length); ms_free(content); } }
int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* authorization ,const char* method ,const char* ha1) { int auth_mode=0; char* uri; char ha2[16*2 + 1]; char response[16*2 + 1]; char cnonce[9]; response[32]=ha2[32]='\0'; if (belle_sip_header_authorization_get_scheme(authorization) != NULL && strcmp("Digest",belle_sip_header_authorization_get_scheme(authorization))!=0) { belle_sip_error("belle_sip_fill_authorization_header, unsupported schema [%s]" ,belle_sip_header_authorization_get_scheme(authorization)); return -1; } if (belle_sip_header_authorization_get_qop(authorization) && !(auth_mode=strcmp("auth",belle_sip_header_authorization_get_qop(authorization))==0)) { belle_sip_error("belle_sip_fill_authorization_header, unsupported qop [%s], use auth or nothing instead" ,belle_sip_header_authorization_get_qop(authorization)); return -1; } CHECK_IS_PRESENT(authorization,authorization,realm) CHECK_IS_PRESENT(authorization,authorization,nonce) CHECK_IS_PRESENT(authorization,authorization,uri) if (auth_mode) { CHECK_IS_PRESENT(authorization,authorization,nonce_count) if (!belle_sip_header_authorization_get_cnonce(authorization)) { snprintf(cnonce,sizeof(cnonce),"%08x",(short)(long)authorization^0x5555555); /*spseudo randomly genrated cnonce*/ belle_sip_header_authorization_set_cnonce(authorization,cnonce); } } if (!method) { belle_sip_error("belle_sip_fill_authorization_header, method not found "); return -1; } uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)); belle_sip_auth_helper_compute_ha2(method,uri,ha2); belle_sip_free(uri); if (auth_mode) { /*response=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2)*/ belle_sip_auth_helper_compute_response_qop_auth(ha1 ,belle_sip_header_authorization_get_nonce(authorization) ,belle_sip_header_authorization_get_nonce_count(authorization) ,belle_sip_header_authorization_get_cnonce(authorization) ,belle_sip_header_authorization_get_qop(authorization) ,ha2 ,response); } else { /*response=MD5(ha1:nonce:ha2)*/ belle_sip_auth_helper_compute_response(ha1,belle_sip_header_authorization_get_nonce(authorization),ha2,response); } belle_sip_header_authorization_set_response(authorization,(const char*)response); return 0; }
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction){ belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t); belle_sip_header_referred_by_t *referred_by= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_referred_by_t); belle_sip_response_t* resp; belle_sip_uri_t* refer_to_uri; char* refer_to_uri_str; ms_message("Receiving REFER request on op [%p]",op); if (refer_to) { refer_to_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)); if (refer_to_uri && belle_sip_uri_get_header(refer_to_uri,"Replaces")) { sal_op_set_replaces(op,belle_sip_header_replaces_create2(belle_sip_uri_get_header(refer_to_uri,"Replaces"))); belle_sip_uri_remove_header(refer_to_uri,"Replaces"); } if (referred_by){ sal_op_set_referred_by(op,referred_by); } refer_to_uri_str=belle_sip_uri_to_string(refer_to_uri); resp = sal_op_create_response_from_request(op,req,202); belle_sip_server_transaction_send_response(server_transaction,resp); op->base.root->callbacks.refer_received(op->base.root,op,refer_to_uri_str); belle_sip_free(refer_to_uri_str); } else { ms_warning("cannot do anything with the refer without destination\n"); resp = sal_op_create_response_from_request(op,req,400); belle_sip_server_transaction_send_response(server_transaction,resp); } }
int sal_call_refer_to(SalOp *op, belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by){ char* tmp; belle_sip_request_t* req=op->dialog?belle_sip_dialog_create_request(op->dialog,"REFER"):sal_op_build_request(op, "REFER"); if (!req) { tmp=belle_sip_uri_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to))); ms_error("Cannot refer to [%s] for op [%p]",tmp,op); belle_sip_free(tmp); return -1; } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(refer_to)); if (referred_by) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(referred_by)); return sal_op_send_request(op,req); }
static void server_process_request_event(void *obj, const belle_sip_request_event_t *event){ endpoint_t* endpoint = (endpoint_t*)obj; belle_sip_server_transaction_t* server_transaction =belle_sip_provider_create_server_transaction(endpoint->provider,belle_sip_request_event_get_request(event)); belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction)); belle_sip_response_t* resp; belle_sip_header_contact_t* contact; belle_sip_header_expires_t* expires; belle_sip_header_authorization_t* authorization; belle_sip_header_via_t* via; const char* raw_authenticate_digest = "WWW-Authenticate: Digest " "algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; belle_sip_header_www_authenticate_t* www_authenticate=NULL; const char* auth_uri; const char* qop; unsigned char auth_ok=0; char local_resp[33]; belle_sip_message("caller_process_request_event received [%s] message",belle_sip_request_get_method(belle_sip_request_event_get_request(event))); switch (endpoint->auth) { case none: { auth_ok=1; break; } case digest_auth: case digest: { if ((authorization=belle_sip_message_get_header_by_type(req,belle_sip_header_authorization_t)) != NULL){ qop=belle_sip_header_authorization_get_qop(authorization); if (qop && strcmp(qop,"auth")==0) { compute_response_auth_qop( belle_sip_header_authorization_get_username(authorization) ,belle_sip_header_authorization_get_realm(authorization) ,PASSWD ,endpoint->nonce ,endpoint->nonce_count ,belle_sip_header_authorization_get_cnonce(authorization) ,belle_sip_header_authorization_get_qop(authorization) ,belle_sip_request_get_method(req) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) ,local_resp); } else { /*digest*/ compute_response(belle_sip_header_authorization_get_username(authorization) ,belle_sip_header_authorization_get_realm(authorization) ,PASSWD ,endpoint->nonce ,belle_sip_request_get_method(req) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) ,local_resp); } belle_sip_free((void*)auth_uri); auth_ok=strcmp(belle_sip_header_authorization_get_response(authorization),local_resp)==0; } if (auth_ok && endpoint->nonce_count<MAX_NC_COUNT ) {/*revoke nonce after MAX_NC_COUNT uses*/ if (endpoint->auth == digest ) { sprintf(endpoint->nonce,"%p",authorization); //*change the nonce for next auth*/ } else { endpoint->nonce_count++; } } else { auth_ok=0; www_authenticate=belle_sip_header_www_authenticate_parse(raw_authenticate_digest); sprintf(endpoint->nonce,"%p",authorization); //*change the nonce for next auth*/ belle_sip_header_www_authenticate_set_nonce(www_authenticate,endpoint->nonce); if (endpoint->auth == digest_auth) { belle_sip_header_www_authenticate_add_qop(www_authenticate,"auth"); if (endpoint->nonce_count>=MAX_NC_COUNT) { belle_sip_header_www_authenticate_set_stale(www_authenticate,1); endpoint->nonce_count=1; } } } } break; default: break; } if (auth_ok) { resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),200); if (!endpoint->expire_in_contact) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires=belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t))); } if (strcmp(belle_sip_request_get_method(req),"REGISTER")==0) { contact=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t); } else { contact=belle_sip_header_contact_new(); } if(endpoint->unreconizable_contact) { /*put an unexpected address*/ belle_sip_uri_set_host(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact)),"nimportequoi.com"); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(contact)); if (strcmp(belle_sip_request_get_method(req),"PUBLISH")==0) { belle_sip_header_t* sip_if_match=belle_sip_message_get_header(BELLE_SIP_MESSAGE(resp),"SIP-If-Match"); if (sip_if_match) { CU_ASSERT_STRING_EQUAL(belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(sip_if_match)),"blablietag"); } /*check for body*/ CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))); if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) { CU_ASSERT_STRING_EQUAL(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),publish_body); } CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t)); CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header_by_type(req,belle_sip_header_content_length_t)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),belle_sip_header_create("SIP-ETag","blablietag")); } } else { resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),401); if (www_authenticate) belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(www_authenticate)); } if (endpoint->received) { via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t); belle_sip_header_via_set_received(via,endpoint->received); } belle_sip_server_transaction_send_response(server_transaction,resp); }
int belle_sip_auth_helper_fill_authorization(belle_sip_header_authorization_t* authorization ,const char* method ,const char* ha1) { int auth_mode=0; char* uri; char ha2[16*2 + 1]; char response[16*2 + 1]; char cnonce[9]; response[32]=ha2[32]='\0'; if (belle_sip_header_authorization_get_scheme(authorization) != NULL && strcmp("Digest",belle_sip_header_authorization_get_scheme(authorization))!=0) { belle_sip_error("belle_sip_fill_authorization_header, unsupported schema [%s]" ,belle_sip_header_authorization_get_scheme(authorization)); return -1; } if (belle_sip_header_authorization_get_qop(authorization) && !(auth_mode=strcmp("auth",belle_sip_header_authorization_get_qop(authorization))==0)) { belle_sip_error("belle_sip_fill_authorization_header, unsupported qop [%s], use auth or nothing instead" ,belle_sip_header_authorization_get_qop(authorization)); return -1; } CHECK_IS_PRESENT(authorization,authorization,realm) CHECK_IS_PRESENT(authorization,authorization,nonce) if (BELLE_SIP_IS_INSTANCE_OF(authorization,belle_http_header_authorization_t)) { /*http case*/ if (!belle_http_header_authorization_get_uri(BELLE_HTTP_HEADER_AUTHORIZATION(authorization))) { belle_sip_error("parameter uri not found for http header authorization"); return-1; } } else { CHECK_IS_PRESENT(authorization,authorization,uri) } if (auth_mode) { CHECK_IS_PRESENT(authorization,authorization,nonce_count) if (!belle_sip_header_authorization_get_cnonce(authorization)) { int cnonce_value=0; belle_sip_random_bytes((unsigned char*)&cnonce_value, sizeof(cnonce_value)); snprintf(cnonce, sizeof(cnonce), "%08x", cnonce_value); belle_sip_header_authorization_set_cnonce(authorization,cnonce); } } if (!method) { belle_sip_error("belle_sip_fill_authorization_header, method not found "); return -1; } if (BELLE_SIP_IS_INSTANCE_OF(authorization,belle_http_header_authorization_t)) { /*http case*/ uri=belle_generic_uri_to_string(belle_http_header_authorization_get_uri(BELLE_HTTP_HEADER_AUTHORIZATION(authorization))); } else { uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)); } belle_sip_auth_helper_compute_ha2(method,uri,ha2); belle_sip_free(uri); if (auth_mode) { /*response=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2)*/ belle_sip_auth_helper_compute_response_qop_auth(ha1 ,belle_sip_header_authorization_get_nonce(authorization) ,belle_sip_header_authorization_get_nonce_count(authorization) ,belle_sip_header_authorization_get_cnonce(authorization) ,belle_sip_header_authorization_get_qop(authorization) ,ha2 ,response); } else { /*response=MD5(ha1:nonce:ha2)*/ belle_sip_auth_helper_compute_response(ha1,belle_sip_header_authorization_get_nonce(authorization),ha2,response); } belle_sip_header_authorization_set_response(authorization,(const char*)response); return 0; }