[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
ldap sasl bind programming : digest-md5 problem
hello all
I'm trying to program an sasl/digest-md5 bind with libldap
I use the following code, nearly totally pasted from ldap client tools
source code
it compiles, but when I start it I got a sasl bind in progress (tag=66)"
error in my slapd logs
somebody can help me ?
thank you very much :)
Francois
#include <stdio.h>
#include <ldap.h>
#include <sasl.h>
typedef struct lutil_sasl_defaults_s {
char *mech;
char *realm;
char *authcid;
char *passwd;
char *authzid;
} lutilSASLdefaults;
void *lutil_sasl_defaults(LDAP *ld, char *mech, char *realm, char
*authcid, char *passwd, char *authzid);
static int interaction ( unsigned flags, sasl_interact_t *interact,
lutilSASLdefaults *defaults);
int ldap_sasl_interaction(LDAP *ld, unsigned flags, void *defaults, void
*in);
int main(int argc, char *argv[])
{
void *defaults;
unsigned sasl_flags = LDAP_SASL_QUIET;
char *sasl_mech = ber_strdup("DIGEST-MD5");
char *sasl_realm = NULL;
//char *sasl_authc_id = ber_strdup("francois");
char *sasl_authc_id = "francois";
char *sasl_authz_id = NULL;
struct berval passwd = {0, NULL};
int rc;
char *ldaphost = "linux-integ.enatel.local";
int ldapport = 389;
LDAP *ld = NULL;
int version = LDAP_VERSION3;
ld = ldap_init( ldaphost, ldapport );
if (ldap_set_option(ld,
LDAP_OPT_PROTOCOL_VERSION,
&version) != LDAP_OPT_SUCCESS)
return LDAP_OPERATIONS_ERROR;
defaults = lutil_sasl_defaults(ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id);
rc = ldap_sasl_interactive_bind_s(ld,
NULL,
sasl_mech,
NULL,
NULL,
sasl_flags,
ldap_sasl_interaction,
defaults);
ldap_unbind (ld);
}
void *lutil_sasl_defaults(LDAP *ld, char *mech, char *realm, char
*authcid, char *passwd, char *authzid)
{
lutilSASLdefaults *defaults;
defaults = ber_memalloc( sizeof( lutilSASLdefaults ) );
if( defaults == NULL ) return NULL;
defaults->mech = mech;
defaults->realm = realm;
defaults->authcid = authcid;
defaults->passwd = passwd;
defaults->authzid = authzid;
if( defaults->mech == NULL ) {
ldap_get_option( ld, LDAP_OPT_X_SASL_MECH, &defaults->mech );
}
if( defaults->realm == NULL ) {
ldap_get_option( ld, LDAP_OPT_X_SASL_REALM, &defaults->realm );
}
if( defaults->authcid == NULL ) {
ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHCID, &defaults->authcid );
}
if( defaults->authzid == NULL ) {
ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHZID, &defaults->authzid );
}
return defaults;
}
static int interaction ( unsigned flags,
sasl_interact_t *interact,
lutilSASLdefaults *defaults )
{
const char *dflt = interact->defresult;
char input[1024];
int noecho=0;
int challenge=0;
switch( interact->id ) {
case SASL_CB_GETREALM:
if( defaults ) dflt = defaults->realm;
break;
case SASL_CB_AUTHNAME:
if( defaults ) dflt = defaults->authcid;
break;
case SASL_CB_PASS:
if( defaults ) dflt = defaults->passwd;
noecho = 1;
break;
case SASL_CB_USER:
if( defaults ) dflt = defaults->authzid;
break;
case SASL_CB_NOECHOPROMPT:
noecho = 1;
challenge = 1;
break;
case SASL_CB_ECHOPROMPT:
challenge = 1;
break;
}
if( dflt && !*dflt ) dflt = NULL;
if( flags != LDAP_SASL_INTERACTIVE &&
( dflt || interact->id == SASL_CB_USER ) )
{
goto use_default;
}
if( flags == LDAP_SASL_QUIET ) {
/* don't prompt */
return LDAP_OTHER;
}
if( challenge ) {
if( interact->challenge ) {
fprintf( stderr, "Challenge: %s\n", interact->challenge );
}
}
if( dflt ) {
fprintf( stderr, "Default: %s\n", dflt );
}
snprintf( input, sizeof input, "%s: ",
interact->prompt ? interact->prompt : "Interact" );
if( noecho ) {
//interact->result = (char *) getpassphrase( input );
interact->result = (char *) "toto";
interact->len = interact->result
? strlen( interact->result ) : 0;
} else {
/* prompt user */
fputs( input, stderr );
/* get input */
interact->result = fgets( input, sizeof(input), stdin );
if( interact->result == NULL ) {
interact->len = 0;
return LDAP_UNAVAILABLE;
}
/* len of input */
interact->len = strlen(input);
if( interact->len > 0 && input[interact->len - 1] == '\n' ) {
/* input includes '\n', trim it */
interact->len--;
input[interact->len] = '\0';
}
}
if( interact->len > 0 ) {
/* duplicate */
char *p = (char *)interact->result;
interact->result = strdup( p );
/* zap */
memset( p, '\0', interact->len );
} else {
use_default:
/* input must be empty */
interact->result = strdup( (dflt && *dflt) ? dflt : "" );
interact->len = interact->result
? strlen( interact->result ) : 0;
}
if( defaults && defaults->passwd && interact->id == SASL_CB_PASS ) {
/* zap password after first use */
memset( defaults->passwd, '\0', strlen(defaults->passwd) );
defaults->passwd = NULL;
}
return LDAP_SUCCESS;
}
int ldap_sasl_interaction(
LDAP *ld,
unsigned flags,
void *defaults,
void *in )
{
sasl_interact_t *interact = in;
if( interact->result ) {
// we have results from a previous interaction
free( (void *)interact->result );
interact->result = NULL;
}
if( ld == NULL ) return LDAP_PARAM_ERROR;
if( flags == LDAP_SASL_INTERACTIVE ) {
fputs( "SASL Interaction\n", stderr );
}
while( interact->id != SASL_CB_LIST_END ) {
int rc = interaction( flags, interact, defaults );
if( rc ) return rc;
interact++;
}
return LDAP_SUCCESS;
}