Commit 1444b552 authored by jehan's avatar jehan

add support for multicast address in connection

parent 2f322659
......@@ -103,6 +103,21 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth( const char*
/*TLS client certificate auth*/
/**
* Set TLS certificate verification callback
*
* @param callback function pointer for callback, or NULL to unset
*
* Callback signature is:
* int (*verify_cb_error_cb_t)(unsigned char* der, int length, int depth, int* flags);
* der - raw certificate data, in DER format
* length - length of certificate DER data
* depth - position of certificate in cert chain, ending at 0 = root or top
* flags - verification state for CURRENT certificate only
*/
BELLESIP_EXPORT int belle_sip_tls_set_verify_error_cb(void *callback);
/**
* Format of certificate buffer
**/
......
......@@ -123,9 +123,13 @@ BELLESIP_EXPORT belle_sdp_connection_t* belle_sdp_connection_parse (const char*
BELLESIP_EXPORT const char* belle_sdp_connection_get_address(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT const char* belle_sdp_connection_get_address_type(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT const char* belle_sdp_connection_get_network_type(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT int belle_sdp_connection_get_ttl(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT int belle_sdp_connection_get_range(const belle_sdp_connection_t* connection);
BELLESIP_EXPORT void belle_sdp_connection_set_address(belle_sdp_connection_t* connection, const char* addr);
BELLESIP_EXPORT void belle_sdp_connection_set_address_type(belle_sdp_connection_t* connection, const char* type);
BELLESIP_EXPORT void belle_sdp_connection_set_network_type(belle_sdp_connection_t* connection, const char* type);
BELLESIP_EXPORT void belle_sdp_connection_set_ttl(belle_sdp_connection_t* connection,int ttl);
BELLESIP_EXPORT void belle_sdp_connection_set_range(belle_sdp_connection_t* connection,int range);
#define BELLE_SDP_CONNECTION(t) BELLE_SDP_CAST(t,belle_sdp_connection_t)
/***************************************************************************************
* Email
......
......@@ -230,6 +230,42 @@ operator<<( std::ostream& __os, const belle_sip_uri_t* uri)
belle_sip_free(uri_as_string);
return __os;
}
template <> struct std::hash<const belle_sip_uri_t*> {
size_t operator()(const belle_sip_uri_t *x ) const {
std::hash<string> H;
size_t h=0;
if (belle_sip_uri_get_user(x))
h = H(belle_sip_uri_get_user(x));
if (belle_sip_uri_get_host(x))
h ^=H(belle_sip_uri_get_host(x));
if (belle_sip_uri_get_port(x)>0) {
std::hash<int> H2;
h ^=H2(belle_sip_uri_get_port(x));
}
if (belle_sip_uri_get_transport_param(x)) {
h ^=H(belle_sip_uri_get_transport_param(x));
}
if (belle_sip_uri_is_secure(x))
h+=1;
return h;
}
};
#include <functional>
namespace bellesip {
struct UriComparator : public std::binary_function<belle_sip_uri_t*, belle_sip_uri_t*, bool> {
bool operator()(const belle_sip_uri_t* lhs, const belle_sip_uri_t* rhs) const {
return belle_sip_uri_equals(lhs,rhs);
}
};
}
#endif
#endif /*BELLE_SIP_URI_H_*/
......
......@@ -370,6 +370,8 @@ struct _belle_sdp_connection {
const char* network_type;
const char* address_type;
const char* address;
int ttl;
int range;
};
void belle_sdp_connection_destroy(belle_sdp_connection_t* connection) {
......@@ -382,11 +384,19 @@ void belle_sdp_connection_clone(belle_sdp_connection_t *connection, const belle_
CLONE_STRING(belle_sdp_connection,network_type,connection,orig)
CLONE_STRING(belle_sdp_connection,address_type,connection,orig)
CLONE_STRING(belle_sdp_connection,address,connection,orig)
connection->range=orig->range;
connection->ttl=orig->ttl;
}
belle_sip_error_code belle_sdp_connection_marshal(belle_sdp_connection_t* connection, char* buff, size_t buff_size, size_t *offset) {
return belle_sip_snprintf(buff,buff_size,offset,"c=%s %s %s",connection->network_type,connection->address_type,connection->address);
belle_sip_error_code error = belle_sip_snprintf(buff,buff_size,offset,"c=%s %s %s",connection->network_type,connection->address_type,connection->address);
if (error!=BELLE_SIP_OK) return error;
if (connection->ttl>0)
error = belle_sip_snprintf(buff,buff_size,offset,"/%i",connection->ttl);
if (error!=BELLE_SIP_OK) return error;
if (connection->range>0)
error = belle_sip_snprintf(buff,buff_size,offset,"/%i",connection->range);
return error;
}
BELLE_SDP_NEW(connection,belle_sip_object)
......@@ -401,6 +411,8 @@ belle_sdp_connection_t* belle_sdp_connection_create(const char* net_type, const
GET_SET_STRING(belle_sdp_connection,network_type);
GET_SET_STRING(belle_sdp_connection,address_type);
GET_SET_STRING(belle_sdp_connection,address);
GET_SET_INT(belle_sdp_connection,ttl,int);
GET_SET_INT(belle_sdp_connection,range,int);
/************************
* email
***********************/
......
......@@ -173,7 +173,7 @@ scope { belle_sdp_connection_t* current; }
@init {$connection::current = belle_sdp_connection_new(); $ret=$connection::current; }
: {IS_TOKEN(c)}?alpha_num EQUAL nettype { belle_sdp_connection_set_network_type($connection::current,(const char*)$nettype.text->chars);}
SPACE addrtype{ belle_sdp_connection_set_address_type($connection::current,(const char*)$addrtype.text->chars);}
SPACE connection_address {belle_sdp_connection_set_address($connection::current,(const char*)$connection_address.text->chars);}
SPACE connection_address
;
//;a connection field must be present
//;in every media description or at the
......@@ -458,7 +458,7 @@ sess_version: DIGIT+;
connection_address:
/*multicast_address
|*/addr;
|*/addr {belle_sdp_connection_set_address($connection::current,(const char*)$addr.text->chars);} multicast_part?;
multicast_address: unicast_address '/' ttl;
// (decimal_uchar DOT decimal_uchar DOT decimal_uchar DOT) decimal_uchar '/' ttl ( '/' integer )?;
......@@ -511,7 +511,15 @@ addrtype: alpha_num+ ; //'IP4' | 'IP6';
//;list to be extended
addr: unicast_address ;
multicast_part: (SLASH num+=integer {
if (strcmp( belle_sdp_connection_get_address_type($connection::current),"IP6")==0)
belle_sdp_connection_set_range($connection::current,atoi((const char*)$integer.text->chars));
else if ($num->count ==1)
belle_sdp_connection_set_ttl($connection::current,atoi((const char*)$integer.text->chars));
else if ($num->count ==2)
belle_sdp_connection_set_range($connection::current,atoi((const char*)$integer.text->chars));
})+;
fqdn : ( domainlabel DOT )* toplabel DOT? ;
......
......@@ -92,6 +92,13 @@ char *belle_sip_signing_key_get_pem(belle_sip_signing_key_t *key) {
#endif /* POLARSSL_VERSION_NUMBER >= 0x01030000 */
/*************tls********/
// SSL verification callback prototype
// der - raw certificate data, in DER format
// length - length of certificate DER data
// depth - position of certificate in cert chain, ending at 0 = root or top
// flags - verification state for CURRENT certificate only
typedef int (*verify_cb_error_cb_t)(unsigned char* der, int length, int depth, int* flags);
static verify_cb_error_cb_t tls_verify_cb_error_cb = NULL;
static int tls_process_data(belle_sip_channel_t *obj,unsigned int revents);
......@@ -351,6 +358,68 @@ static const char *polarssl_certflags_to_string(char *buf, size_t size, int flag
return buf;
}
// shim the default PolarSSL certificate handling by adding an external callback
// see "verify_cb_error_cb_t" for the function signature
int belle_sip_tls_set_verify_error_cb(void * callback)
{
if (callback) {
tls_verify_cb_error_cb = (verify_cb_error_cb_t)callback;
belle_sip_message("belle_sip_tls_set_verify_error_cb: callback set");
} else {
tls_verify_cb_error_cb = NULL;
belle_sip_message("belle_sip_tls_set_verify_error_cb: callback cleared");
}
return 0;
}
//
// Augment certificate verification with certificates stored outside rootca.pem
// PolarSSL calls the verify_cb with each cert in the chain; flags apply to the
// current certificate until depth is 0;
//
// NOTES:
// 1) rootca.pem *must* have at least one valid certificate, or PolarSSL
// does not attempt to verify any certificates
// 2) callback must return 0; non-zero indicates that the verification process failed
// 3) flags should be saved off and cleared for each certificate where depth>0
// 4) return final verification result in *flags when depth == 0
// 5) callback must disable calls to linphone_core_iterate while running
//
#if POLARSSL_VERSION_NUMBER < 0x01030000
int belle_sip_verify_cb_error_wrapper(x509_cert *cert, int depth, int *flags){
#else
int belle_sip_verify_cb_error_wrapper(x509_crt *cert, int depth, int *flags){
#endif
int rc = 0;
unsigned char *der = NULL;
// do nothing if the callback is not set
if (!tls_verify_cb_error_cb) {
return 0;
}
belle_sip_message("belle_sip_verify_cb_error_wrapper: depth=[%d], flags=[%d]:\n", depth, *flags);
der = belle_sip_malloc(cert->raw.len + 1);
if (der == NULL) {
// leave the flags alone and just return to the library
belle_sip_error("belle_sip_verify_cb_error_wrapper: memory error\n");
return 0;
}
// copy in and NULL terminate again for safety
memcpy(der, cert->raw.p, cert->raw.len);
der[cert->raw.len] = '\0';
rc = tls_verify_cb_error_cb(der, cert->raw.len, depth, flags);
belle_sip_message("belle_sip_verify_cb_error_wrapper: callback return rc: %d, flags: %d", rc, *flags);
belle_sip_free(der);
return rc;
}
#if POLARSSL_VERSION_NUMBER < 0x01030000
static int belle_sip_ssl_verify(void *data , x509_cert *cert , int depth, int *flags){
#else
......@@ -372,7 +441,8 @@ static int belle_sip_ssl_verify(void *data , x509_crt *cert , int depth, int *fl
}else if (verify_ctx->exception_flags & BELLE_TLS_VERIFY_CN_MISMATCH){
*flags&=~BADCERT_CN_MISMATCH;
}
return 0;
return belle_sip_verify_cb_error_wrapper(cert, depth, flags);
}
static int belle_sip_tls_channel_load_root_ca(belle_sip_tls_channel_t *obj, const char *path){
......
......@@ -197,6 +197,8 @@ static void test_connection(void) {
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address(lConnection), "192.168.0.18");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address_type(lConnection), "IP4");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_network_type(lConnection), "IN");
CU_ASSERT_EQUAL(belle_sdp_connection_get_ttl(lConnection), 0);
CU_ASSERT_EQUAL(belle_sdp_connection_get_ttl(lConnection), 0);
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
belle_sip_free(l_raw_connection);
}
......@@ -216,6 +218,53 @@ static void test_connection_6(void) {
belle_sip_free(l_raw_connection);
}
static void test_connection_multicast(void) {
belle_sdp_connection_t* lTmp;
belle_sdp_connection_t* lConnection = belle_sdp_connection_parse("c=IN IP4 224.2.1.1/127/3");
char* l_raw_connection = belle_sip_object_to_string(BELLE_SIP_OBJECT(lConnection));
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
lTmp = belle_sdp_connection_parse(l_raw_connection);
lConnection = BELLE_SDP_CONNECTION(belle_sip_object_clone(BELLE_SIP_OBJECT(lTmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(lTmp));
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address(lConnection), "224.2.1.1");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address_type(lConnection), "IP4");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_network_type(lConnection), "IN");
CU_ASSERT_EQUAL(belle_sdp_connection_get_ttl(lConnection), 127);
CU_ASSERT_EQUAL(belle_sdp_connection_get_range(lConnection), 3);
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
belle_sip_free(l_raw_connection);
lConnection = belle_sdp_connection_parse("c=IN IP4 224.2.1.1/127");
l_raw_connection = belle_sip_object_to_string(BELLE_SIP_OBJECT(lConnection));
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
lTmp = belle_sdp_connection_parse(l_raw_connection);
lConnection = BELLE_SDP_CONNECTION(belle_sip_object_clone(BELLE_SIP_OBJECT(lTmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(lTmp));
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address(lConnection), "224.2.1.1");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address_type(lConnection), "IP4");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_network_type(lConnection), "IN");
CU_ASSERT_EQUAL(belle_sdp_connection_get_ttl(lConnection), 127);
CU_ASSERT_EQUAL(belle_sdp_connection_get_range(lConnection), 0);
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
belle_sip_free(l_raw_connection);
lConnection = belle_sdp_connection_parse("c=IN IP6 ::1/3");
l_raw_connection = belle_sip_object_to_string(BELLE_SIP_OBJECT(lConnection));
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
lTmp = belle_sdp_connection_parse(l_raw_connection);
lConnection = BELLE_SDP_CONNECTION(belle_sip_object_clone(BELLE_SIP_OBJECT(lTmp)));
belle_sip_object_unref(BELLE_SIP_OBJECT(lTmp));
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address(lConnection), "::1");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_address_type(lConnection), "IP6");
CU_ASSERT_STRING_EQUAL(belle_sdp_connection_get_network_type(lConnection), "IN");
CU_ASSERT_EQUAL(belle_sdp_connection_get_ttl(lConnection), 0);
CU_ASSERT_EQUAL(belle_sdp_connection_get_range(lConnection), 3);
belle_sip_object_unref(BELLE_SIP_OBJECT(lConnection));
belle_sip_free(l_raw_connection);
}
static void test_email(void) {
belle_sdp_email_t* lTmp;
belle_sdp_email_t* l_email = belle_sdp_email_parse("e= jehan <jehan@linphone.org>");
......@@ -636,6 +685,7 @@ test_t sdp_tests[] = {
{ "o= (malformed origin)", test_malformed_origin },
{ "c= (IPv4 connection)", test_connection },
{ "c= (IPv6 connection)", test_connection_6 },
{ "c= (multicast)", test_connection_multicast},
{ "e= (email)", test_email },
{ "i= (info)", test_info },
{ "m= (media)", test_media },
......
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