Commit 81f0dada authored by Simon Morlat's avatar Simon Morlat

Implement TLS support on top of polarssl.

parent 2e7d9876
Dependencies:
libantlr3c-3.4
antlr3-3.4
CUinit-2.x
*libantlr3c-3.4
*antlr3-3.4
Newer versions won't compile.
Optional:
*CUinit-2.x
*polarssl>=1.2
On windows you have to edit /usr/local/include/antl3defs.h
replace:
#include <winsock.h>
......@@ -16,6 +19,8 @@ Or get the source code from linphone's git (linphone branch):
git clone -b linphone git://git.linphone.org/antlr3.git
git clone -b linphone git://git.linphone.org/cunit.git
polarssl build system is Make (or Cmake). To build the shared library version, use "make SHARED=1 DEBUG=1", followed by "make install".
Prequisites
***********
You must jave 'java' in your PATH.
......
......@@ -64,8 +64,12 @@ AC_ARG_WITH( antlr,
[ antlr_prefix=${withval}],[ antlr_prefix=${prefix} ])
found_antlr3=no
ANTLR_CFLAGS="-I${antlr_prefix}/include"
ANTLR_LIBS="-L${antlr_prefix}/lib -lantlr3c"
if test "$antlr_prefix" != "/usr" ; then
ANTLR_CFLAGS="-I${antlr_prefix}/include"
ANTLR_LIBS="-L${antlr_prefix}/lib"
fi
ANTLR_LIBS="$ANTLR_LIBS -lantlr3c"
dnl check antlr headers
CPPFLAGS_save=$CPPFLAGS
......@@ -119,25 +123,44 @@ AC_ARG_ENABLE( tls,
*) AC_MSG_ERROR(bad value ${enableval} for --enable-tls) ;;
esac],[use_tls=true])
AC_ARG_WITH( polarssl,
[ --with-polarssl Set prefix where libantlr3c can be found (ex:/usr, /usr/local)[default=PREFIX] ],
[ polarssl_prefix=${withval}],[ polarssl_prefix=${prefix} ])
if test "$polarssl_prefix" != "/usr" ; then
POLARSSL_CFLAGS="-I${polarssl_prefix}/include"
POLARSSL_LIBS="-L${polarssl_prefix}/lib"
fi
POLARSSL_LIBS="$POLARSSL_LIBS -lpolarssl"
found_polarssl=no
if test "$use_tls" = "true" ; then
PKG_CHECK_MODULES(GNUTLS, gnutls, [found_gnutls=yes],
[AC_MSG_ERROR([Gnutls not found. You can use --disable-tls to turn tls support off.])] )
CPPFLAGS_save=$CPPFLAGS
LIBS_save=$LIBS
CPPFLAGS="$CPPFLAGS $POLARSSL_CFLAGS"
LIBS="$LIBS $POLARSSL_LIBS"
AC_CHECK_HEADERS(polarssl/ssl.h,
[
AC_CHECK_LIB(polarssl,x509parse_crtpath,[
found_polarssl=yes
POLARSSL_LIBS=" -lpolarssl"
])
])
CPPFLAGS=$CPPFLAGS_save
LIBS=$LIBS_save
fi
AM_CONDITIONAL([BUILD_TLS], [test "x$found_gnutls" = "xyes" || test "x$found_openssl" = "xyes"])
AM_CONDITIONAL([BUILD_TLS], [test "x$found_polarssl" = "xyes"])
TLS_CFLAGS=""
TLS_LIBS=""
TLS_PC=""
if test "x$found_gnutls" = "xyes" ; then
GNUTLS_LIBS+="$GNUTLS_LIBS -lgnutls "
AC_DEFINE(HAVE_GNUTLS,1,[Defined when gnutls api is available])
TLS_CFLAGS=$GNUTLS_CFLAGS
TLS_LIBS=$GNUTLS_LIBS
TLS_PC=gnutls
elif test "x$found_openssl" = "xyes" ; then
AC_DEFINE(HAVE_OPENSSL,1,[Defined when openssl api is available])
TLS_CFLAGS=$OPENSSL_CFLAGS
TLS_LIBS=$OPENSSL_LIBS
if test "x$found_polarssl" = "xyes" ; then
AC_DEFINE(HAVE_POLARSSL,1,[Defined when polarssl api is available])
TLS_CFLAGS=$POLARSSL_CFLAGS
TLS_LIBS=$POLARSSL_LIBS
fi
AC_SUBST(TLS_CFLAGS)
AC_SUBST(TLS_LIBS)
......
......@@ -126,6 +126,7 @@ BELLE_SIP_END_DECLS
/*these types are declared here because they are widely used in many headers included after*/
typedef struct belle_sip_listening_point belle_sip_listening_point_t;
typedef struct belle_sip_tls_listening_point belle_sip_tls_listening_point_t;
typedef struct belle_sip_stack belle_sip_stack_t;
typedef struct belle_sip_provider belle_sip_provider_t;
typedef struct belle_sip_dialog belle_sip_dialog_t;
......
......@@ -59,6 +59,18 @@ 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);
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)
int belle_sip_tls_listening_point_set_verify_exceptions(belle_sip_tls_listening_point_t *s, int flags);
#define BELLE_SIP_UDP_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_udp_listening_point_t)
#define BELLE_SIP_STREAM_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_stream_listening_point_t)
#define BELLE_SIP_TLS_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_tls_listening_point_t)
BELLE_SIP_END_DECLS
......
......@@ -133,6 +133,8 @@ BELLESIP_EXPORT void belle_sip_set_log_level(int level);
BELLESIP_EXPORT char * belle_sip_random_token(char *ret, size_t size);
unsigned char * belle_sip_random_bytes(unsigned char *ret, size_t size);
char * belle_sip_octets_to_text(const unsigned char *hash, size_t hash_len, char *ret, size_t size);
char * belle_sip_create_tag(char *ret, size_t size);
......
......@@ -58,12 +58,11 @@ libbellesip_la_SOURCES= \
transports/stream_channel.c \
transports/stream_channel.h \
transports/stream_listeningpoint.c \
transports/tls_listeningpoint.c \
transports/tls_listeningpoint_polarssl.c \
transports/tls_channel_polarssl.c \
refresher.c refresher-helper.h \
dns.c dns.h
if BUILD_TLS
libbellesip_la_SOURCES+=transports/tls_channel.c
endif
libbellesip_la_CFLAGS=$(STRICT_OPTIONS) $(ANTLR_CFLAGS) $(TLS_CFLAGS) $(LIBBELLESIP_CFLAGS)
......
......@@ -63,13 +63,13 @@ int belle_sip_auth_helper_compute_ha1(const char* userid,const char* realm,const
return -1;
}
md5_init(&state);
md5_append(&state,(const md5_byte_t *)userid,strlen(userid));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state,(const md5_byte_t *)realm,strlen(realm));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state,(const md5_byte_t *)password,strlen(password));
md5_finish(&state,out);
belle_sip_md5_init(&state);
belle_sip_md5_append(&state,(const md5_byte_t *)userid,strlen(userid));
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state,(const md5_byte_t *)realm,strlen(realm));
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state,(const md5_byte_t *)password,strlen(password));
belle_sip_md5_finish(&state,out);
for (di = 0; di < 16; ++di)
sprintf(ha1 + di * 2, "%02x", out[di]);
ha1[32]='\0';
......@@ -82,11 +82,11 @@ int belle_sip_auth_helper_compute_ha2(const char* method,const char* uri, char h
int di;
ha2[32]='\0';
/*HA2=MD5(method:uri)*/
md5_init(&state);
md5_append(&state,(const md5_byte_t *)method,strlen(method));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state,(const md5_byte_t *)uri,strlen(uri));
md5_finish(&state,out);
belle_sip_md5_init(&state);
belle_sip_md5_append(&state,(const md5_byte_t *)method,strlen(method));
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state,(const md5_byte_t *)uri,strlen(uri));
belle_sip_md5_finish(&state,out);
for (di = 0; di < 16; ++di)
sprintf(ha2 + di * 2, "%02x", out[di]);
return 0;
......@@ -97,15 +97,15 @@ int belle_sip_auth_helper_compute_response(const char* ha1,const char* nonce, co
int di;
response[32]='\0';
md5_init(&state);
md5_append(&state,(const md5_byte_t *)ha1,strlen(ha1));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
belle_sip_md5_init(&state);
belle_sip_md5_append(&state,(const md5_byte_t *)ha1,strlen(ha1));
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state
,(const md5_byte_t *)nonce
,strlen(nonce));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state,(const md5_byte_t *)ha2,strlen(ha2));
md5_finish(&state,out);
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state,(const md5_byte_t *)ha2,strlen(ha2));
belle_sip_md5_finish(&state,out);
/*copy values*/
for (di = 0; di < 16; ++di)
sprintf(response + di * 2, "%02x", out[di]);
......@@ -128,28 +128,28 @@ int belle_sip_auth_helper_compute_response_qop_auth(const char* ha1
snprintf(nounce_count_as_string,sizeof(nounce_count_as_string),"%08x",nonce_count);
/*response=MD5(HA1:nonce:nonce_count:cnonce:qop:HA2)*/
md5_init(&state);
md5_append(&state,(const md5_byte_t *)ha1,strlen(ha1));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
belle_sip_md5_init(&state);
belle_sip_md5_append(&state,(const md5_byte_t *)ha1,strlen(ha1));
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state
,(const md5_byte_t *)nonce
,strlen(nonce));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state
,(const md5_byte_t *)nounce_count_as_string
,strlen(nounce_count_as_string));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state
,(const md5_byte_t *)cnonce
,strlen(cnonce));
md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state
,(const md5_byte_t *)qop
,strlen(qop));
md5_append(&state,(const md5_byte_t *)":",1);
belle_sip_md5_append(&state,(const md5_byte_t *)":",1);
md5_append(&state,(const md5_byte_t *)ha2,strlen(ha2));
md5_finish(&state,out);
belle_sip_md5_append(&state,(const md5_byte_t *)ha2,strlen(ha2));
belle_sip_md5_finish(&state,out);
/*copy values*/
for (di = 0; di < 16; ++di)
sprintf(response + di * 2, "%02x", out[di]);
......
......@@ -457,6 +457,7 @@ void belle_sip_parameters_init(belle_sip_parameters_t *obj);
struct belle_sip_hop{
belle_sip_object_t base;
char *cname;
char *host;
char *transport;
int port;
......@@ -479,7 +480,7 @@ struct belle_sip_stack{
int resolver_send_error; /* used to simulate network error*/
};
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char* host,int port);
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port);
belle_sip_hop_t* belle_sip_hop_new_from_uri(const belle_sip_uri_t *uri);
belle_sip_hop_t * belle_sip_stack_get_next_hop(belle_sip_stack_t *stack, belle_sip_request_t *req);
......@@ -511,7 +512,7 @@ belle_sip_server_transaction_t * belle_sip_provider_find_matching_server_transac
belle_sip_request_t *req);
void belle_sip_provider_remove_server_transaction(belle_sip_provider_t *prov, belle_sip_server_transaction_t *t);
void belle_sip_provider_set_transaction_terminated(belle_sip_provider_t *p, belle_sip_transaction_t *t);
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const char *name, int port, const char *transport);
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const belle_sip_hop_t *hop);
void belle_sip_provider_add_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
void belle_sip_provider_remove_dialog(belle_sip_provider_t *prov, belle_sip_dialog_t *dialog);
void belle_sip_provider_release_channel(belle_sip_provider_t *p, belle_sip_channel_t *chan);
......
......@@ -188,6 +188,8 @@ void belle_sip_socket_source_init(belle_sip_source_t *s, belle_sip_source_func_t
belle_sip_source_init(s,func,data,sock,events,timeout_value_ms);
#endif
s->sock=sock;
if (sock!=(belle_sip_socket_t)-1)
belle_sip_socket_set_nonblocking(sock);
}
void belle_sip_fd_source_init(belle_sip_source_t *s, belle_sip_source_func_t func, void *data, belle_sip_fd_t fd, unsigned int events, unsigned int timeout_value_ms){
......
......@@ -582,9 +582,10 @@ static const char *symbols="aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
**/
char * belle_sip_random_token(char *ret, size_t size){
unsigned int val;
unsigned int i,j;
for(i=0,j=0;i<size-1;++i,++j){
if (j%5==0) val=belle_sip_random();
unsigned int i;
for(i=0;i<size-1;++i){
if (i%5==0) val=belle_sip_random();
ret[i]=symbols[val & 63];
val=val>>6;
}
......@@ -592,6 +593,20 @@ char * belle_sip_random_token(char *ret, size_t size){
return ret;
}
/**
* Write random bytes of supplied size.
**/
unsigned char * belle_sip_random_bytes(unsigned char *ret, size_t size){
unsigned int val;
unsigned int i;
for(i=0;i<size;++i){
if (i%4==0) val=belle_sip_random();
ret[i]=val & 0xff;
val=val>>8;
}
return ret;
}
typedef struct bits_reader{
const uint8_t *buffer;
size_t buf_size;
......
......@@ -54,6 +54,7 @@ static belle_sip_list_t * for_each_weak_unref_free(belle_sip_list_t *l, belle_si
static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
if (obj->peer) freeaddrinfo(obj->peer);
belle_sip_free(obj->peer_cname);
belle_sip_free(obj->peer_name);
if (obj->local_ip) belle_sip_free(obj->local_ip);
obj->listeners=for_each_weak_unref_free(obj->listeners,(belle_sip_object_destroy_notify_t)belle_sip_channel_remove_listener,obj);
......@@ -277,7 +278,8 @@ static void update_inactivity_timer(belle_sip_channel_t *obj){
}
}
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,const char *bindip,int localport,const char *peername, int peer_port){
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack,const char *bindip,int localport,const char *peer_cname, const char *peername, int peer_port){
obj->peer_cname=peer_cname ? belle_sip_strdup(peer_cname) : belle_sip_strdup(peername);
obj->peer_name=belle_sip_strdup(peername);
obj->peer_port=peer_port;
obj->stack=stack;
......@@ -299,7 +301,7 @@ void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_
ai.ai_addr=(struct sockaddr*)peer_addr;
ai.ai_addrlen=addrlen;
belle_sip_addrinfo_to_ip(&ai,remoteip,sizeof(remoteip),&peer_port);
belle_sip_channel_init(obj,stack,NULL,0,remoteip,peer_port);
belle_sip_channel_init(obj,stack,NULL,0,NULL,remoteip,peer_port);
obj->peer=belle_sip_ip_address_to_addrinfo(ai.ai_family, obj->peer_name,obj->peer_port);
}
......@@ -323,9 +325,12 @@ void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_chann
obj->listeners=belle_sip_list_remove(obj->listeners,l);
}
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const char *peername, int peerport, const struct addrinfo *addr){
if (peername && strcmp(peername,obj->peer_name)==0 && peerport==obj->peer_port)
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const belle_sip_hop_t *hop, const struct addrinfo *addr){
if (hop && strcmp(hop->host,obj->peer_name)==0 && hop->port==obj->peer_port){
if (hop->cname && obj->peer_cname && strcmp(hop->cname,obj->peer_cname)!=0)
return 0; /*cname mismatch*/
return 1;
}
if (addr && obj->peer)
return addr->ai_addrlen==obj->peer->ai_addrlen && memcmp(addr->ai_addr,obj->peer->ai_addr,addr->ai_addrlen)==0;
return 0;
......
......@@ -78,6 +78,7 @@ struct belle_sip_channel{
belle_sip_stack_t *stack;
belle_sip_channel_state_t state;
belle_sip_list_t *listeners;
char *peer_cname;
char *peer_name;
int peer_port;
char *local_ip;
......@@ -99,7 +100,7 @@ void belle_sip_channel_add_listener(belle_sip_channel_t *chan, belle_sip_channel
void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_channel_listener_t *l);
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const char *peername, int peerport, const struct addrinfo *addr);
int belle_sip_channel_matches(const belle_sip_channel_t *obj, const belle_sip_hop_t *hop, const struct addrinfo *addr);
void belle_sip_channel_resolve(belle_sip_channel_t *obj);
......@@ -117,7 +118,7 @@ int belle_sip_channel_send(belle_sip_channel_t *obj, const void *buf, size_t buf
int belle_sip_channel_recv(belle_sip_channel_t *obj, void *buf, size_t buflen);
/*only used by channels implementation*/
void belle_sip_channel_set_ready(belle_sip_channel_t *obj, const struct sockaddr *addr, socklen_t slen);
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const char *bindip,int localport,const char *peername, int peer_port);
void belle_sip_channel_init(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const char *bindip,int localport, const char *peer_cname, const char *peername, int peer_port);
void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const struct sockaddr *peer_addr, socklen_t addrlen);
void belle_sip_channel_set_socket(belle_sip_channel_t *obj, belle_sip_socket_t sock, belle_sip_source_func_t datafunc);
/*end of channel implementations*/
......
......@@ -45,8 +45,8 @@ void belle_sip_listening_point_add_channel(belle_sip_listening_point_t *lp, bell
lp->channels=belle_sip_list_append(lp->channels,chan);/*channel is already owned*/
}
belle_sip_channel_t *belle_sip_listening_point_create_channel(belle_sip_listening_point_t *obj, const char *dest, int port){
belle_sip_channel_t *chan=BELLE_SIP_OBJECT_VPTR(obj,belle_sip_listening_point_t)->create_channel(obj,dest,port);
belle_sip_channel_t *belle_sip_listening_point_create_channel(belle_sip_listening_point_t *obj, const belle_sip_hop_t *hop){
belle_sip_channel_t *chan=BELLE_SIP_OBJECT_VPTR(obj,belle_sip_listening_point_t)->create_channel(obj,hop);
if (chan){
chan->lp=obj;
belle_sip_listening_point_add_channel(obj,chan);
......@@ -114,29 +114,29 @@ int belle_sip_listening_point_get_well_known_port(const char *transport){
return -1;
}
belle_sip_channel_t *_belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp,const char *peer_name, int peer_port, const struct addrinfo *addr){
belle_sip_channel_t *_belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop, const struct addrinfo *addr){
belle_sip_list_t *elem;
belle_sip_channel_t *chan;
for(elem=lp->channels;elem!=NULL;elem=elem->next){
chan=(belle_sip_channel_t*)elem->data;
if (belle_sip_channel_matches(chan,peer_name,peer_port,addr)){
if (belle_sip_channel_matches(chan,hop,addr)){
return chan;
}
}
return NULL;
}
belle_sip_channel_t *belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp,const char *peer_name, int peer_port){
belle_sip_channel_t *belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp,const belle_sip_hop_t *hop){
struct addrinfo *res=NULL;
struct addrinfo hints={0};
char portstr[20];
belle_sip_channel_t *chan;
hints.ai_flags=AI_NUMERICHOST|AI_NUMERICSERV;
snprintf(portstr,sizeof(portstr),"%i",peer_port);
getaddrinfo(peer_name,portstr,&hints,&res);
chan=_belle_sip_listening_point_get_channel(lp,peer_name,peer_port,res);
snprintf(portstr,sizeof(portstr),"%i",hop->port);
getaddrinfo(hop->host,portstr,&hints,&res);
chan=_belle_sip_listening_point_get_channel(lp,hop,res);
if (res) freeaddrinfo(res);
return chan;
}
......@@ -211,6 +211,6 @@ int belle_sip_listening_point_get_keep_alive(const belle_sip_listening_point_t *
return lp->keep_alive_timer?belle_sip_source_get_timeout(lp->keep_alive_timer):-1;
}
void belle_sip_listener_set_channel_listener(belle_sip_listening_point_t *lp,belle_sip_channel_listener_t* channel_listener) {
void belle_sip_listening_point_set_channel_listener(belle_sip_listening_point_t *lp,belle_sip_channel_listener_t* channel_listener) {
lp->channel_listener=channel_listener;
}
......@@ -23,9 +23,13 @@
#include "gnutls/openssl.h"
#endif
#ifdef HAVE_POLARSSL
#include <polarssl/ssl.h>
#endif
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_listening_point_t,belle_sip_object_t)
const char *transport;
belle_sip_channel_t * (*create_channel)(belle_sip_listening_point_t *,const char *dest_ip, int port);
belle_sip_channel_t * (*create_channel)(belle_sip_listening_point_t *, const belle_sip_hop_t *hop);
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
......@@ -47,13 +51,13 @@ struct belle_sip_listening_point{
};
void belle_sip_listening_point_init(belle_sip_listening_point_t *lp, belle_sip_stack_t *s, const char *address, int port);
belle_sip_channel_t *_belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp,const char *peer_name, int peer_port, const struct addrinfo *addr);
belle_sip_channel_t *belle_sip_listening_point_create_channel(belle_sip_listening_point_t *ip,const char *dest, int port);
belle_sip_channel_t *_belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp,const belle_sip_hop_t *hop, const struct addrinfo *addr);
belle_sip_channel_t *belle_sip_listening_point_create_channel(belle_sip_listening_point_t *ip, const belle_sip_hop_t *hop);
void belle_sip_listening_point_remove_channel(belle_sip_listening_point_t *lp, belle_sip_channel_t *chan);
int belle_sip_listening_point_get_well_known_port(const char *transport);
belle_sip_channel_t *belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp,const char *peer_name, int peer_port);
belle_sip_channel_t *belle_sip_listening_point_get_channel(belle_sip_listening_point_t *lp, const belle_sip_hop_t *hop);
void belle_sip_listening_point_add_channel(belle_sip_listening_point_t *lp, belle_sip_channel_t *chan);
void belle_sip_listener_set_channel_listener(belle_sip_listening_point_t *lp,belle_sip_channel_listener_t* channel_listener);
void belle_sip_listening_point_set_channel_listener(belle_sip_listening_point_t *lp,belle_sip_channel_listener_t* channel_listener);
/**udp*/
typedef struct belle_sip_udp_listening_point belle_sip_udp_listening_point_t;
......@@ -62,14 +66,23 @@ belle_sip_channel_t * belle_sip_channel_new_udp_with_addr(belle_sip_stack_t *sta
belle_sip_listening_point_t * belle_sip_udp_listening_point_new(belle_sip_stack_t *s, const char *ipaddress, int port);
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_udp_listening_point_t,belle_sip_listening_point_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
#define BELLE_SIP_UDP_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_udp_listening_point_t)
/*stream*/
typedef struct belle_sip_stream_listening_point belle_sip_stream_listening_point_t;
struct belle_sip_stream_listening_point{
belle_sip_listening_point_t base;
belle_sip_socket_t server_sock;
belle_sip_source_t *source;
};
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_stream_listening_point_t,belle_sip_listening_point_t)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
#define BELLE_SIP_STREAM_LISTENING_POINT(obj) BELLE_SIP_CAST(obj,belle_sip_stream_listening_point_t)
void belle_sip_stream_listening_point_setup_server_socket(belle_sip_stream_listening_point_t *obj, belle_sip_source_func_t on_new_connection_cb );
void belle_sip_stream_listening_point_destroy_server_socket(belle_sip_stream_listening_point_t *lp);
void belle_sip_stream_listening_point_init(belle_sip_stream_listening_point_t *obj, belle_sip_stack_t *s, const char *ipaddress, int port, belle_sip_source_func_t on_new_connection_cb );
belle_sip_listening_point_t * belle_sip_stream_listening_point_new(belle_sip_stack_t *s, const char *ipaddress, int port);
/*tls*/
......@@ -77,17 +90,21 @@ belle_sip_listening_point_t * belle_sip_stream_listening_point_new(belle_sip_sta
typedef struct belle_sip_tls_listening_point belle_sip_tls_listening_point_t;
struct belle_sip_tls_listening_point{
belle_sip_listening_point_t base;
belle_sip_stream_listening_point_t base;
#ifdef HAVE_OPENSSL
SSL_CTX *ssl_context;
#endif
#ifdef HAVE_POLARSSL
x509_cert root_ca;
#endif
int verify_exceptions;
};
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(belle_sip_tls_listening_point_t,belle_sip_listening_point_t)
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 *name, 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);
#include "transports/stream_channel.h"
......
......@@ -310,7 +310,7 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
}
void
md5_init(md5_state_t *pms)
belle_sip_md5_init(md5_state_t *pms)
{
pms->count[0] = pms->count[1] = 0;
pms->abcd[0] = 0x67452301;
......@@ -320,7 +320,7 @@ md5_init(md5_state_t *pms)
}
void
md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
belle_sip_md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
{
const md5_byte_t *p = data;
int left = nbytes;
......@@ -358,7 +358,7 @@ md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
}
void
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
belle_sip_md5_finish(md5_state_t *pms, md5_byte_t digest[16])
{
static const md5_byte_t pad[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
......@@ -373,9 +373,9 @@ md5_finish(md5_state_t *pms, md5_byte_t digest[16])
for (i = 0; i < 8; ++i)
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
belle_sip_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
belle_sip_md5_append(pms, data, 8);
for (i = 0; i < 16; ++i)
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
}
......@@ -76,13 +76,13 @@ extern "C"
#endif
/* Initialize the algorithm. */
void md5_init(md5_state_t *pms);
void belle_sip_md5_init(md5_state_t *pms);
/* Append a string to the message. */
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
void belle_sip_md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
/* Finish the message and return the digest. */
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
void belle_sip_md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
#ifdef __cplusplus
} /* end extern "C" */
......
......@@ -556,7 +556,7 @@ belle_sip_hop_t* belle_sip_response_get_return_hop(belle_sip_response_t *msg){
belle_sip_header_via_t *via=BELLE_SIP_HEADER_VIA(belle_sip_message_get_header(BELLE_SIP_MESSAGE(msg),"via"));
const char *host=belle_sip_header_via_get_received(via) ? belle_sip_header_via_get_received(via) : belle_sip_header_via_get_host(via);
int port=belle_sip_header_via_get_rport(via)>0 ? belle_sip_header_via_get_rport(via) : belle_sip_header_via_get_listening_port(via);
return belle_sip_hop_new(belle_sip_header_via_get_transport_lowercase(via),host,port);
return belle_sip_hop_new(belle_sip_header_via_get_transport_lowercase(via),NULL,host,port);
}
int belle_sip_response_fix_contact(const belle_sip_response_t* response,belle_sip_header_contact_t* contact) {
......
......@@ -170,31 +170,31 @@ static void compute_hash_from_invariants(belle_sip_message_t *msg, char *branchi
requri=belle_sip_request_get_uri(BELLE_SIP_REQUEST(msg));
}
md5_init(&ctx);
belle_sip_md5_init(&ctx);
if (initial)
md5_append(&ctx,(uint8_t*)initial,strlen(initial));
belle_sip_md5_append(&ctx,(uint8_t*)initial,strlen(initial));
if (requri){
belle_sip_object_marshal((belle_sip_object_t*)requri,tmp,0,sizeof(tmp)-1);
md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
belle_sip_md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
}
if (from_tag)
md5_append(&ctx,(uint8_t*)from_tag,strlen(from_tag));
belle_sip_md5_append(&ctx,(uint8_t*)from_tag,strlen(from_tag));
if (to_tag)
md5_append(&ctx,(uint8_t*)to_tag,strlen(to_tag));
md5_append(&ctx,(uint8_t*)callid,strlen(callid));
md5_append(&ctx,(uint8_t*)&cseq,sizeof(cseq));
belle_sip_md5_append(&ctx,(uint8_t*)to_tag,strlen(to_tag));
belle_sip_md5_append(&ctx,(uint8_t*)callid,strlen(callid));
belle_sip_md5_append(&ctx,(uint8_t*)&cseq,sizeof(cseq));
if (is_request){
if (prev_via){
belle_sip_object_marshal((belle_sip_object_t*)prev_via,tmp,0,sizeof(tmp)-1);
md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
belle_sip_md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
}
}else{
if (via){
belle_sip_object_marshal((belle_sip_object_t*)via,tmp,0,sizeof(tmp)-1);
md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
belle_sip_md5_append(&ctx,(uint8_t*)tmp,strlen(tmp));
}
}
md5_finish(&ctx,digest);
belle_sip_md5_finish(&ctx,digest);
belle_sip_octets_to_text(digest,sizeof(digest),branchid,branchid_size);
}
......@@ -285,7 +285,7 @@ int belle_sip_provider_add_listening_point(belle_sip_provider_t *p, belle_sip_li
belle_sip_error("Cannot add NULL lp to provider [%p]",p);
return -1;
}
belle_sip_listener_set_channel_listener(lp,BELLE_SIP_CHANNEL_LISTENER(p));
belle_sip_listening_point_set_channel_listener(lp,BELLE_SIP_CHANNEL_LISTENER(p));
p->lps=belle_sip_list_append(p->lps,belle_sip_object_ref(lp));
return 0;
}
......@@ -458,24 +458,25 @@ belle_sip_stack_t *belle_sip_provider_get_sip_stack(belle_sip_provider_t *p){
return p->stack;
}
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const char *name, int port, const char *transport){
belle_sip_channel_t * belle_sip_provider_get_channel(belle_sip_provider_t *p, const belle_sip_hop_t *hop){
belle_sip_list_t *l;
belle_sip_listening_point_t *candidate=NULL,*lp;
belle_sip_channel_t *chan;
const char *transport=hop->transport;
if (transport==NULL) transport="UDP";
for(l=p->lps;l!=NULL;l=l->next){
lp=(belle_sip_listening_point_t*)l->data;
if (strcasecmp(belle_sip_listening_point_get_transport(lp),transport)==0){
chan=belle_sip_listening_point_get_channel(lp,name,port);
chan=belle_sip_listening_point_get_channel(lp,hop);
if (chan) return chan;
candidate=lp;
}
}
if (candidate){
chan=belle_sip_listening_point_create_channel(candidate,name,port);
if (!chan) belle_sip_error("Could not create channel to %s:%s:%i",transport,name,port);
chan=belle_sip_listening_point_create_channel(candidate,hop);
if (!chan) belle_sip_error("Could not create channel to %s://%s:%i",transport,hop->host,hop->port);
return chan;
}
belle_sip_error("No listening point matching for transport %s",transport);
......@@ -500,7 +501,7 @@ void belle_sip_provider_send_request(belle_sip_provider_t *p, belle_sip_request_
belle_sip_hop_t* hop;
belle_sip_channel_t *chan;
hop=belle_sip_stack_get_next_hop(p->stack,req);
chan=belle_sip_provider_get_channel(p,hop->host, hop->port, hop->transport);
chan=belle_sip_provider_get_channel(p,hop);
if (chan) {
belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(req));
}
......@@ -517,7 +518,7 @@ void belle_sip_provider_send_response(belle_sip_provider_t *p, belle_sip_respons
belle_sip_header_to_set_tag(to,token);
}
hop=belle_sip_response_get_return_hop(resp);
chan=belle_sip_provider_get_channel(p,hop->host, hop->port, hop->transport);
chan=belle_sip_provider_get_channel(p,hop);
if (chan) belle_sip_channel_queue_message(chan,BELLE_SIP_MESSAGE(resp));
belle_sip_object_unref(hop);
}
......
......@@ -20,19 +20,23 @@
#include "listeningpoint_internal.h"
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char* host,int port) {
belle_sip_hop_t* belle_sip_hop_new(const char* transport, const char *cname, const char* host,int port) {
belle_sip_hop_t* hop = belle_sip_object_new(belle_sip_hop_t);
if (transport) hop->transport=belle_sip_strdup(transport);
if (host) hop->host=belle_sip_strdup(host);
if (cname) hop->cname=belle_sip_strdup(cname);
hop->port=port;
return hop;