Commit b3f9f492 authored by jehan's avatar jehan

rework http proxy to support both sips & https

parent 2900a617
......@@ -69,13 +69,6 @@ BELLESIP_EXPORT int belle_sip_tls_listening_point_set_verify_exceptions(belle_si
BELLESIP_EXPORT int belle_sip_tls_listening_point_set_verify_policy(belle_sip_tls_listening_point_t *s, belle_tls_verify_policy_t *pol);
BELLESIP_EXPORT void belle_sip_tls_listening_point_set_http_proxy_host(belle_sip_tls_listening_point_t *s, const char* proxy_addr);
BELLESIP_EXPORT void belle_sip_tls_listening_point_set_http_proxy_port(belle_sip_tls_listening_point_t *s, int port);
BELLESIP_EXPORT const char *belle_sip_tls_listening_point_get_http_proxy_addr(const belle_sip_tls_listening_point_t *s);
BELLESIP_EXPORT int belle_sip_tls_listening_point_get_http_proxy_port(const belle_sip_tls_listening_point_t *s);
BELLESIP_EXPORT belle_sip_listening_point_t * belle_sip_tunnel_listening_point_new(belle_sip_stack_t *s, void *tunnelclient);
......
......@@ -150,6 +150,12 @@ BELLESIP_EXPORT const belle_sip_timer_config_t *belle_sip_stack_get_timer_config
* */
BELLESIP_EXPORT void belle_sip_stack_set_timer_config(belle_sip_stack_t *stack, const belle_sip_timer_config_t *timer_config);
BELLESIP_EXPORT void belle_sip_stack_set_http_proxy_host(belle_sip_stack_t *stack, const char* proxy_addr);
BELLESIP_EXPORT void belle_sip_stack_set_http_proxy_port(belle_sip_stack_t *stack, int port);
BELLESIP_EXPORT const char *belle_sip_stack_get_http_proxy_host(const belle_sip_stack_t *stack);
BELLESIP_EXPORT int belle_sip_stack_get_http_proxy_port(const belle_sip_stack_t *stack);
BELLE_SIP_END_DECLS
#endif
......
......@@ -521,6 +521,12 @@ struct belle_sip_stack{
char *dns_user_hosts_file; /* used to load additional hosts file for tests */
char *dns_resolv_conf; /*used to load custom resolv.conf, for tests*/
unsigned char dns_srv_enabled;
/*http proxy stuff to be used by both http and sip provider*/
char *http_proxy_host;
int http_proxy_port;
char *http_proxy_username; /*for futur use*/
char *http_proxy_passwd; /*for futur use*/
};
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port);
......
......@@ -92,10 +92,6 @@ belle_sip_listening_point_t * belle_sip_stream_listening_point_new(belle_sip_sta
struct belle_sip_tls_listening_point{
belle_sip_stream_listening_point_t base;
belle_tls_verify_policy_t *verify_ctx;
char *http_proxy_host;
int http_proxy_port;
char *http_proxy_username; /*for futur use*/
char *http_proxy_passwd; /*for futur use*/
};
int belle_sip_tls_listening_point_available(void);
......
......@@ -101,6 +101,10 @@ static void belle_sip_stack_destroy(belle_sip_stack_t *stack){
if (stack->dns_user_hosts_file) belle_sip_free(stack->dns_user_hosts_file);
if (stack->dns_resolv_conf) belle_sip_free(stack->dns_resolv_conf);
belle_sip_object_unref(stack->ml);
if (stack->http_proxy_host) belle_sip_free(stack->http_proxy_host);
if (stack->http_proxy_passwd) belle_sip_free(stack->http_proxy_passwd);
if (stack->http_proxy_username) belle_sip_free(stack->http_proxy_username);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_stack_t);
......@@ -275,3 +279,6 @@ int belle_sip_stack_tls_available(belle_sip_stack_t *stack){
return belle_sip_tls_listening_point_available();
}
GET_SET_STRING(belle_sip_stack,http_proxy_host)
GET_SET_INT(belle_sip_stack,http_proxy_port, int)
......@@ -205,12 +205,11 @@ static void http_proxy_res_done(void *data, const char *name, struct addrinfo *a
}
static int tls_channel_connect(belle_sip_channel_t *obj, const struct addrinfo *ai){
belle_sip_tls_listening_point_t * lp = (belle_sip_tls_listening_point_t * )obj->lp;
belle_sip_tls_channel_t *channel=(belle_sip_tls_channel_t*)obj;
if (lp && lp->http_proxy_host) {
belle_sip_message("Resolving http proxy addr [%s] for channel [%p]",lp->http_proxy_host,obj);
if (obj->stack->http_proxy_host) {
belle_sip_message("Resolving http proxy addr [%s] for channel [%p]",obj->stack->http_proxy_host,obj);
/*assume ai family is the same*/
channel->http_proxy_resolver_ctx = belle_sip_stack_resolve_a(obj->stack, lp->http_proxy_host, lp->http_proxy_port, obj->ai_family, http_proxy_res_done, obj);
channel->http_proxy_resolver_ctx = belle_sip_stack_resolve_a(obj->stack, obj->stack->http_proxy_host, obj->stack->http_proxy_port, obj->ai_family, http_proxy_res_done, obj);
if (channel->http_proxy_resolver_ctx) belle_sip_object_ref(channel->http_proxy_resolver_ctx);
return 0;
} else {
......@@ -307,7 +306,6 @@ static int tls_process_http_connect(belle_sip_tls_channel_t *obj) {
#ifdef HAVE_POLARSSL
char* request;
belle_sip_channel_t *channel = (belle_sip_channel_t *)obj;
belle_sip_tls_listening_point_t* lp = (belle_sip_tls_listening_point_t*)channel->lp;
int err;
char ip[64];
int port;
......@@ -318,8 +316,8 @@ static int tls_process_http_connect(belle_sip_tls_channel_t *obj) {
,port
,ip);
if (lp->http_proxy_username && lp->http_proxy_passwd) {
char *username_passwd = belle_sip_strdup_printf("%s:%s",lp->http_proxy_username,lp->http_proxy_passwd);
if (channel->stack->http_proxy_username && channel->stack->http_proxy_passwd) {
char *username_passwd = belle_sip_strdup_printf("%s:%s",channel->stack->http_proxy_username,channel->stack->http_proxy_passwd);
size_t username_passwd_length = strlen(username_passwd);
size_t encoded_username_paswd_length = username_passwd_length*2;
unsigned char *encoded_username_paswd = belle_sip_malloc(2*username_passwd_length);
......@@ -334,8 +332,8 @@ static int tls_process_http_connect(belle_sip_tls_channel_t *obj) {
belle_sip_free(request);
if (err <= 0) {
belle_sip_error("tls_process_http_connect: fail to send connect request to http proxy [%s:%i] status [%s]"
,lp->http_proxy_host
,lp->http_proxy_port
,channel->stack->http_proxy_host
,channel->stack->http_proxy_port
,strerror(errno));
return -1;
}
......@@ -346,7 +344,6 @@ static int tls_process_http_connect(belle_sip_tls_channel_t *obj) {
}
static int tls_process_data(belle_sip_channel_t *obj,unsigned int revents){
belle_sip_tls_channel_t* channel=(belle_sip_tls_channel_t*)obj;
belle_sip_tls_listening_point_t* lp = (belle_sip_tls_listening_point_t*)(obj->lp);
int err;
if (obj->state == BELLE_SIP_CHANNEL_CONNECTING ) {
......@@ -359,42 +356,41 @@ static int tls_process_data(belle_sip_channel_t *obj,unsigned int revents){
channel->socket_connected=1;
belle_sip_source_set_events((belle_sip_source_t*)channel,BELLE_SIP_EVENT_READ|BELLE_SIP_EVENT_ERROR);
belle_sip_source_set_timeout((belle_sip_source_t*)obj,belle_sip_stack_get_transport_timeout(obj->stack));
if (lp && lp->http_proxy_host) {
if (obj->stack->http_proxy_host) {
belle_sip_message("Channel [%p]: Connected at TCP level, now doing http proxy connect",obj);
if (tls_process_http_connect(channel)) goto process_error;
} else {
belle_sip_message("Channel [%p]: Connected at TCP level, now doing TLS handshake",obj);
if (tls_process_handshake(obj)==-1) goto process_error;
}
} else if (lp && lp->http_proxy_host && !channel->http_proxy_connected) {
} else if (obj->stack->http_proxy_host && !channel->http_proxy_connected) {
char response[256];
err = stream_channel_recv((belle_sip_stream_channel_t*)obj,response,sizeof(response));
if (err<0 ){
belle_sip_error("Channel [%p]: connection refused by http proxy [%s:%i] status [%s]"
,channel
,lp->http_proxy_host
,lp->http_proxy_port
,obj->stack->http_proxy_host
,obj->stack->http_proxy_port
,strerror(errno));
goto process_error;
} else if (strstr(response,"407")) {
belle_sip_error("Channel [%p]: auth requested, provide user/passwd by http proxy [%s:%i]"
,channel
,lp->http_proxy_host
,lp->http_proxy_port);
,obj->stack->http_proxy_host
,obj->stack->http_proxy_port);
goto process_error;
} else if (strstr(response,"200")) {
belle_sip_message("Channel [%p]: connected to http proxy, doing TLS handshake [%s:%i] "
,channel
,lp->http_proxy_host
,lp->http_proxy_port);
,obj->stack->http_proxy_host
,obj->stack->http_proxy_port);
channel->http_proxy_connected = 1;
if (tls_process_handshake(obj)==-1) goto process_error;
} else {
belle_sip_error("Channel [%p]: connection refused by http proxy [%s:%i]"
,channel
,lp->http_proxy_host
,lp->http_proxy_port);
,obj->stack->http_proxy_host
,obj->stack->http_proxy_port);
goto process_error;
}
......@@ -1111,8 +1107,6 @@ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_signing_key_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_sip_signing_key_t,belle_sip_object_t,belle_sip_signing_key_destroy,belle_sip_signing_key_clone,NULL,TRUE);
GET_SET_STRING(belle_sip_tls_listening_point,http_proxy_host)
GET_SET_INT(belle_sip_tls_listening_point,http_proxy_port, int)
......
......@@ -24,9 +24,6 @@
static void belle_sip_tls_listening_point_uninit(belle_sip_tls_listening_point_t *lp){
belle_sip_object_unref(lp->verify_ctx);
if (lp->http_proxy_host) belle_sip_free(lp->http_proxy_host);
if (lp->http_proxy_passwd) belle_sip_free(lp->http_proxy_passwd);
if (lp->http_proxy_username) belle_sip_free(lp->http_proxy_username);
}
static belle_sip_channel_t *tls_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){
......
......@@ -324,10 +324,30 @@ static void http_get_long_user_body(void){
if (outfile) fclose(outfile);
}
extern const char *test_http_proxy_addr;
extern int test_http_proxy_port;
static void one_https_get_with_proxy(void){
http_counters_t counters={0};
belle_sip_stack_set_http_proxy_host(stack, test_http_proxy_addr);
belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
if (one_get("https://smtp.linphone.org",&counters,&counters.response_count) == 0) {
BC_ASSERT_EQUAL(counters.response_count, 1, int, "%d");
BC_ASSERT_EQUAL(counters.io_error_count, 0, int, "%d");
BC_ASSERT_EQUAL(counters.two_hundred,1,int,"%d");
}
belle_sip_stack_set_http_proxy_host(stack, NULL);
belle_sip_stack_set_http_proxy_port(stack, 0);
}
test_t http_tests[] = {
{ "One http GET", one_http_get },
{ "http GET of empty body", http_get_empty_body },
{ "One https GET", one_https_get },
{ "One https GET with http proxy", one_https_get_with_proxy },
{ "http request with io error", http_get_io_error },
{ "https GET with long body", https_get_long_body },
{ "https digest GET", https_digest_get },/*, FIXME, need a server for testing
......
......@@ -422,11 +422,11 @@ static void stateful_register_tls_with_http_proxy(void) {
return;
}
belle_sip_provider_clean_channels(prov);
belle_sip_tls_listening_point_set_http_proxy_host(lp, test_http_proxy_addr);
belle_sip_tls_listening_point_set_http_proxy_port(lp, test_http_proxy_port);
belle_sip_stack_set_http_proxy_host(stack, test_http_proxy_addr);
belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
register_test("tls",1);
belle_sip_tls_listening_point_set_http_proxy_host(lp, NULL);
belle_sip_tls_listening_point_set_http_proxy_port(lp, 0);
belle_sip_stack_set_http_proxy_host(stack, NULL);
belle_sip_stack_set_http_proxy_port(stack, 0);
}
......@@ -438,11 +438,11 @@ static void stateful_register_tls_with_wrong_http_proxy(void){
return;
}
belle_sip_provider_clean_channels(prov);
belle_sip_tls_listening_point_set_http_proxy_host(lp, "mauvaisproxy.linphone.org");
belle_sip_tls_listening_point_set_http_proxy_port(lp, test_http_proxy_port);
belle_sip_stack_set_http_proxy_host(stack, "mauvaisproxy.linphone.org");
belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
try_register_user_at_domain(stack,prov,"tls",1,"tester",test_domain,NULL,0);
belle_sip_tls_listening_point_set_http_proxy_host(lp, NULL);
belle_sip_tls_listening_point_set_http_proxy_port(lp, 0);
belle_sip_stack_set_http_proxy_host(stack, NULL);
belle_sip_stack_set_http_proxy_port(stack, 0);
}
......@@ -618,11 +618,11 @@ static void register_dns_srv_tls_with_http_proxy(void){
}
io_error_count=0;
belle_sip_provider_clean_channels(prov);
belle_sip_tls_listening_point_set_http_proxy_host(lp, test_http_proxy_addr);
belle_sip_tls_listening_point_set_http_proxy_port(lp, test_http_proxy_port);
belle_sip_stack_set_http_proxy_host(stack, test_http_proxy_addr);
belle_sip_stack_set_http_proxy_port(stack, test_http_proxy_port);
req=try_register_user_at_domain(stack, prov, "TLS",1,"tester",client_auth_domain,"sip:linphone.net;transport=tls",1);
belle_sip_tls_listening_point_set_http_proxy_host(lp, NULL);
belle_sip_tls_listening_point_set_http_proxy_port(lp, 0);
belle_sip_stack_set_http_proxy_host(stack, NULL);
belle_sip_stack_set_http_proxy_port(stack, 0);
BC_ASSERT_EQUAL(io_error_count, 0, int, "%d");
if (req) belle_sip_object_unref(req);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment