Commit 006ba8be authored by Guillaume BIENKOWSKI's avatar Guillaume BIENKOWSKI

Progress commit: basic object structure is here

parent 9d41c890
......@@ -161,6 +161,24 @@ AC_ARG_ENABLE(x11,
[enable_x11=true]
)
dnl conditional build of LDAP support
AC_ARG_ENABLE(ldap,
[AS_HELP_STRING([--disable-ldap], [Disable LDAP support (default=no)])],
[case "${enableval}" in
yes) enable_ldap=true ;;
no) enable_ldap=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --disable-ldap) ;;
esac],
[enable_ldap=true]
)
AM_CONDITIONAL(BUILD_LDAP, test x$enable_ldap != xfalse)
if test "$enable_ldap" = "true"; then
AC_CHECK_LIB(ldap,ldap_initialize, LDAP_LIBS="-lldap")
AC_SUBST(LDAP_LIBS)
AC_DEFINE(BUILD_LDAP,1,[Defined if LDAP build option enabled])
fi
dnl conditionnal build of console interface.
AC_ARG_ENABLE(console_ui,
[AS_HELP_STRING([--enable-console_ui=[yes/no]], [Turn on or off compilation of console interface (default=yes)])],
......@@ -854,6 +872,7 @@ printf "* %-30s %s\n" "Tools" $build_tools
printf "* %-30s %s\n" "Message storage" $enable_msg_storage
printf "* %-30s %s\n" "zRTP encryption (GPLv3)" $zrtp
printf "* %-30s %s\n" "uPnP support" $build_upnp
printf "* %-30s %s\n" "LDAP support" $enable_ldap
if test "$enable_tunnel" = "true" ; then
printf "* %-30s %s\n" "Tunnel support" "true"
......
......@@ -48,11 +48,16 @@ liblinphone_la_SOURCES=\
message_storage.c \
info.c \
event.c event.h \
contactprovider.c contactprovider.h \
$(GITVERSION_FILE)
if BUILD_UPNP
liblinphone_la_SOURCES+=upnp.c upnp.h
endif
if BUILD_LDAP
liblinphone_la_SOURCES+= ldap/ldapprovider.c ldap/ldapprovider.h
endif
liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
bellesip_sal/sal_impl.c bellesip_sal/sal_impl.h \
......@@ -89,7 +94,8 @@ liblinphone_la_LIBADD= \
$(TUNNEL_LIBS) \
$(LIBSOUP_LIBS) \
$(SQLITE3_LIBS) \
$(LIBXML2_LIBS)
$(LIBXML2_LIBS) \
$(LDAP_LIBS)
if ENABLE_TESTS
......
......@@ -15,23 +15,85 @@
*/
#include "contactprovider.h"
#include <linphonecore.h>
struct linphone_contact_provider {
belle_sip_object_t base;
};
/* LinphoneContactSearchRequest
*/
linphone_contact_provider_t* linphone_contact_provider_create()
void linphone_contact_search_init(LinphoneContactSearch* obj,
const char* predicate,
ContactSearchCallback cb,
void* cb_data)
{
linphone_contact_provider_t* obj = belle_sip_object_new(linphone_contact_provider_t);
return obj;
static unsigned int request_id_counter = 1;
obj->id = request_id_counter++; // unique id
obj->predicate = ms_strdup(predicate?predicate:"");
obj->cb = cb;
obj->data = cb_data;
}
static void linphone_contact_search_destroy( LinphoneContactSearch* req) {
if( req->predicate ) ms_free(req->predicate);
ms_free(req);
}
static void linphone_contact_provider_destroy()
ContactSearchID linphone_contact_search_get_id(LinphoneContactSearch* obj)
{
return obj->id;
}
const char*linphone_contact_search_get_predicate(LinphoneContactSearch* obj)
{
return obj->predicate;
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(linphone_contact_provider_t);
BELLE_SIP_INSTANCIATE_VPTR(linphone_contact_provider_t, belle_sip_object_t,
linphone_contact_provider_destroy, NULL, NULL,FALSE);
void linphone_contact_search_invoke_cb(LinphoneContactSearch* req, MSList* friends)
{
if( req->cb ) req->cb(req->id, friends, req->data);
}
int linphone_contact_search_compare(const void* a, const void* b) {
LinphoneContactSearch *ra=((LinphoneContactSearch*)a);
LinphoneContactSearch *rb=((LinphoneContactSearch*)b);
return !(ra->id == rb->id); // return 0 if id is equal, 1 otherwise
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContactSearch);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneContactSearch,belle_sip_object_t,
(belle_sip_object_destroy_t)linphone_contact_search_destroy,
NULL, // clone
NULL, // marshal
FALSE
);
/*
* LinphoneContactProvider
*/
void linphone_contact_provider_init(LinphoneContactProvider* obj, LinphoneCore* lc){
obj->lc = lc;
}
static void contact_provider_destroy(LinphoneContactProvider* obj){
(void)obj;
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneContactProvider);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(LinphoneContactProvider)=
{
{
BELLE_SIP_VPTR_INIT(LinphoneContactProvider,belle_sip_object_t,TRUE),
(belle_sip_object_destroy_t) contact_provider_destroy,
NULL,/*no clone*/
NULL,/*no marshal*/
},
"",
// Pure virtual
NULL, /* begin_search -> pure virtual */
NULL /* cancel_search -> pure virtual */
};
......@@ -17,10 +17,50 @@
#include <belle-sip/object.h>
#include "linphonecore.h"
/* LinphoneContactSearchRequest */
typedef struct linphone_contact_provider linphone_contact_provider_t;
#define LINPHONE_CONTACT_PROVIDER(obj) BELLE_SIP_CAST(obj,linphone_contact_provider_t)
typedef unsigned int ContactSearchID;
typedef void (*ContactSearchCallback)( ContactSearchID id, MSList* friends, void* data );
typedef struct {
ContactSearchID id;
char* predicate;
ContactSearchCallback cb;
void* data;
} LinphoneContactSearch;
linphone_contact_provider_t* linphone_contact_provider_create();
#define LINPHONE_CONTACT_SEARCH(obj) BELLE_SIP_CAST(obj,LinphoneContactSearch)
BELLE_SIP_DECLARE_VPTR(LinphoneContactSearch)
void linphone_contact_search_init(LinphoneContactSearch* obj, const char* predicate, ContactSearchCallback cb, void* cb_data);
ContactSearchID linphone_contact_search_get_id(LinphoneContactSearch* obj);
const char* linphone_contact_search_get_predicate(LinphoneContactSearch* obj);
void linphone_contact_search_invoke_cb(LinphoneContactSearch* req, MSList* friends);
/* LinphoneContactProvider */
struct _LinphoneContactProvider {
belle_sip_object_t base;
LinphoneCore* lc;
};
typedef struct _LinphoneContactProvider LinphoneContactProvider;
typedef LinphoneContactSearch* (*LinphoneContactProviderStartSearchMethod)( LinphoneContactProvider* thiz, const char* predicate, ContactSearchCallback cb, void* data );
typedef unsigned int (*LinphoneContactProviderCancelSearchMethod)( LinphoneContactProvider* thiz, LinphoneContactSearch *request );
#define LINPHONE_CONTACT_PROVIDER(obj) BELLE_SIP_CAST(obj,LinphoneContactProvider)
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(LinphoneContactProvider,belle_sip_object_t)
const char* name; /*!< Name of the contact provider (LDAP, Google, ...) */
/* pure virtual methods: inheriting objects must implement these */
LinphoneContactProviderStartSearchMethod begin_search;
LinphoneContactProviderCancelSearchMethod cancel_search;
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
void linphone_contact_provider_init(LinphoneContactProvider* obj, LinphoneCore* lc);
LinphoneCore* linphone_contact_provider_get_core(LinphoneContactProvider* obj);
const char* linphone_contact_provider_get_name(LinphoneContactProvider* obj);
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "ldapprovider.h"
#include "linphonecore_utils.h"
#include "lpconfig.h"
#include <ldap.h>
struct _LinphoneLDAPContactSearch
{
LDAP *ld;
int msgid;
char* filter;
};
#define MAX_RUNNING_REQUESTS 10
#define FILTER_MAX_SIZE 512
typedef struct {
int msgid;
LinphoneLDAPContactSearch* request;
} LDAPRequestEntry;
struct _LinphoneLDAPContactProvider
{
LDAP* ld;
//LDAPRequestEntry requests[MAX_RUNNING_REQUESTS];
MSList* requests;
int req_count;
// config
int use_tls;
char* auth_method;
char* username;
char* password;
char* base_object;
char** attributes;
char* filter;
int timeout;
int deref_aliases;
int max_results;
};
/* *************************
* LinphoneLDAPContactSearch
* *************************/
LinphoneLDAPContactSearch*linphone_ldap_contact_search_create(LinphoneLDAPContactProvider* cp, const char* predicate, ContactSearchCallback cb, void* cb_data)
{
LinphoneLDAPContactSearch* search = belle_sip_object_new(LinphoneLDAPContactSearch);
LinphoneContactSearch* base = LINPHONE_CONTACT_SEARCH(search);
linphone_contact_search_init(base, predicate, cb, cb_data);
search->ld = cp->ld;
search->filter = ms_malloc(FILTER_MAX_SIZE);
snprintf(search->filter, FILTER_MAX_SIZE-1, cp->filter, predicate);
search->filter[FILTER_MAX_SIZE-1] = 0;
struct timeval timeout = { cp->timeout, 0 };
ldap_search_ext(search->ld, cp->base_object, LDAP_SCOPE_SUBTREE, search->filter,
cp->attributes, 0, NULL, NULL, &timeout, cp->max_results, &search->msgid );
return search;
}
static void linphone_ldap_contact_destroy( LinphoneLDAPContactSearch* obj )
{
(void)obj;
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLDAPContactSearch);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneLDAPContactSearch,LinphoneContactSearch,
(belle_sip_object_destroy_t)linphone_ldap_contact_destroy,
NULL,
NULL,
TRUE
);
/* ***************************
* LinphoneLDAPContactProvider
* ***************************/
static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvider* obj )
{
if(obj->auth_method) ms_free(obj->auth_method);
if(obj->username) ms_free(obj->username);
if(obj->password) ms_free(obj->password);
if(obj->base_object) ms_free(obj->base_object);
if(obj->attributes){
int i=0;
for( ; obj->attributes[i]; i++){
ms_free(obj->attributes[i]);
}
ms_free(obj->attributes);
}
}
static void linphone_ldap_contact_provider_destroy( LinphoneLDAPContactProvider* obj )
{
if (obj->ld) ldap_unbind_ext(obj->ld, NULL, NULL);
obj->ld = NULL;
linphone_ldap_contact_provider_conf_destroy(obj);
}
static LinphoneLDAPContactSearch* linphone_ldap_begin_search(LinphoneLDAPContactProvider* obj,
const char* predicate,
ContactSearchCallback cb,
void* cb_data)
{
LDAPRequestEntry* entry = ms_new0(LDAPRequestEntry,1);
if( entry){
LinphoneLDAPContactSearch* request = linphone_ldap_contact_search_create(obj, predicate, cb, cb_data);
entry->msgid = request->msgid;
entry->request = request;
obj->requests = ms_list_append(obj->requests, entry);
obj->req_count++;
return request;
} else {
return NULL;
}
}
static int linphone_ldap_request_entry_compare(const void*a, const void* b)
{
const LDAPRequestEntry* ra = (const LDAPRequestEntry*)a;
const LDAPRequestEntry* rb = (const LDAPRequestEntry*)b;
return !(ra->msgid == rb->msgid);
}
static unsigned int linphone_ldap_cancel_search(LinphoneContactProvider* obj, LinphoneContactSearch *req)
{
LinphoneLDAPContactSearch* ldap_req = LINPHONE_LDAP_CONTACT_SEARCH(req);
LinphoneLDAPContactProvider* ldap_cp = LINPHONE_LDAP_CONTACT_PROVIDER(obj);
LDAPRequestEntry dummy = { ldap_req->msgid, ldap_req };
int ret = 1;
MSList* list_entry = ms_list_find_custom(ldap_cp->requests, linphone_ldap_request_entry_compare, &dummy);
if( list_entry ) {
ldap_cp->requests = ms_list_remove(ldap_cp->requests, list_entry);
ldap_cp->req_count--;
ms_free(list_entry);
ret = 0; // return OK if we found it in the monitored requests
} else {
ms_warning("Couldn't find ldap request %p (id %d) in monitoring.", ldap_req, ldap_req->msgid);
}
belle_sip_object_unref(req);
return ret;
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLDAPContactProvider);
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR(LinphoneLDAPContactProvider)=
{
{
{
BELLE_SIP_VPTR_INIT(LinphoneLDAPContactProvider,LinphoneContactProvider,TRUE),
(belle_sip_object_destroy_t)linphone_ldap_contact_provider_destroy,
NULL,
NULL
},
"LDAP",
(LinphoneContactProviderStartSearchMethod)linphone_ldap_begin_search,
(LinphoneContactProviderCancelSearchMethod)linphone_ldap_cancel_search
}
};
static bool_t linphone_ldap_contact_provider_iterate(void *data)
{
LinphoneLDAPContactProvider* obj = LINPHONE_LDAP_CONTACT_PROVIDER(data);
if( obj->ld && (obj->req_count >= 0) ){
int wait_for_all_results = 1;
// never block
struct timeval timeout = {0,0};
LDAPMessage* results = NULL;
int res = ldap_result(obj->ld, LDAP_RES_ANY, wait_for_all_results, &timeout, &results);
switch( res ){
case -1:
{
ms_warning("Error in ldap_result : returned -1");
break;
}
case 0: break; // nothing to do
case LDAP_RES_BIND:
case LDAP_RES_SEARCH_ENTRY:
case LDAP_RES_SEARCH_REFERENCE:
case LDAP_RES_SEARCH_RESULT:
case LDAP_RES_MODIFY:
case LDAP_RES_ADD:
case LDAP_RES_DELETE:
case LDAP_RES_MODDN:
case LDAP_RES_COMPARE:
case LDAP_RES_EXTENDED:
case LDAP_RES_INTERMEDIATE:
{
ms_message("Got LDAP result type %x", res);
ldap_msgfree(results);
break;
}
default:
ms_message("Unhandled LDAP result %x", res);
break;
}
}
return TRUE;
}
static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvider* obj, LpConfig* config)
{
const char* section="ldap";
char* attributes_list, *saveptr, *attr;
unsigned int attr_count = 0, attr_idx = 0, i;
obj->use_tls = lp_config_get_int(config, section, "use_tls", 0);
obj->timeout = lp_config_get_int(config, section, "timeout", 10);
obj->deref_aliases = lp_config_get_int(config, section, "deref_aliases", 0);
obj->max_results = lp_config_get_int(config, section, "max_results", 50);
// free any pre-existing char* conf values
linphone_ldap_contact_provider_conf_destroy(obj);
// parse the attributes list
attributes_list = ms_strdup(lp_config_get_string(config, section, "attributes", "telephoneNumber,givenName,sn"));
// count attributes:
for( i=0; attributes_list[i]; i++)
{
if( attributes_list[i] == ',') attr_count++;
}
obj->attributes = ms_malloc0((attr_count+2) * sizeof(char*));
attr = strtok_r( attributes_list, ",", &saveptr );
while( attr != NULL ){
obj->attributes[attr_idx] = ms_strdup(attr);
attr_idx++;
attr = strtok_r(NULL, ",", &saveptr);
}
if( attr_idx == attr_count)
obj->auth_method = ms_strdup(lp_config_get_string(config, section, "auth_method", "anonymous"));
obj->username = ms_strdup(lp_config_get_string(config, section, "username", ""));
obj->password = ms_strdup(lp_config_get_string(config, section, "password", ""));
obj->base_object = ms_strdup(lp_config_get_string(config, section, "base_object", ""));
}
LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore* lc)
{
LinphoneLDAPContactProvider* obj = belle_sip_object_new(LinphoneLDAPContactProvider);
linphone_contact_provider_init(LINPHONE_CONTACT_PROVIDER(obj), lc);
memset(obj->requests, MAX_RUNNING_REQUESTS, sizeof(LDAPRequestEntry));
int proto_version = LDAP_VERSION3;
const char* url = "localhost";
ms_message( "Constructed Contact provider '%s'", BELLE_SIP_OBJECT_VPTR(obj,LinphoneContactProvider)->name);
linphone_ldap_contact_provider_loadconfig(obj, linphone_core_get_config(lc));
int ret = ldap_initialize(&(obj->ld),url);
if( ret != LDAP_SUCCESS ){
ms_error( "Problem initializing ldap on url '%s': %s", url, ldap_err2string(ret));
linphone_ldap_contact_provider_destroy(obj);
return NULL;
} else if( (ret = ldap_set_option(obj->ld, LDAP_OPT_PROTOCOL_VERSION, &proto_version)) != LDAP_SUCCESS ){
ms_error( "Problem setting protocol version %d: %s", proto_version, ldap_err2string(ret));
linphone_ldap_contact_provider_destroy(obj);
return NULL;
} else {
// register our hook into iterate so that LDAP can do its magic asynchronously
linphone_core_add_iterate_hook(lc, linphone_ldap_contact_provider_iterate, obj);
}
return obj;
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "contactprovider.h"
#include <ldap.h>
typedef struct _LinphoneLDAPContactProvider LinphoneLDAPContactProvider;
/* LinphoneLDAPContactSearch */
typedef struct _LinphoneLDAPContactSearch LinphoneLDAPContactSearch;
#define LINPHONE_LDAP_CONTACT_SEARCH(obj) BELLE_SIP_CAST(obj,LinphoneLDAPContactSearch)
BELLE_SIP_DECLARE_VPTR(LinphoneLDAPContactSearch)
LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPContactProvider* ld,
const char* predicate,
ContactSearchCallback cb,
void* cb_data);
/* LinphoneLDAPContactProvider */
#define LINPHONE_LDAP_CONTACT_PROVIDER(obj) BELLE_SIP_CAST(obj,LinphoneLDAPContactProvider)
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(LinphoneLDAPContactProvider,LinphoneContactProvider)
BELLE_SIP_DECLARE_CUSTOM_VPTR_END
LinphoneLDAPContactProvider* linphone_ldap_contact_provider_create(LinphoneCore* lc);
......@@ -2152,10 +2152,12 @@ LINPHONE_PUBLIC void linphone_core_set_video_display_filter(LinphoneCore *lc, co
/** Contact Providers
*/
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
BELLE_SIP_TYPE_ID(linphone_contact_provider_t)
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch)
BELLE_SIP_DECLARE_TYPES_END
BELLE_SIP_DECLARE_VPTR(linphone_contact_provider_t)
#ifdef __cplusplus
}
......
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