mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Progress commit...
This commit is contained in:
parent
006ba8be2e
commit
f5c9d60d88
1 changed files with 150 additions and 54 deletions
|
|
@ -19,12 +19,6 @@
|
|||
#include "lpconfig.h"
|
||||
#include <ldap.h>
|
||||
|
||||
struct _LinphoneLDAPContactSearch
|
||||
{
|
||||
LDAP *ld;
|
||||
int msgid;
|
||||
char* filter;
|
||||
};
|
||||
|
||||
#define MAX_RUNNING_REQUESTS 10
|
||||
#define FILTER_MAX_SIZE 512
|
||||
|
|
@ -33,18 +27,27 @@ typedef struct {
|
|||
LinphoneLDAPContactSearch* request;
|
||||
} LDAPRequestEntry;
|
||||
|
||||
typedef enum {
|
||||
ANONYMOUS,
|
||||
PLAIN,
|
||||
SASL
|
||||
} LDAPAuthMethod;
|
||||
|
||||
struct _LinphoneLDAPContactProvider
|
||||
{
|
||||
LDAP* ld;
|
||||
//LDAPRequestEntry requests[MAX_RUNNING_REQUESTS];
|
||||
LDAP* ld;
|
||||
MSList* requests;
|
||||
int req_count;
|
||||
uint req_count;
|
||||
|
||||
// bind transaction
|
||||
uint bind_msgid;
|
||||
|
||||
// config
|
||||
int use_tls;
|
||||
char* auth_method;
|
||||
LDAPAuthMethod auth_method;
|
||||
char* username;
|
||||
char* password;
|
||||
char* server;
|
||||
|
||||
char* base_object;
|
||||
char** attributes;
|
||||
|
|
@ -54,6 +57,14 @@ struct _LinphoneLDAPContactProvider
|
|||
int max_results;
|
||||
};
|
||||
|
||||
struct _LinphoneLDAPContactSearch
|
||||
{
|
||||
LDAP *ld;
|
||||
int msgid;
|
||||
char* filter;
|
||||
};
|
||||
|
||||
|
||||
/* *************************
|
||||
* LinphoneLDAPContactSearch
|
||||
* *************************/
|
||||
|
|
@ -62,20 +73,38 @@ LinphoneLDAPContactSearch*linphone_ldap_contact_search_create(LinphoneLDAPContac
|
|||
{
|
||||
LinphoneLDAPContactSearch* search = belle_sip_object_new(LinphoneLDAPContactSearch);
|
||||
LinphoneContactSearch* base = LINPHONE_CONTACT_SEARCH(search);
|
||||
struct timeval timeout = { cp->timeout, 0 };
|
||||
|
||||
linphone_contact_search_init(base, predicate, cb, cb_data);
|
||||
search->ld = cp->ld;
|
||||
|
||||
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 );
|
||||
|
||||
int ret = ldap_search_ext(search->ld,
|
||||
cp->base_object, // base from which to start
|
||||
LDAP_SCOPE_SUBTREE,
|
||||
search->filter, // search predicate
|
||||
cp->attributes, // which attributes to get
|
||||
0, // 0 = get attrs AND value, 1 = get attrs only
|
||||
NULL,
|
||||
NULL,
|
||||
&timeout, // server timeout for the search
|
||||
cp->max_results,// max result number
|
||||
&search->msgid );
|
||||
if( ret != LDAP_SUCCESS ){
|
||||
ms_error("Error ldap_search_ext returned %d (%s)", ret, ldap_err2string(ret));
|
||||
belle_sip_object_unref(search);
|
||||
return NULL;
|
||||
}
|
||||
return search;
|
||||
}
|
||||
|
||||
static void linphone_ldap_contact_destroy( LinphoneLDAPContactSearch* obj )
|
||||
{
|
||||
(void)obj;
|
||||
if( obj->filter ) ms_free(obj->filter);
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLDAPContactSearch);
|
||||
|
|
@ -90,13 +119,35 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneLDAPContactSearch,LinphoneContactSearch,
|
|||
/* ***************************
|
||||
* LinphoneLDAPContactProvider
|
||||
* ***************************/
|
||||
struct AuthMethodDescription{
|
||||
LDAPAuthMethod method;
|
||||
const char* description;
|
||||
};
|
||||
|
||||
static struct AuthMethodDescription ldap_auth_method_description[] = {
|
||||
{ANONYMOUS, "anonymous"},
|
||||
{PLAIN, "plain"},
|
||||
{SASL, "sasl"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static LDAPAuthMethod linphone_ldap_contact_provider_auth_method( const char* description )
|
||||
{
|
||||
struct AuthMethodDescription* desc = ldap_auth_method_description;
|
||||
while( desc && desc->description ){
|
||||
if( strcmp(description, desc->description) == 0)
|
||||
return desc->method;
|
||||
desc++;
|
||||
}
|
||||
return ANONYMOUS;
|
||||
}
|
||||
|
||||
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->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++){
|
||||
|
|
@ -113,17 +164,20 @@ static void linphone_ldap_contact_provider_destroy( LinphoneLDAPContactProvider*
|
|||
linphone_ldap_contact_provider_conf_destroy(obj);
|
||||
}
|
||||
|
||||
static LinphoneLDAPContactSearch* linphone_ldap_begin_search(LinphoneLDAPContactProvider* obj,
|
||||
const char* predicate,
|
||||
ContactSearchCallback cb,
|
||||
void* cb_data)
|
||||
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->requests = ms_list_append(obj->requests, entry);
|
||||
obj->req_count++;
|
||||
return request;
|
||||
} else {
|
||||
|
|
@ -158,33 +212,16 @@ static unsigned int linphone_ldap_cancel_search(LinphoneContactProvider* obj, Li
|
|||
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;
|
||||
if( obj->ld && ((obj->req_count >= 0) || (obj->bind_msgid != 0) )){
|
||||
|
||||
// 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);
|
||||
int res = ldap_result(obj->ld, LDAP_RES_ANY, LDAP_MSG_ALL, &timeout, &results);
|
||||
|
||||
switch( res ){
|
||||
case -1:
|
||||
|
|
@ -193,7 +230,14 @@ static bool_t linphone_ldap_contact_provider_iterate(void *data)
|
|||
break;
|
||||
}
|
||||
case 0: break; // nothing to do
|
||||
case LDAP_RES_BIND:
|
||||
case LDAP_RES_BIND:
|
||||
{
|
||||
ms_message("iterate: LDAP_RES_BIND");
|
||||
if( ldap_msgid( results ) != obj->bind_msgid ) {
|
||||
ms_error("Bad msgid");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
case LDAP_RES_SEARCH_REFERENCE:
|
||||
case LDAP_RES_SEARCH_RESULT:
|
||||
|
|
@ -226,13 +270,19 @@ static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvide
|
|||
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"));
|
||||
|
||||
|
||||
// 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"));
|
||||
/*
|
||||
* 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++)
|
||||
|
|
@ -240,6 +290,7 @@ static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvide
|
|||
if( attributes_list[i] == ',') attr_count++;
|
||||
}
|
||||
obj->attributes = ms_malloc0((attr_count+2) * sizeof(char*));
|
||||
// 1 more for the first attr without ',', the other for the null-finished list
|
||||
|
||||
attr = strtok_r( attributes_list, ",", &saveptr );
|
||||
while( attr != NULL ){
|
||||
|
|
@ -247,17 +298,45 @@ static void linphone_ldap_contact_provider_loadconfig(LinphoneLDAPContactProvide
|
|||
attr_idx++;
|
||||
attr = strtok_r(NULL, ",", &saveptr);
|
||||
}
|
||||
if( attr_idx == attr_count)
|
||||
if( attr_idx != attr_count+1) ms_error("Invalid attribute number!!! %d expected, got %d", attr_count+1, attr_idx);
|
||||
|
||||
ms_free(attributes_list);
|
||||
|
||||
|
||||
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", ""));
|
||||
obj->server = ms_strdup(lp_config_get_string(config, section, "server", "ldap://localhost:10389"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
static int linphone_ldap_contact_provider_bind( LinphoneLDAPContactProvider* obj )
|
||||
{
|
||||
struct berval password = { strlen( obj->password), obj->password };
|
||||
int ret;
|
||||
int bind_msgid = 0;
|
||||
|
||||
switch( obj->auth_method ){
|
||||
case ANONYMOUS:
|
||||
default:
|
||||
{
|
||||
ret = ldap_sasl_bind( obj->ld, obj->base_object, NULL, &password, NULL, NULL, &bind_msgid);
|
||||
if( ret == LDAP_SUCCESS ) {
|
||||
obj->bind_msgid = bind_msgid;
|
||||
} else {
|
||||
int err;
|
||||
ldap_get_option(obj->ld, LDAP_OPT_RESULT_CODE, &err);
|
||||
ms_error("ldap_sasl_bind error %d (%s)", err, ldap_err2string(err) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SASL:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore* lc)
|
||||
{
|
||||
|
|
@ -266,25 +345,42 @@ LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore*
|
|||
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);
|
||||
int ret = ldap_initialize(&(obj->ld),obj->server);
|
||||
|
||||
if( ret != LDAP_SUCCESS ){
|
||||
ms_error( "Problem initializing ldap on url '%s': %s", url, ldap_err2string(ret));
|
||||
linphone_ldap_contact_provider_destroy(obj);
|
||||
ms_error( "Problem initializing ldap on url '%s': %s", obj->server, ldap_err2string(ret));
|
||||
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));
|
||||
linphone_ldap_contact_provider_destroy(obj);
|
||||
belle_sip_object_unref(obj);
|
||||
return 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;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue