Commit e00c82e4 authored by Simon Morlat's avatar Simon Morlat

factorize ssl verification code

progress in http implementation
parent ab3232e2
......@@ -134,6 +134,15 @@ BELLESIP_EXPORT belle_sip_certificates_chain_t* belle_sip_certificates_chain_par
*/
BELLESIP_EXPORT belle_sip_signing_key_t* belle_sip_signing_key_parse_file(const char* path, const char* passwd);
BELLESIP_EXPORT belle_tls_verify_policy_t *belle_tls_verify_policy_new(void);
BELLESIP_EXPORT int belle_tls_verify_policy_set_root_ca(belle_tls_verify_policy_t *obj, const char *path);
#define BELLE_TLS_VERIFY_CN_MISMATCH (1)
#define BELLE_TLS_VERIFY_ANY_REASON (0xff)
BELLESIP_EXPORT void belle_tls_verify_policy_set_exceptions(belle_tls_verify_policy_t *obj, int flags);
BELLE_SIP_END_DECLS
#endif /* AUTHENTICATION_HELPER_H_ */
......@@ -22,27 +22,18 @@
#define belle_http_listener_h
struct belle_http_response_event{
belle_http_provider_t *provider;
belle_sip_object_t *source;
belle_http_request_t *request;
belle_http_response_t *response;
};
typedef struct belle_http_response_event belle_http_response_event_t;
struct belle_http_io_error_event{
belle_http_provider_t *provider;
belle_http_request_t *request;
};
typedef struct belle_http_io_error_event belle_http_io_error_event_t;
typedef struct belle_http_io_error_event belle_http_timeout_event_t;
#define BELLE_HTTP_INTERFACE_FUNCS(argT) \
void (*process_response)(argT *user_ctx, const belle_http_response_event_t *event); \
void (*process_io_error)(argT *user_ctx, const belle_http_io_error_event_t *event); \
void (*process_timeout)(argT *user_ctx, const belle_http_timeout_event_t *event); \
void (*process_io_error)(argT *user_ctx, const belle_sip_io_error_event_t *event); \
void (*process_timeout)(argT *user_ctx, const belle_sip_timeout_event_t *event); \
void (*process_auth_requested)(argT *user_ctx, belle_sip_auth_event_t *event);
BELLE_SIP_DECLARE_INTERFACE_BEGIN(belle_http_request_listener_t)
......
......@@ -25,6 +25,8 @@ BELLE_SIP_BEGIN_DECLS
#define BELLE_SIP_HTTP_PROVIDER(obj) BELLE_SIP_CAST(obj,belle_http_provider_t)
BELLESIP_EXPORT int belle_http_provider_set_tls_verify_policy(belle_http_provider_t *obj, belle_tls_verify_policy_t *verify_ctx);
BELLESIP_EXPORT int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_request_t *req, belle_http_request_listener_t *listener);
BELLE_SIP_END_DECLS
......
......@@ -59,12 +59,16 @@ BELLESIP_EXPORT void belle_sip_listening_point_clean_channels(belle_sip_listenin
BELLESIP_EXPORT int belle_sip_listening_point_get_channel_count(const belle_sip_listening_point_t *lp);
BELLESIP_EXPORT int belle_sip_listening_point_get_well_known_port(const char *transport);
/*deprecated*/
BELLESIP_EXPORT int belle_sip_tls_listening_point_set_root_ca(belle_sip_tls_listening_point_t *s, const char *path);
#define BELLE_SIP_TLS_LISTENING_POINT_BADCERT_CN_MISMATCH (1)
#define BELLE_SIP_TLS_LISTENING_POINT_BADCERT_ANY_REASON (0xff)
/*deprecated*/
#define BELLE_SIP_TLS_LISTENING_POINT_BADCERT_CN_MISMATCH BELLE_TLS_VERIFY_CN_MISMATCH
#define BELLE_SIP_TLS_LISTENING_POINT_BADCERT_ANY_REASON BELLE_TLS_VERIFY_ANY_REASON
BELLESIP_EXPORT int belle_sip_tls_listening_point_set_verify_exceptions(belle_sip_tls_listening_point_t *s, int flags);
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 belle_sip_listening_point_t * belle_sip_tunnel_listening_point_new(belle_sip_stack_t *s, void *tunnelclient);
......
......@@ -120,7 +120,8 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_http_response_t),
BELLE_SIP_TYPE_ID(belle_http_channel_context_t),
BELLE_SIP_TYPE_ID(belle_generic_uri_t),
BELLE_SIP_TYPE_ID(belle_http_callbacks_t)
BELLE_SIP_TYPE_ID(belle_http_callbacks_t),
BELLE_SIP_TYPE_ID(belle_tls_verify_policy_t)
BELLE_SIP_DECLARE_TYPES_END
......@@ -153,6 +154,7 @@ typedef struct _belle_sip_uri belle_sip_uri_t;
typedef struct _belle_sip_parameters belle_sip_parameters_t;
typedef struct belle_sip_param_pair belle_sip_param_pair_t;
typedef struct _belle_sip_header belle_sip_header_t;
typedef struct belle_tls_verify_policy belle_tls_verify_policy_t;
#endif
......
......@@ -30,9 +30,9 @@ GET_SET_STRING(belle_sip_auth_event,passwd)
GET_SET_STRING(belle_sip_auth_event,ha1)
GET_SET_STRING(belle_sip_auth_event,distinguished_name)
belle_sip_auth_event_t* belle_sip_auth_event_create(const char* realm, const belle_sip_header_from_t *from) {
belle_sip_auth_event_t* belle_sip_auth_event_create(belle_sip_object_t *source, const char* realm, const belle_sip_header_from_t *from) {
belle_sip_auth_event_t* result = belle_sip_new0(belle_sip_auth_event_t);
result->source=source;
belle_sip_auth_event_set_realm(result,realm);
if (from){
......@@ -82,3 +82,42 @@ belle_sip_auth_mode_t belle_sip_auth_event_get_mode(const belle_sip_auth_event_t
return event->mode;
}
static void verify_policy_uninit(belle_tls_verify_policy_t *obj){
if (obj->root_ca) belle_sip_free(obj->root_ca);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_tls_verify_policy_t);
BELLE_SIP_INSTANCIATE_VPTR(belle_tls_verify_policy_t,belle_sip_object_t,verify_policy_uninit,NULL,NULL,FALSE);
belle_tls_verify_policy_t *belle_tls_verify_policy_new(){
belle_tls_verify_policy_t *obj=belle_sip_object_new(belle_tls_verify_policy_t);
/*default to "system" default root ca, wihtout warranty...*/
#ifdef __linux
belle_tls_verify_policy_set_root_ca(obj,"/etc/ssl/certs");
#elif defined(__APPLE__)
belle_tls_verify_policy_set_root_ca(obj,"/opt/local/share/curl/curl-ca-bundle.crt");
#endif
return obj;
}
int belle_tls_verify_policy_set_root_ca(belle_tls_verify_policy_t *obj, const char *path){
if (obj->root_ca){
belle_sip_free(obj->root_ca);
obj->root_ca=NULL;
}
if (path){
obj->root_ca=belle_sip_strdup(path);
belle_sip_message("Root ca path set to %s",obj->root_ca);
} else {
belle_sip_message("Root ca path disabled");
}
return 0;
}
void belle_tls_verify_policy_set_exceptions(belle_tls_verify_policy_t *obj, int flags){
obj->exception_flags=flags;
}
......@@ -193,13 +193,13 @@ BELLE_SIP_DECLARE_VPTR(belle_sip_certificates_chain_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_signing_key_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_dns_srv_t);
BELLE_SIP_DECLARE_VPTR(belle_sip_dict_t)
BELLE_SIP_DECLARE_VPTR(belle_http_provider_t);
BELLE_SIP_DECLARE_VPTR(belle_http_channel_context_t);
BELLE_SIP_DECLARE_VPTR(belle_http_request_t);
BELLE_SIP_DECLARE_VPTR(belle_http_response_t);
BELLE_SIP_DECLARE_VPTR(belle_generic_uri_t);
BELLE_SIP_DECLARE_VPTR(belle_http_callbacks_t);
BELLE_SIP_DECLARE_VPTR(belle_tls_verify_policy_t);
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_resolver_context_t,belle_sip_source_t)
void (*cancel)(belle_sip_resolver_context_t *);
......@@ -605,6 +605,7 @@ struct belle_http_request{
belle_generic_uri_t *req_uri;
char* method;
belle_http_request_listener_t *listener;
belle_generic_uri_t *orig_uri;/*original uri before removing host and user/passwd*/
belle_http_response_t *response;
};
......@@ -868,21 +869,21 @@ struct belle_sip_io_error_event{
};
struct belle_sip_request_event{
belle_sip_provider_t *source;
belle_sip_object_t *source;
belle_sip_server_transaction_t *server_transaction;
belle_sip_dialog_t *dialog;
belle_sip_request_t *request;
};
struct belle_sip_response_event{
belle_sip_provider_t *source;
belle_sip_object_t *source;
belle_sip_client_transaction_t *client_transaction;
belle_sip_dialog_t *dialog;
belle_sip_response_t *response;
};
struct belle_sip_timeout_event{
belle_sip_provider_t *source;
belle_sip_object_t *source;
belle_sip_transaction_t *transaction;
int is_server_transaction;
};
......@@ -894,6 +895,7 @@ struct belle_sip_transaction_terminated_event{
};
struct belle_sip_auth_event {
belle_sip_object_t *source;
belle_sip_auth_mode_t mode;
char* username;
char* userid;
......@@ -904,10 +906,9 @@ struct belle_sip_auth_event {
char* distinguished_name;
belle_sip_certificates_chain_t * cert;
belle_sip_signing_key_t* key;
};
belle_sip_auth_event_t* belle_sip_auth_event_create(const char* realm,const belle_sip_header_from_t * from);
belle_sip_auth_event_t* belle_sip_auth_event_create(belle_sip_object_t *source, const char* realm,const belle_sip_header_from_t * from);
void belle_sip_auth_event_set_distinguished_name(belle_sip_auth_event_t* event,const char* value);
......@@ -946,6 +947,13 @@ void belle_sip_dialog_update_request(belle_sip_dialog_t *dialog, belle_sip_reque
belle_sip_error_code belle_sip_headers_marshal(belle_sip_message_t *message, char* buff, size_t buff_size, size_t *offset);
#define SET_OBJECT_PROPERTY(obj,property_name,new_value) \
if (new_value) belle_sip_object_ref(new_value); \
if (obj->property_name){ \
belle_sip_object_unref(obj->property_name); \
}\
obj->property_name=new_value;
#include "parserutils.h"
#endif
......@@ -485,8 +485,10 @@ struct addrinfo * belle_sip_ip_address_to_addrinfo(int family, const char *ipadd
hints.ai_flags|=AI_V4MAPPED;
}
err=getaddrinfo(ipaddress,serv,&hints,&res);
if (err!=0){
belle_sip_error("belle_sip_ip_address_to_addrinfo(): getaddrinfo() error: %s",gai_strerror(err));
if (err!=EAI_NONAME)
belle_sip_error("belle_sip_ip_address_to_addrinfo(): getaddrinfo() error: %s",gai_strerror(err));
return NULL;
}
return res;
......
......@@ -188,4 +188,10 @@ belle_sip_channel_t *belle_sip_channel_find_from_list(belle_sip_list_t *l, int a
#define BELLE_SIP_TLS_CHANNEL(obj) BELLE_SIP_CAST(obj,belle_sip_tls_channel_t)
struct belle_tls_verify_policy{
belle_sip_object_t base;
char *root_ca;
int exception_flags;
};
#endif
......@@ -34,13 +34,13 @@ static void process_response_event(belle_http_request_listener_t *l, const belle
obj->cbs.process_response(obj->user_ctx,event);
}
static void process_io_error(belle_http_request_listener_t *l, const belle_http_io_error_event_t *event){
static void process_io_error(belle_http_request_listener_t *l, const belle_sip_io_error_event_t *event){
belle_http_callbacks_t *obj=(belle_http_callbacks_t*)l;
if (obj->cbs.process_io_error)
obj->cbs.process_io_error(obj->user_ctx,event);
}
static void process_timeout(belle_http_request_listener_t *l, const belle_http_timeout_event_t *event){
static void process_timeout(belle_http_request_listener_t *l, const belle_sip_timeout_event_t *event){
belle_http_callbacks_t *obj=(belle_http_callbacks_t*)l;
if (obj->cbs.process_timeout)
obj->cbs.process_timeout(obj->user_ctx,event);
......
......@@ -32,6 +32,7 @@ static void belle_http_request_destroy(belle_http_request_t *req){
if (req->req_uri) belle_sip_object_unref(req->req_uri);
DESTROY_STRING(req,method)
belle_http_request_set_listener(req,NULL);
SET_OBJECT_PROPERTY(req,orig_uri,NULL);
belle_sip_message("http request destroyed");
}
......
......@@ -38,30 +38,78 @@ struct belle_http_provider{
int ai_family;
belle_sip_list_t *tcp_channels;
belle_sip_list_t *tls_channels;
belle_tls_verify_policy_t *verify_ctx;
};
#define BELLE_HTTP_REQUEST_INVOKE_LISTENER(obj,method,arg) \
obj->listener ? BELLE_SIP_INVOKE_LISTENER_ARG(obj->listener,belle_http_request_listener_t,method,arg) : 0
static int http_channel_context_handle_authentication(belle_http_channel_context_t *ctx, belle_http_request_t *req){
const char *realm=NULL;
belle_sip_auth_event_t *ev=NULL;
belle_http_response_t *resp=belle_http_request_get_response(req);
const char *username=NULL;
const char *passwd=NULL;
int ret=0;
(void)resp;
/*find if username, passwd were already supplied in original request uri*/
if (req->orig_uri){
username=belle_generic_uri_get_user(req->orig_uri);
passwd=belle_generic_uri_get_user_password(req->orig_uri);
}
if (username==NULL || passwd==NULL){
/*TODO find the realm from the Authentication header*/
ev=belle_sip_auth_event_create((belle_sip_object_t*)ctx->provider,realm,NULL);
BELLE_HTTP_REQUEST_INVOKE_LISTENER(req,process_auth_requested,ev);
username=ev->username;
passwd=ev->passwd;
}
if (username && passwd){
/*TODO resubmit the request to the provider with authentication added*/
belle_http_provider_send_request(ctx->provider,req,NULL);
}else ret=-1;
if (ev) belle_sip_auth_event_destroy(ev);
return ret;
}
static void http_channel_context_handle_response(belle_http_channel_context_t *ctx , belle_http_response_t *response){
belle_http_request_t *req=NULL;
belle_http_response_event_t ev={0};
int code;
/*pop the request matching this response*/
ctx->pending_requests=belle_sip_list_pop_front(ctx->pending_requests,(void**)&req);
if (req==NULL){
belle_sip_error("Receiving http response not matching any request.");
return;
}
belle_http_request_set_response(req,response);
code=belle_http_response_get_status_code(response);
if ((code==401 || code==407) && http_channel_context_handle_authentication(ctx,req)==0 ){
/*nothing to do, the request has been resubmitted with authentication*/
}else{
/*else notify the app about the response received*/
ev.source=(belle_sip_object_t*)ctx->provider;
ev.request=req;
ev.response=response;
BELLE_HTTP_REQUEST_INVOKE_LISTENER(req,process_response,&ev);
}
belle_sip_object_unref(req);
}
static int channel_on_event(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, unsigned int revents){
belle_http_channel_context_t *ctx=BELLE_HTTP_CHANNEL_CONTEXT(obj);
if (revents & BELLE_SIP_EVENT_READ){
belle_sip_message_t *msg;
while((msg=belle_sip_channel_pick_message(chan))!=NULL){
if (msg && BELLE_SIP_OBJECT_IS_INSTANCE_OF(msg,belle_http_response_t)){
belle_http_request_t *req=NULL;
belle_http_response_event_t ev={0};
/*pop the request matching this response*/
ctx->pending_requests=belle_sip_list_pop_front(ctx->pending_requests,(void**)&req);
if (req==NULL){
belle_sip_error("Receiving http response not matching any request.");
return 0;
}
ev.provider=NULL;
ev.request=req;
ev.response=(belle_http_response_t*)msg;
BELLE_HTTP_REQUEST_INVOKE_LISTENER(req,process_response,&ev);
belle_sip_object_unref(req);
http_channel_context_handle_response(ctx,(belle_http_response_t*)msg);
}
belle_sip_object_unref(msg);
}
......@@ -70,19 +118,18 @@ static int channel_on_event(belle_sip_channel_listener_t *obj, belle_sip_channel
}
static int channel_on_auth_requested(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, const char* distinguished_name){
belle_http_channel_context_t *ctx=BELLE_HTTP_CHANNEL_CONTEXT(obj);
if (BELLE_SIP_IS_INSTANCE_OF(chan,belle_sip_tls_channel_t)) {
/*
belle_http_provider_t *prov=BELLE_SIP_HTTP_PROVIDER(obj);
belle_sip_auth_event_t* auth_event = belle_sip_auth_event_create(NULL,NULL);
belle_sip_auth_event_t* auth_event = belle_sip_auth_event_create((belle_sip_object_t*)ctx->provider,NULL,NULL);
belle_sip_tls_channel_t *tls_chan=BELLE_SIP_TLS_CHANNEL(chan);
belle_http_request_t *req=(belle_http_request_t*)ctx->pending_requests->data;
auth_event->mode=BELLE_SIP_AUTH_MODE_TLS;
belle_sip_auth_event_set_distinguished_name(auth_event,distinguished_name);
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_auth_requested,auth_event);
BELLE_HTTP_REQUEST_INVOKE_LISTENER(req,process_auth_requested,auth_event);
belle_sip_tls_channel_set_client_certificates_chain(tls_chan,auth_event->cert);
belle_sip_tls_channel_set_client_certificate_key(tls_chan,auth_event->key);
belle_sip_auth_event_destroy(auth_event);
*/
}
return 0;
}
......@@ -147,6 +194,7 @@ static void http_provider_uninit(belle_http_provider_t *obj){
belle_sip_list_free_with_data(obj->tcp_channels,belle_sip_object_unref);
belle_sip_list_for_each(obj->tls_channels,(void (*)(void*))belle_sip_channel_force_close);
belle_sip_list_free_with_data(obj->tls_channels,belle_sip_object_unref);
belle_sip_object_unref(obj->verify_ctx);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_http_provider_t);
......@@ -157,6 +205,7 @@ belle_http_provider_t *belle_http_provider_new(belle_sip_stack_t *s, const char
p->stack=s;
p->bind_ip=belle_sip_strdup(bind_ip);
p->ai_family=strchr(p->bind_ip,':') ? AF_INET6 : AF_INET;
p->verify_ctx=belle_tls_verify_policy_new();
return p;
}
......@@ -173,6 +222,7 @@ static void split_request_url(belle_http_request_t *req){
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);
}
......@@ -197,12 +247,16 @@ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_requ
belle_sip_hop_t *hop=belle_sip_hop_new_from_generic_uri(belle_http_request_get_uri(req));
belle_sip_list_t **channels=provider_get_channels(obj,hop->transport);
belle_http_request_set_listener(req,listener);
if (listener) belle_http_request_set_listener(req,listener);
chan=belle_sip_channel_find_from_list(*channels,obj->ai_family, hop);
if (!chan){
chan=belle_sip_stream_channel_new_client(obj->stack,obj->bind_ip,0,hop->cname,hop->host,hop->port);
if (strcasecmp(hop->transport,"tcp")==0){
chan=belle_sip_stream_channel_new_client(obj->stack,obj->bind_ip,0,hop->cname,hop->host,hop->port);
}else if (strcasecmp(hop->transport,"tls")==0){
chan=belle_sip_channel_new_tls(obj->stack,obj->verify_ctx,obj->bind_ip,0,hop->cname,hop->host,hop->port);
}
belle_http_channel_context_new(chan,obj);
*channels=belle_sip_list_prepend(*channels,chan);
}
......@@ -212,3 +266,9 @@ int belle_http_provider_send_request(belle_http_provider_t *obj, belle_http_requ
return 0;
}
int belle_http_provider_set_tls_verify_policy(belle_http_provider_t *obj, belle_tls_verify_policy_t *verify_ctx){
SET_OBJECT_PROPERTY(obj,verify_ctx,verify_ctx);
return 0;
}
......@@ -85,8 +85,7 @@ 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;
char *root_ca;
int verify_exceptions;
belle_tls_verify_policy_t *verify_ctx;
};
int belle_sip_tls_listening_point_available(void);
......@@ -95,7 +94,7 @@ BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_tls_listening_point_t,belle_sip_li
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
#define BELLE_SIP_TLS_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_tls_listening_point_t)
belle_sip_listening_point_t * belle_sip_tls_listening_point_new(belle_sip_stack_t *s, const char *ipaddress, int port);
belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_tls_listening_point_t* lp, const char *bindip, int localport,const char *cname, const char *name, int port);
belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_stack_t *s, belle_tls_verify_policy_t* verify_ctx, const char *bindip, int localport,const char *cname, const char *name, int port);
/*tunnel*/
#ifdef HAVE_TUNNEL
......
......@@ -115,7 +115,7 @@ static void belle_sip_provider_dispatch_request(belle_sip_provider_t* prov, bell
belle_sip_server_transaction_send_response(tr,belle_sip_response_create_from_request(req,480));
return;
} else {
ev.source=prov;
ev.source=(belle_sip_object_t*)prov;
ev.server_transaction=NULL;
ev.request=req;
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(prov->listeners,process_request_event,&ev);
......@@ -156,7 +156,7 @@ static void belle_sip_provider_dispatch_response(belle_sip_provider_t* prov, bel
belle_sip_object_unref(t);
}else{
belle_sip_response_event_t event;
event.source=prov;
event.source=(belle_sip_object_t*)prov;
event.client_transaction=NULL;
event.dialog=NULL;
event.response=msg;
......@@ -317,7 +317,7 @@ static int channel_on_event(belle_sip_channel_listener_t *obj, belle_sip_channel
static int channel_on_auth_requested(belle_sip_channel_listener_t *obj, belle_sip_channel_t *chan, const char* distinguished_name){
if (BELLE_SIP_IS_INSTANCE_OF(chan,belle_sip_tls_channel_t)) {
belle_sip_provider_t *prov=BELLE_SIP_PROVIDER(obj);
belle_sip_auth_event_t* auth_event = belle_sip_auth_event_create(NULL,NULL);
belle_sip_auth_event_t* auth_event = belle_sip_auth_event_create((belle_sip_object_t*)prov,NULL,NULL);
belle_sip_tls_channel_t *tls_chan=BELLE_SIP_TLS_CHANNEL(chan);
auth_event->mode=BELLE_SIP_AUTH_MODE_TLS;
belle_sip_auth_event_set_distinguished_name(auth_event,distinguished_name);
......@@ -1004,7 +1004,7 @@ int belle_sip_provider_add_authorization(belle_sip_provider_t *p, belle_sip_requ
for (;auth_context_lst!=NULL;auth_context_lst=auth_context_lst->next) {
/*clear auth info*/
auth_context=(authorization_context_t*)auth_context_lst->data;
auth_event = belle_sip_auth_event_create(auth_context->realm,from);
auth_event = belle_sip_auth_event_create((belle_sip_object_t*)p,auth_context->realm,from);
/*put data*/
/*call listener*/
BELLE_SIP_PROVIDER_INVOKE_LISTENERS(p->listeners,process_auth_requested,auth_event);
......
......@@ -130,7 +130,7 @@ belle_sip_response_t *belle_sip_transaction_get_response(const belle_sip_transac
static void notify_timeout(belle_sip_transaction_t *t){
belle_sip_timeout_event_t ev;
ev.source=t->provider;
ev.source=(belle_sip_object_t*)t->provider;
ev.transaction=t;
ev.is_server_transaction=BELLE_SIP_OBJECT_IS_INSTANCE_OF(t,belle_sip_server_transaction_t);
BELLE_SIP_PROVIDER_INVOKE_LISTENERS_FOR_TRANSACTION(t,process_timeout,&ev);
......@@ -245,7 +245,7 @@ void belle_sip_server_transaction_send_response(belle_sip_server_transaction_t *
static void server_transaction_notify(belle_sip_server_transaction_t *t, belle_sip_request_t *req, belle_sip_dialog_t *dialog){
belle_sip_request_event_t event;
event.source=t->base.provider;
event.source=(belle_sip_object_t*)t->base.provider;
event.server_transaction=t;
event.dialog=dialog;
event.request=req;
......@@ -441,7 +441,7 @@ void belle_sip_client_transaction_notify_response(belle_sip_client_transaction_t
return;
}
event.source=base->provider;
event.source=(belle_sip_object_t*)base->provider;
event.client_transaction=t;
event.dialog=dialog;
event.response=(belle_sip_response_t*)resp;
......
......@@ -62,6 +62,7 @@ struct belle_sip_tls_channel{
char *cur_debug_msg;
belle_sip_certificates_chain_t* client_cert_chain;
belle_sip_signing_key_t* client_cert_key;
belle_tls_verify_policy_t *verify_ctx;
};
static void tls_channel_close(belle_sip_tls_channel_t *obj){
......@@ -81,6 +82,7 @@ static void tls_channel_uninit(belle_sip_tls_channel_t *obj){
x509_free(&obj->root_ca);
if (obj->cur_debug_msg)
belle_sip_free(obj->cur_debug_msg);
belle_sip_object_unref(obj->verify_ctx);
}
static int tls_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buflen){
......@@ -270,16 +272,16 @@ static const char *polarssl_certflags_to_string(char *buf, size_t size, int flag
}
static int belle_sip_ssl_verify(void *data , x509_cert *cert , int depth, int *flags){
belle_sip_tls_listening_point_t *lp=(belle_sip_tls_listening_point_t*)data;
belle_tls_verify_policy_t *verify_ctx=(belle_tls_verify_policy_t*)data;
char tmp[512];
char flags_str[128];
x509parse_cert_info(tmp,sizeof(tmp),"",cert);
belle_sip_message("Found certificate depth=[%i], flags=[%s]:\n%s",
depth,polarssl_certflags_to_string(flags_str,sizeof(flags_str),*flags),tmp);
if (lp->verify_exceptions==BELLE_SIP_TLS_LISTENING_POINT_BADCERT_ANY_REASON){
if (verify_ctx->exception_flags==BELLE_TLS_VERIFY_ANY_REASON){
*flags=0;
}else if (lp->verify_exceptions & BELLE_SIP_TLS_LISTENING_POINT_BADCERT_CN_MISMATCH){
}else if (verify_ctx->exception_flags & BELLE_TLS_VERIFY_CN_MISMATCH){
*flags&=~BADCERT_CN_MISMATCH;
}
return 0;
......@@ -335,12 +337,12 @@ static void ssl_debug_to_belle_sip(void *context, int level, const char *str){
#endif
belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_tls_listening_point_t *lp,const char *bindip, int localport, const char *peer_cname, const char *dest, int port){
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
,((belle_sip_listening_point_t*)lp)->stack
,stack
,bindip,localport,peer_cname,dest,port);
ssl_init(&obj->sslctx);
#ifdef ENABLE_POLARSSL_LOGS
......@@ -349,11 +351,12 @@ belle_sip_channel_t * belle_sip_channel_new_tls(belle_sip_tls_listening_point_t
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 (lp->root_ca && belle_sip_tls_channel_load_root_ca(obj,lp->root_ca)==0){
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,lp);
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;
}
......
......@@ -23,11 +23,11 @@
#include <polarssl/ssl.h>
static void belle_sip_tls_listening_point_uninit(belle_sip_tls_listening_point_t *lp){
belle_sip_free(lp->root_ca);
belle_sip_object_unref(lp->verify_ctx);
}
static belle_sip_channel_t *tls_create_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop){
belle_sip_channel_t *chan=belle_sip_channel_new_tls(BELLE_SIP_TLS_LISTENING_POINT(lp)
belle_sip_channel_t *chan=belle_sip_channel_new_tls(lp->stack, ((belle_sip_tls_listening_point_t*) lp)->verify_ctx
,belle_sip_uri_get_host(lp->listening_uri)
,belle_sip_uri_get_port(lp->listening_uri)
,hop->cname
......@@ -72,35 +72,24 @@ belle_sip_listening_point_t * belle_sip_tls_listening_point_new(belle_sip_stack_
belle_sip_tls_listening_point_t *lp=belle_sip_object_new(belle_sip_tls_listening_point_t);
belle_sip_stream_listening_point_init((belle_sip_stream_listening_point_t*)lp,s,ipaddress,port,on_new_connection);
lp->verify_exceptions=0;
/*try to load "system" default root ca, wihtout warranty...*/
#ifdef __linux
belle_sip_tls_listening_point_set_root_ca(lp,"/etc/ssl/certs");
#elif defined(__APPLE__)
belle_sip_tls_listening_point_set_root_ca(lp,"/opt/local/share/curl/curl-ca-bundle.crt");
#endif
lp->verify_ctx=belle_tls_verify_policy_new();
return BELLE_SIP_LISTENING_POINT(lp);
}
int belle_sip_tls_listening_point_set_root_ca(belle_sip_tls_listening_point_t *lp, const char *path){
if (lp->root_ca){
belle_sip_free(lp->root_ca);
lp->root_ca=NULL;
}
if (path){
lp->root_ca=belle_sip_strdup(path);
belle_sip_message("Root ca path set to %s",lp->root_ca);
} else {
belle_sip_message("Root ca path disabled");
}
return 0;
return belle_tls_verify_policy_set_root_ca(lp->verify_ctx,path);
}
int belle_sip_tls_listening_point_set_verify_exceptions(belle_sip_tls_listening_point_t *lp, int flags){
lp->verify_exceptions=flags;
belle_tls_verify_policy_set_exceptions(lp->verify_ctx,flags);
return 0;
}
int belle_sip_tls_listening_point_set_verify_policy(belle_sip_tls_listening_point_t *s, belle_tls_verify_policy_t *pol){
SET_OBJECT_PROPERTY(s,verify_ctx,pol);
}
int belle_sip_tls_listening_point_available(void){
return TRUE;
}
......
......@@ -49,23 +49,31 @@ static void process_response(void *data, const belle_http_response_event_t *even
}
}
static void process_io_error(void *data, const belle_http_io_error_event_t *event){
static void process_io_error(void *data, const belle_sip_io_error_event_t *event){
http_counters_t *counters=(http_counters_t*)data;
counters->io_error_count++;
}
static void one_get(void){
static void process_auth_requested(void *data, belle_sip_auth_event_t *event){
}
static void one_get(int secure, const char *keyfile, const char *certfile){
belle_sip_stack_t *stack=belle_sip_stack_new(NULL);
belle_http_provider_t *prov=belle_sip_stack_create_http_provider(stack,"0.0.0.0");
belle_http_request_listener_callbacks_t cbs={0};
http_counters_t counters={0};
belle_http_request_listener_t *l;
belle_http_request_t *req=belle_http_request_create("GET",
belle_generic_uri_parse("http://smtp.linphone.org/"),
belle_generic_uri_t *uri=belle_generic_uri_parse("http://smtp.linphone.org/");
belle_http_request_t *req;
if (secure) belle_generic_uri_set_scheme(uri,"https");
req=belle_http_request_create("GET",
uri,
belle_sip_header_create("User-Agent","belle-sip/"PACKAGE_VERSION),
NULL);
cbs.process_response=process_response;
cbs.process_io_error=process_io_error;
cbs.process_auth_requested=process_auth_requested;
l=belle_http_request_listener_create_from_callbacks(&cbs,&counters);
belle_http_provider_send_request(prov,req,l);
wait_for(stack,&counters.response_count,1,3000);
......@@ -77,8 +85,17 @@ static void one_get(void){
belle_sip_object_unref(stack);
}
static void one_http_get(void){
one_get(FALSE,NULL,NULL);
}
static void one_https_get(void){
one_get(TRUE,NULL,NULL);
}
test_t http_tests[] = {
{ "One http GET", one_get },
{ "One http GET", one_http_get },
{ "One https GET", one_https_get },
};
test_suite_t http_test_suite = {
......
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