From cfc100243ba1d9b37e814f7c1a416652d0b605ec Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 6 Dec 2013 14:31:07 +0100 Subject: [PATCH] Use LinphoneDictionary instead of lpconfig for creating LDAP provider. --- coreapi/ldap/ldapprovider.c | 149 ++++++++++++++++++++++-------------- coreapi/ldap/ldapprovider.h | 2 +- coreapi/linphonecore.c | 21 ----- coreapi/linphonecore.h | 2 - gtk/linphone.h | 6 ++ gtk/main.c | 47 ++++++++++-- 6 files changed, 140 insertions(+), 87 deletions(-) diff --git a/coreapi/ldap/ldapprovider.c b/coreapi/ldap/ldapprovider.c index 7f49c21b7..3bab710b2 100644 --- a/coreapi/ldap/ldapprovider.c +++ b/coreapi/ldap/ldapprovider.c @@ -175,7 +175,7 @@ static LDAPAuthMethod linphone_ldap_contact_provider_auth_method( const char* de return ANONYMOUS; } -static void linphone_ldap_contact_provider_destroy_request(void *req) +static void linphone_ldap_contact_provider_destroy_request_cb(void *req) { belle_sip_object_unref(req); } @@ -183,7 +183,7 @@ static void linphone_ldap_contact_provider_destroy_request(void *req) static void linphone_ldap_contact_provider_destroy( LinphoneLDAPContactProvider* obj ) { // clean pending requests - ms_list_for_each(obj->requests, linphone_ldap_contact_provider_destroy_request); + ms_list_for_each(obj->requests, linphone_ldap_contact_provider_destroy_request_cb); if (obj->ld) ldap_unbind_ext(obj->ld, NULL, NULL); obj->ld = NULL; @@ -368,13 +368,6 @@ static bool_t linphone_ldap_contact_provider_iterate(void *data) static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvider* obj ) { - 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->filter) ms_free(obj->filter); - if(obj->sip_attr) ms_free(obj->sip_attr); - if(obj->name_attr) ms_free(obj->name_attr); - if(obj->attributes){ int i=0; for( ; obj->attributes[i]; i++){ @@ -384,53 +377,87 @@ static void linphone_ldap_contact_provider_conf_destroy(LinphoneLDAPContactProvi } } -static bool_t linphone_ldap_contact_provider_valid_config(LinphoneLDAPContactProvider* obj) +static char* required_config_keys[] = { + // connection + "server", + "use_tls", + "auth_method", + "username", + "password", + + // search + "base_object", + "filter", + "name_attribute", + "sip_attribute", + "attributes", + + // misc + "timeout", + "max_results", + "deref_aliases", + NULL +}; + +static bool_t linphone_ldap_contact_provider_valid_config(LinphoneDictionary* dict) { - bool_t valid = linphone_dictionary_haskey(obj->config, "use_tls") && - linphone_dictionary_haskey(obj->config, "timeout") && - linphone_dictionary_haskey(obj->config, "deref_aliases") && - linphone_dictionary_haskey(obj->config, "max_results") && - linphone_dictionary_haskey(obj->config, "auth_method") && - linphone_dictionary_haskey(obj->config, "username") && - linphone_dictionary_haskey(obj->config, "password") && - linphone_dictionary_haskey(obj->config, "base_object") && - linphone_dictionary_haskey(obj->config, "server") && - linphone_dictionary_haskey(obj->config, "filter") && - linphone_dictionary_haskey(obj->config, "name_attribute") && - linphone_dictionary_haskey(obj->config, "sip_attribute") && - linphone_dictionary_haskey(obj->config, "attributes"); + char** config_name = required_config_keys; + + bool_t valid = TRUE; + bool_t has_key; + + while(*config_name ){ + has_key = linphone_dictionary_haskey(dict, *config_name); + if( !has_key ) ms_error("Missing LDAP config value for '%s'", *config_name); + valid &= has_key; + } return valid; } -static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvider* obj, LpConfig* config) +static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvider* obj, const LinphoneDictionary* dict) { - 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); - obj->auth_method = linphone_ldap_contact_provider_auth_method( lp_config_get_string(config, section, "auth_method", "anonymous")); + if( !linphone_ldap_contact_provider_valid_config(dict) ) return; - // free any pre-existing char* conf values + // free any pre-existing attributes values linphone_ldap_contact_provider_conf_destroy(obj); + if( obj->config ) linphone_dictionary_unref(obj->config); - 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", "dc=example,dc=com")); - obj->server = ms_strdup(lp_config_get_string(config, section, "server", "ldap://192.168.0.230:10389")); - obj->filter = ms_strdup(lp_config_get_string(config, section, "filter", "uid=*%s*")); - obj->name_attr = ms_strdup(lp_config_get_string(config, section, "name_attribute", "givenName")); - obj->sip_attr = ms_strdup(lp_config_get_string(config, section, "sip_attribute", "mobile")); + // clone new config into the dictionary + obj->config = linphone_dictionary_clone(dict); + linphone_dictionary_ref(obj->config); + + + obj->use_tls = linphone_dictionary_get_int(obj->config, "use_tls", 0); + obj->timeout = linphone_dictionary_get_int(obj->config, "timeout", 10); + obj->deref_aliases = linphone_dictionary_get_int(obj->config, "deref_aliases", 0); + obj->max_results = linphone_dictionary_get_int(obj->config, "max_results", 50); + obj->username = linphone_dictionary_get_string(obj->config, "username", ""); + obj->password = linphone_dictionary_get_string(obj->config, "password", ""); + obj->base_object = linphone_dictionary_get_string(obj->config, "base_object", "dc=example,dc=com"); + obj->server = linphone_dictionary_get_string(obj->config, "server", "ldap://192.168.0.230:10389"); + obj->filter = linphone_dictionary_get_string(obj->config, "filter", "uid=*%s*"); + obj->name_attr = linphone_dictionary_get_string(obj->config, "name_attribute", "givenName"); + obj->sip_attr = linphone_dictionary_get_string(obj->config, "sip_attribute", "mobile"); + + /* + * Get authentication method + */ + obj->auth_method = + linphone_ldap_contact_provider_auth_method( + linphone_dictionary_get_string(obj->config, "auth_method", "anonymous") + ); /* * parse the attributes list */ - attributes_list = ms_strdup(lp_config_get_string(config, section, - "attributes", - "telephoneNumber,givenName,sn,mobile,homePhone")); + attributes_list = ms_strdup( + linphone_dictionary_get_string(obj->config, + "attributes", + "telephoneNumber,givenName,sn,mobile,homePhone") + ); // count attributes: for( i=0; attributes_list[i]; i++) { @@ -453,7 +480,8 @@ static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvide static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj ) { - struct berval password = { strlen( obj->password), obj->password }; + const char* password_str = linphone_dictionary_get_string(obj, "password", ""); + struct berval password = { strlen( password_str ), password_str }; int ret; int bind_msgid = 0; @@ -480,32 +508,37 @@ static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj return 0; } -LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore* lc) +LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore* lc, const LinphoneDictionary* config) { LinphoneLDAPContactProvider* obj = belle_sip_object_new(LinphoneLDAPContactProvider); int proto_version = LDAP_VERSION3; linphone_contact_provider_init((LinphoneContactProvider*)obj, lc); - obj->config = linphone_dictionary_ref(linphone_dictionary_new()); 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),obj->server); - - if( ret != LDAP_SUCCESS ){ - ms_error( "Problem initializing ldap on url '%s': %s", obj->server, ldap_err2string(ret)); + if( !linphone_ldap_contact_provider_valid_config(config) ) { + ms_error( "Invalid configuration for LDAP, aborting creation"); belle_sip_object_unref(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)); - belle_sip_object_unref(obj); - return NULL; + obj = NULL; } else { - // register our hook into iterate so that LDAP can do its magic asynchronously. - linphone_ldap_contact_provider_bind(obj); - linphone_core_add_iterate_hook(lc, linphone_ldap_contact_provider_iterate, obj); + linphone_ldap_contact_provider_loadconfig(obj, config); + + int ret = ldap_initialize(&(obj->ld),obj->server); + + if( ret != LDAP_SUCCESS ){ + ms_error( "Problem initializing ldap on url '%s': %s", obj->server, ldap_err2string(ret)); + belle_sip_object_unref(obj); + obj = 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)); + belle_sip_object_unref(obj); + obj = NULL; + } else { + // register our hook into iterate so that LDAP can do its magic asynchronously. + linphone_ldap_contact_provider_bind(obj); + linphone_core_add_iterate_hook(lc, linphone_ldap_contact_provider_iterate, obj); + } } return obj; } diff --git a/coreapi/ldap/ldapprovider.h b/coreapi/ldap/ldapprovider.h index bea77554b..be8c23235 100644 --- a/coreapi/ldap/ldapprovider.h +++ b/coreapi/ldap/ldapprovider.h @@ -39,4 +39,4 @@ LinphoneLDAPContactSearch* linphone_ldap_contact_search_create(LinphoneLDAPConta BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(LinphoneLDAPContactProvider,LinphoneContactProvider) BELLE_SIP_DECLARE_CUSTOM_VPTR_END -LinphoneLDAPContactProvider* linphone_ldap_contact_provider_create(LinphoneCore* lc); +LinphoneLDAPContactProvider* linphone_ldap_contact_provider_create(LinphoneCore* lc, const LinphoneDictionary* config); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index f52283cb6..7cc9ee14d 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6270,24 +6270,3 @@ void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path){ linphone_core_message_storage_init(lc); } } - - -LinphoneContactSearch* linphone_core_ldap_launch_search(LinphoneCore* lc, const char* predicate, ContactSearchCallback cb, void* userdata) -{ - if( lc->ldap ){ - LinphoneContactProvider* cp = LINPHONE_CONTACT_PROVIDER(lc->ldap); - LinphoneContactSearch* search = BELLE_SIP_OBJECT_VPTR(cp,LinphoneContactProvider)->begin_search(cp, predicate, cb, userdata); - char *desc = belle_sip_object_to_string(cp); - - if( desc) { - ms_message("ldap: %s", desc); - ms_free(desc); - } - - if(search){ - belle_sip_object_ref(search); - return search; - } - } - return NULL; -} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 9f57d1ce3..0345344cb 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -2216,8 +2216,6 @@ typedef struct _LinphoneContactSearch LinphoneContactSearch; typedef void (*ContactSearchCallback)( LinphoneContactSearch* id, MSList* friends, void* data ); -LINPHONE_PUBLIC LinphoneContactSearch* linphone_core_ldap_launch_search(LinphoneCore* lc, const char* predicate, ContactSearchCallback cb, void* userdata); - #ifdef __cplusplus } #endif diff --git a/gtk/linphone.h b/gtk/linphone.h index 2b2eba531..da398d9df 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -28,6 +28,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #include "linphonecore.h" +#ifdef BUILD_LDAP +#include "ldap/ldapprovider.h" +#endif + + #ifdef ENABLE_NLS # include # undef _ @@ -68,6 +73,7 @@ void linphone_gtk_show_assistant(void); void linphone_gtk_close_assistant(void); LinphoneCore *linphone_gtk_get_core(void); +LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void); GtkWidget *linphone_gtk_get_main_window(); void linphone_gtk_display_something(GtkMessageType type,const gchar *message); void linphone_gtk_start_call(GtkWidget *button); diff --git a/gtk/main.c b/gtk/main.c index 870c1d40e..aa114644d 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -50,6 +50,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION; static LinphoneCore *the_core=NULL; +static LinphoneLDAPContactProvider* ldap_provider = NULL; static GtkWidget *the_ui=NULL; static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState rs, const char *msg); @@ -256,7 +257,17 @@ static void linphone_gtk_init_liblinphone(const char *config_file, the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL); //lp_config_set_int(linphone_core_get_config(the_core), "sip", "store_auth_info", 0); - + + +#ifdef BUILD_LDAP + if( lp_config_has_section(linphone_core_get_config(the_core),"ldap") ){ + LpConfig* cfg = linphone_core_get_config(the_core); + LinphoneDictionary* ldap_cfg = lp_config_section_to_dict(cfg, "ldap"); + ldap_provider = linphone_ldap_contact_provider_create(the_core, ldap_cfg); + belle_sip_object_ref( ldap_provider ); + } +#endif + linphone_core_set_user_agent(the_core,"Linphone", LINPHONE_VERSION); linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL); linphone_core_set_zrtp_secrets_file(the_core,secrets_file); @@ -274,12 +285,20 @@ LinphoneCore *linphone_gtk_get_core(void){ return the_core; } +LinphoneLDAPContactProvider* linphone_gtk_get_ldap(void){ +#ifdef BUILD_LDAP + return ldap_provider; +#else + return NULL; +#endif +} + GtkWidget *linphone_gtk_get_main_window(){ return the_ui; } void linphone_gtk_destroy_main_window() { - linphone_gtk_destroy_window(the_ui); + linphone_gtk_destroy_window(the_ui); the_ui = NULL; } @@ -786,19 +805,37 @@ struct CompletionTimeout { static gboolean launch_contact_provider_search(void *userdata) { - LinphoneCore* core = linphone_gtk_get_core(); + LinphoneLDAPContactProvider* ldap = linphone_gtk_get_ldap(); GtkWidget* uribar = GTK_WIDGET(userdata); const gchar* predicate = gtk_entry_get_text((GtkEntry*)uribar); - if( strlen(predicate) >= 3 ){ // don't search too small predicates + if( ldap && strlen(predicate) >= 3 ){ // don't search too small predicates + ms_message("launch_contact_provider_search"); - linphone_core_ldap_launch_search(core, predicate, on_contact_provider_search_results, uribar); + + LinphoneContactSearch* search = + BELLE_SIP_OBJECT_VPTR(ldap,LinphoneContactProvider)->begin_search( + LINPHONE_CONTACT_PROVIDER(ldap), + predicate, + on_contact_provider_search_results, + uribar); + + char *desc = belle_sip_object_to_string(ldap); + + if( desc) { + ms_message("ldap: %s", desc); + ms_free(desc); + } + + if(search) + belle_sip_object_ref(search); } return FALSE; } void linphone_gtk_on_uribar_changed(GtkEditable *uribar, gpointer user_data) { +#ifdef BUILD_LDAP gchar* text = gtk_editable_get_chars(uribar, 0,-1); gint timeout = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(uribar), "complete_timeout")); ms_message("URIBAR changed, new text: %s, userdata %p uribar @%p", text, user_data, uribar);