openldap/libraries/liblutil/sasl.c

223 lines
4.5 KiB
C
Raw Normal View History

/* $OpenLDAP$ */
/*
2003-01-04 04:20:47 +08:00
* Copyright 2000-2003 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#ifdef HAVE_CYRUS_SASL
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/unistd.h>
2002-02-11 17:39:15 +08:00
#ifdef HAVE_SASL_SASL_H
#include <sasl/sasl.h>
#else
#include <sasl.h>
2002-02-11 17:39:15 +08:00
#endif
#include <ldap.h>
#include "lutil_ldap.h"
typedef struct lutil_sasl_defaults_s {
char *mech;
char *realm;
char *authcid;
char *passwd;
char *authzid;
char **resps;
int nresps;
} lutilSASLdefaults;
void
lutil_sasl_freedefs(
void *defaults )
{
lutilSASLdefaults *defs = defaults;
if (defs->mech) ber_memfree(defs->mech);
if (defs->realm) ber_memfree(defs->realm);
if (defs->authcid) ber_memfree(defs->authcid);
if (defs->passwd) ber_memfree(defs->passwd);
if (defs->authzid) ber_memfree(defs->authzid);
if (defs->resps) ldap_charray_free(defs->resps);
ber_memfree(defs);
}
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 ? ber_strdup(mech) : NULL;
defaults->realm = realm ? ber_strdup(realm) : NULL;
defaults->authcid = authcid ? ber_strdup(authcid) : NULL;
defaults->passwd = passwd ? ber_strdup(passwd) : NULL;
defaults->authzid = authzid ? ber_strdup(authzid) : NULL;
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 );
}
defaults->resps = NULL;
defaults->nresps = 0;
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;
2000-07-18 05:36:30 +08:00
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 ) {
2003-04-06 14:47:31 +08:00
fprintf( stderr, _("Challenge: %s\n"), interact->challenge );
}
}
if( dflt ) {
2003-04-06 14:47:31 +08:00
fprintf( stderr, _("Default: %s\n"), dflt );
}
2002-07-24 02:26:33 +08:00
snprintf( input, sizeof input, "%s: ",
2003-04-06 14:47:31 +08:00
interact->prompt ? interact->prompt : _("Interact") );
if( noecho ) {
interact->result = (char *) getpassphrase( input );
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 */
2002-02-10 22:27:23 +08:00
char *p = (char *)interact->result;
ldap_charray_add(&defaults->resps, interact->result);
interact->result = defaults->resps[defaults->nresps++];
/* zap */
memset( p, '\0', interact->len );
} else {
use_default:
2000-07-18 05:45:18 +08:00
/* input must be empty */
interact->result = (dflt && *dflt) ? dflt : "";
interact->len = strlen( interact->result );
}
return LDAP_SUCCESS;
}
int lutil_sasl_interact(
LDAP *ld,
unsigned flags,
void *defaults,
void *in )
{
sasl_interact_t *interact = in;
2003-02-22 03:27:54 +08:00
if( ld == NULL ) return LDAP_PARAM_ERROR;
2000-07-18 05:36:30 +08:00
if( flags == LDAP_SASL_INTERACTIVE ) {
2003-04-06 14:47:31 +08:00
fputs( _("SASL Interaction\n"), stderr );
}
2000-07-15 09:28:16 +08:00
while( interact->id != SASL_CB_LIST_END ) {
int rc = interaction( flags, interact, defaults );
if( rc ) return rc;
interact++;
}
return LDAP_SUCCESS;
}
#endif