belle_sip_request_t* try_register_user_at_domain(belle_sip_stack_t * stack ,belle_sip_provider_t *prov ,const char *transport ,int use_transaction ,const char* username ,const char* domain ,const char* outbound_proxy ,int success_expected) { belle_sip_request_t *req,*copy; char identity[256]; char uri[256]; int i; char *outbound=NULL; number_of_challenge=0; if (transport) snprintf(uri,sizeof(uri),"sip:%s;transport=%s",domain,transport); else snprintf(uri,sizeof(uri),"sip:%s",domain); if (transport && strcasecmp("tls",transport)==0 && belle_sip_provider_get_listening_point(prov,"tls")==NULL){ belle_sip_error("No TLS support, test skipped."); return NULL; } if (outbound_proxy){ if (strstr(outbound_proxy,"sip:")==NULL && strstr(outbound_proxy,"sips:")==NULL){ outbound=belle_sip_strdup_printf("sip:%s",outbound_proxy); }else outbound=belle_sip_strdup(outbound_proxy); } snprintf(identity,sizeof(identity),"Tester <sip:%s@%s>",username,domain); req=belle_sip_request_create( belle_sip_uri_parse(uri), "REGISTER", belle_sip_provider_create_call_id(prov), belle_sip_header_cseq_create(20,"REGISTER"), belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG), belle_sip_header_to_create2(identity,NULL), belle_sip_header_via_new(), 70); is_register_ok=0; io_error_count=0; using_transaction=0; belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_contact_new())); copy=(belle_sip_request_t*)belle_sip_object_ref(belle_sip_object_clone((belle_sip_object_t*)req)); belle_sip_provider_add_sip_listener(prov,l=BELLE_SIP_LISTENER(listener)); if (use_transaction){ belle_sip_client_transaction_t *t=belle_sip_provider_create_client_transaction(prov,req); belle_sip_client_transaction_send_request_to(t,outbound?belle_sip_uri_parse(outbound):NULL); }else belle_sip_provider_send_request(prov,req); for(i=0;!is_register_ok && i<2 && io_error_count==0;i++) belle_sip_stack_sleep(stack,5000); CU_ASSERT_EQUAL(is_register_ok,success_expected); if (success_expected) CU_ASSERT_EQUAL(using_transaction,use_transaction); belle_sip_provider_remove_sip_listener(prov,l); if (outbound) belle_sip_free(outbound); return copy; }
belle_sip_header_contact_t* sal_op_create_contact(SalOp *op){ belle_sip_header_contact_t* contact_header; belle_sip_uri_t* contact_uri; if (sal_op_get_contact_address(op)) { contact_header = belle_sip_header_contact_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_contact_address(op))); } else { contact_header= belle_sip_header_contact_new(); } if (!(contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_header)))) { /*no uri, just creating a new one*/ contact_uri=belle_sip_uri_new(); belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact_header),contact_uri); } belle_sip_uri_set_user_password(contact_uri,NULL); belle_sip_uri_set_secure(contact_uri,sal_op_is_secure(op)); if (op->privacy!=SalPrivacyNone){ belle_sip_uri_set_user(contact_uri,NULL); } belle_sip_header_contact_set_automatic(contact_header,op->base.root->auto_contacts); if (op->base.root->uuid){ if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance")==0){ char *instance_id=belle_sip_strdup_printf("\"<urn:uuid:%s>\"",op->base.root->uuid); belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance",instance_id); belle_sip_free(instance_id); } } return contact_header; }
int main (int argc, char *argv[]) { int i; int ret; const char *root_ca_path = NULL; const char *env_domain=getenv("TEST_DOMAIN"); belle_sip_tester_init(NULL); #ifndef WIN32 /*this hack doesn't work for argv[0]="c:\blablab\"*/ // this allows to launch liblinphone_tester from outside of tester directory if (strstr(argv[0], ".libs")) { int prefix_length = strstr(argv[0], ".libs") - argv[0] + 1; char *prefix = belle_sip_strdup_printf("%s%.*s", argv[0][0] == '/' ? "" : "./", prefix_length, argv[0]); // printf("Resource prefix set to %s\n", prefix); bc_tester_set_resource_dir_prefix(prefix); bc_tester_set_writable_dir_prefix(prefix); belle_sip_free(prefix); } #endif if (env_domain) { test_domain=env_domain; } for(i=1;i<argc;++i){ if (strcmp(argv[i],"--verbose")==0){ belle_sip_set_log_level(BELLE_SIP_LOG_DEBUG); } else if (strcmp(argv[i],"--silent")==0){ belle_sip_set_log_level(BELLE_SIP_LOG_FATAL); } else if (strcmp(argv[i],"--log-file")==0){ CHECK_ARG("--log-file", ++i, argc); if (belle_sip_tester_set_log_file(argv[i]) < 0) return -2; } else if (strcmp(argv[i],"--domain")==0){ CHECK_ARG("--domain", ++i, argc); test_domain=argv[i]; }else if (strcmp(argv[i],"--auth-domain")==0){ CHECK_ARG("--auth-domain", ++i, argc); auth_domain=argv[i]; } else if (strcmp(argv[i], "--root-ca") == 0) { CHECK_ARG("--root-ca", ++i, argc); root_ca_path = argv[i]; }else { int ret = bc_tester_parse_args(argc, argv, i); if (ret>0) { i += ret - 1; continue; } else if (ret<0) { bc_tester_helper(argv[0], belle_sip_helper); } return ret; } } belle_sip_tester_set_root_ca_path(root_ca_path); pool=belle_sip_object_pool_push(); ret = bc_tester_start(argv[0]); belle_sip_tester_uninit(); return ret; }
void belle_sip_multipart_body_handler_progress_cb(belle_sip_body_handler_t *obj, belle_sip_message_t *msg, void *user_data, size_t transfered, size_t expected_total) { if (transfered == expected_total) { /* The full multipart body has been received, we can now parse it and split the different parts, * creating a belle_sip_memory_body_handler for each part and adding them to the belle_sip_multipart_body_handler * parts list. */ belle_sip_multipart_body_handler_t *obj_multipart = (belle_sip_multipart_body_handler_t *)obj; belle_sip_memory_body_handler_t *memorypart; belle_sip_header_t *header; uint8_t *end_part_cursor; uint8_t *end_headers_cursor; uint8_t *end_header_cursor; uint8_t *cursor = obj_multipart->buffer; char *boundary = belle_sip_strdup_printf("--%s", obj_multipart->boundary); if (strncmp((char *)cursor, boundary, strlen(boundary))) { belle_sip_warning("belle_sip_multipart_body_handler [%p]: body not starting by specified boundary '%s'", obj_multipart, obj_multipart->boundary); belle_sip_free(boundary); return; } cursor += strlen(boundary); do { if (strncmp((char *)cursor, "\r\n", 2)) { belle_sip_warning("belle_sip_multipart_body_handler [%p]: no new-line after boundary", obj_multipart); return; } cursor += 2; end_part_cursor = (uint8_t *)strstr((char *)cursor, boundary); if (end_part_cursor == NULL) { belle_sip_warning("belle_sip_multipart_body_handler [%p]: cannot find next boundary", obj_multipart); return; } else { *end_part_cursor = 0; end_headers_cursor = (uint8_t *)strstr((char *)cursor, "\r\n\r\n"); if (end_headers_cursor == NULL) { memorypart = belle_sip_memory_body_handler_new_copy_from_buffer(cursor, strlen((char *)cursor), NULL, NULL); } else { uint8_t *begin_body_cursor = end_headers_cursor + 4; memorypart = belle_sip_memory_body_handler_new_copy_from_buffer(begin_body_cursor, strlen((char *)begin_body_cursor), NULL, NULL); do { end_header_cursor = (uint8_t *)strstr((char *)cursor, "\r\n"); *end_header_cursor = 0; header = belle_sip_header_parse((char *)cursor); if (header != NULL) { belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(memorypart), header); } cursor = end_header_cursor + 2; } while (end_header_cursor != end_headers_cursor); } belle_sip_multipart_body_handler_add_part(obj_multipart, BELLE_SIP_BODY_HANDLER(memorypart)); cursor = end_part_cursor + strlen(boundary); } } while (strcmp((char *)cursor, "--\r\n")); belle_sip_free(boundary); } }
static void test_connection_too_long(const char *transport){ belle_sip_request_t *req; int orig=belle_sip_stack_get_transport_timeout(stack); char *no_response_here_with_transport = belle_sip_strdup_printf(no_response_here, transport); io_error_count=0; belle_sip_stack_set_transport_timeout(stack,2000); req=try_register_user_at_domain(stack, prov, transport,1,"tester","sip.linphone.org",no_response_here_with_transport,0); CU_ASSERT_TRUE(io_error_count>=1); belle_sip_stack_set_transport_timeout(stack,orig); belle_sip_free(no_response_here_with_transport); if (req) belle_sip_object_unref(req); }
static int send_notify_for_refer(SalOp* op, int code, const char *reason){ belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(op->dialog,"NOTIFY"); char *sipfrag=belle_sip_strdup_printf("SIP/2.0 %i %s\r\n",code,reason); size_t content_length=strlen(sipfrag); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,-1))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),belle_sip_header_create("Event","refer")); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(belle_sip_header_content_type_create("message","sipfrag"))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length))); belle_sip_message_assign_body(BELLE_SIP_MESSAGE(notify),sipfrag,content_length); return sal_op_send_request(op,notify); }
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END void belle_sip_client_transaction_init(belle_sip_client_transaction_t *obj, belle_sip_provider_t *prov, belle_sip_request_t *req){ belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header((belle_sip_message_t*)req,"via")); char token[BELLE_SIP_BRANCH_ID_LENGTH]; if (!via){ belle_sip_fatal("belle_sip_client_transaction_init(): No via in request."); } if (strcmp(belle_sip_request_get_method(req),"CANCEL")!=0){ obj->base.branch_id=belle_sip_strdup_printf(BELLE_SIP_BRANCH_MAGIC_COOKIE ".%s",belle_sip_random_token(token,sizeof(token))); belle_sip_header_via_set_branch(via,obj->base.branch_id); }else{ obj->base.branch_id=belle_sip_strdup(belle_sip_header_via_get_branch(via)); } belle_sip_transaction_init((belle_sip_transaction_t*)obj, prov,req); }
static void _linphone_nat_policy_save_to_config(const LinphoneNatPolicy *policy, LpConfig *config, int index) { char *section; bctbx_list_t *l = NULL; section = belle_sip_strdup_printf("nat_policy_%i", index); lp_config_set_string(config, section, "ref", policy->ref); lp_config_set_string(config, section, "stun_server", policy->stun_server); lp_config_set_string(config, section, "stun_server_username", policy->stun_server_username); if (linphone_nat_policy_upnp_enabled(policy)) { l = bctbx_list_append(l, "upnp"); } else { if (linphone_nat_policy_stun_enabled(policy)) l = bctbx_list_append(l, "stun"); if (linphone_nat_policy_turn_enabled(policy)) l = bctbx_list_append(l, "turn"); if (linphone_nat_policy_ice_enabled(policy)) l = bctbx_list_append(l, "ice"); } lp_config_set_string_list(config, section, "protocols", l); belle_sip_free(section); bctbx_list_free(l); }
char *belle_sip_object_describe_type_from_name(const char *name){ char *vptr_name; void *handle; void *symbol; handle=dlopen(NULL,RTLD_LAZY); if (handle==NULL){ belle_sip_error("belle_sip_object_describe_type_from_name: dlopen() failed: %s",dlerror()); return NULL; } vptr_name=belle_sip_strdup_printf("%s_vptr",name); symbol=dlsym(handle,vptr_name); belle_sip_free(vptr_name); dlclose(handle); if (symbol==NULL){ belle_sip_error("belle_sip_object_describe_type_from_name: could not find vptr for type %s",name); return NULL; } return _belle_sip_object_describe_type((belle_sip_object_vptr_t*)symbol); }
void linphone_nat_policy_save_to_config(const LinphoneNatPolicy *policy) { LpConfig *config = policy->lc->config; char *section; int index; bool_t finished = FALSE; for (index = 0; finished != TRUE; index++) { section = belle_sip_strdup_printf("nat_policy_%i", index); if (lp_config_has_section(config, section)) { const char *config_ref = lp_config_get_string(config, section, "ref", NULL); if ((config_ref != NULL) && (strcmp(config_ref, policy->ref) == 0)) { _linphone_nat_policy_save_to_config(policy, config, index); finished = TRUE; } } else { _linphone_nat_policy_save_to_config(policy, config, index); finished = TRUE; } belle_sip_free(section); } }
static void split_request_url(belle_http_request_t *req){ belle_generic_uri_t *uri=belle_http_request_get_uri(req); belle_generic_uri_t *new_uri; char *host_value; const char *path; if (belle_generic_uri_get_host(uri)==NULL && req->orig_uri!=NULL) return;/*already processed request uri*/ path=belle_generic_uri_get_path(uri); if (path==NULL) path="/"; new_uri=belle_generic_uri_new(); belle_generic_uri_set_path(new_uri,path); belle_generic_uri_set_query(new_uri, belle_generic_uri_get_query(uri)); if (belle_generic_uri_get_port(uri)>0) host_value=belle_sip_strdup_printf("%s:%i",belle_generic_uri_get_host(uri),belle_generic_uri_get_port(uri)); else host_value=belle_sip_strdup(belle_generic_uri_get_host(uri)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Host",host_value)); belle_sip_free(host_value); SET_OBJECT_PROPERTY(req,orig_uri,uri); belle_http_request_set_uri(req,new_uri); }
LinphoneNatPolicy * linphone_core_create_nat_policy_from_config(LinphoneCore *lc, const char *ref) { LpConfig *config = lc->config; LinphoneNatPolicy *policy = NULL; char *section; int index; bool_t finished = FALSE; for (index = 0; finished != TRUE; index++) { section = belle_sip_strdup_printf("nat_policy_%i", index); if (lp_config_has_section(config, section)) { const char *config_ref = lp_config_get_string(config, section, "ref", NULL); if ((config_ref != NULL) && (strcmp(config_ref, ref) == 0)) { const char *server = lp_config_get_string(config, section, "stun_server", NULL); const char *username = lp_config_get_string(config, section, "stun_server_username", NULL); bctbx_list_t *l = lp_config_get_string_list(config, section, "protocols", NULL); policy = _linphone_nat_policy_new_with_ref(lc, ref); if (server != NULL) linphone_nat_policy_set_stun_server(policy, server); if (username != NULL) linphone_nat_policy_set_stun_server_username(policy, username); if (l != NULL) { bool_t upnp_enabled = FALSE; bctbx_list_t *elem; for (elem = l; elem != NULL; elem = elem->next) { const char *value = (const char *)elem->data; if (strcmp(value, "stun") == 0) linphone_nat_policy_enable_stun(policy, TRUE); else if (strcmp(value, "turn") == 0) linphone_nat_policy_enable_turn(policy, TRUE); else if (strcmp(value, "ice") == 0) linphone_nat_policy_enable_ice(policy, TRUE); else if (strcmp(value, "upnp") == 0) upnp_enabled = TRUE; } if (upnp_enabled) linphone_nat_policy_enable_upnp(policy, TRUE); } finished = TRUE; } } else finished = TRUE; belle_sip_free(section); } return policy; }
char *belle_sip_object_describe_type_from_name(const char *name){ return belle_sip_strdup_printf("Sorry belle_sip_object_describe_type_from_name() is not implemented on this platform."); }
char *belle_sip_channel_get_public_ip_port(belle_sip_channel_t *obj){ if (obj->public_ip){ return belle_sip_strdup_printf("%s:%d", obj->public_ip, obj->public_port); } return NULL; }
static int belle_sip_tls_channel_load_root_ca(belle_sip_tls_channel_t *obj, const char *path){ struct stat statbuf; if (stat(path,&statbuf)==0){ if (statbuf.st_mode & S_IFDIR){ #if POLARSSL_VERSION_NUMBER < 0x01030000 if (x509parse_crtpath(&obj->root_ca,path)<0){ #else if (x509_crt_parse_path(&obj->root_ca,path)<0){ #endif belle_sip_error("Failed to load root ca from directory %s",path); return -1; } }else{ #if POLARSSL_VERSION_NUMBER < 0x01030000 if (x509parse_crtfile(&obj->root_ca,path)<0){ #else if (x509_crt_parse_file(&obj->root_ca,path)<0){ #endif belle_sip_error("Failed to load root ca from file %s",path); return -1; } } return 0; } belle_sip_error("Could not load root ca from %s: %s",path,strerror(errno)); return -1; } #ifdef ENABLE_POLARSSL_LOGS /* * polarssl does a lot of logs, some with newline, some without. * We need to concatenate logs without new line until a new line is found. */ static void ssl_debug_to_belle_sip(void *context, int level, const char *str){ belle_sip_tls_channel_t *chan=(belle_sip_tls_channel_t*)context; int len=strlen(str); if (len>0 && (str[len-1]=='\n' || str[len-1]=='\r')){ /*eliminate the newline*/ char *tmp=belle_sip_strdup(str); tmp[len-1]=0; if (chan->cur_debug_msg){ belle_sip_message("ssl: %s%s",chan->cur_debug_msg,tmp); belle_sip_free(chan->cur_debug_msg); chan->cur_debug_msg=NULL; }else belle_sip_message("ssl: %s",tmp); belle_sip_free(tmp); }else{ if (chan->cur_debug_msg){ char *tmp=belle_sip_strdup_printf("%s%s",chan->cur_debug_msg,str); belle_sip_free(chan->cur_debug_msg); chan->cur_debug_msg=tmp; }else chan->cur_debug_msg=belle_sip_strdup(str); } } #endif belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_stack_t *stack, belle_tls_verify_policy_t *verify_ctx,const char *bindip, int localport, const char *peer_cname, const char *dest, int port){ belle_sip_tls_channel_t *obj=belle_sip_object_new(belle_sip_tls_channel_t); belle_sip_stream_channel_t* super=(belle_sip_stream_channel_t*)obj; belle_sip_stream_channel_init_client(super ,stack ,bindip,localport,peer_cname,dest,port); ssl_init(&obj->sslctx); #ifdef ENABLE_POLARSSL_LOGS ssl_set_dbg(&obj->sslctx,ssl_debug_to_belle_sip,obj); #endif ssl_set_endpoint(&obj->sslctx,SSL_IS_CLIENT); ssl_set_authmode(&obj->sslctx,SSL_VERIFY_REQUIRED); ssl_set_bio(&obj->sslctx,polarssl_read,obj,polarssl_write,obj); if (verify_ctx->root_ca && belle_sip_tls_channel_load_root_ca(obj,verify_ctx->root_ca)==0){ ssl_set_ca_chain(&obj->sslctx,&obj->root_ca,NULL,super->base.peer_cname ? super->base.peer_cname : super->base.peer_name ); } ssl_set_rng(&obj->sslctx,random_generator,NULL); ssl_set_verify(&obj->sslctx,belle_sip_ssl_verify,verify_ctx); obj->verify_ctx=(belle_tls_verify_policy_t*)belle_sip_object_ref(verify_ctx); return (belle_sip_channel_t*)obj; }