2000-07-14 06:54:38 +08:00
|
|
|
/* $OpenLDAP$ */
|
|
|
|
/*
|
2002-01-05 05:17:25 +08:00
|
|
|
* Copyright 2000-2002 The OpenLDAP Foundation, All Rights Reserved.
|
2000-07-14 06:54:38 +08:00
|
|
|
* 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
|
2000-07-14 06:54:38 +08:00
|
|
|
#include <sasl.h>
|
2002-02-11 17:39:15 +08:00
|
|
|
#endif
|
2000-07-14 06:54:38 +08:00
|
|
|
|
|
|
|
#include <ldap.h>
|
|
|
|
#include "lutil_ldap.h"
|
|
|
|
|
2000-07-17 08:56:29 +08:00
|
|
|
|
|
|
|
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 )
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2000-07-14 06:54:38 +08:00
|
|
|
static int interaction(
|
2000-07-18 05:23:59 +08:00
|
|
|
unsigned flags,
|
|
|
|
sasl_interact_t *interact,
|
|
|
|
lutilSASLdefaults *defaults )
|
2000-07-14 06:54:38 +08:00
|
|
|
{
|
2000-07-17 08:56:29 +08:00
|
|
|
const char *dflt = interact->defresult;
|
2000-07-14 06:54:38 +08:00
|
|
|
char input[1024];
|
|
|
|
|
|
|
|
int noecho=0;
|
|
|
|
int challenge=0;
|
|
|
|
|
|
|
|
switch( interact->id ) {
|
2000-07-17 08:56:29 +08:00
|
|
|
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;
|
2000-07-14 06:54:38 +08:00
|
|
|
case SASL_CB_NOECHOPROMPT:
|
|
|
|
noecho = 1;
|
|
|
|
challenge = 1;
|
|
|
|
break;
|
|
|
|
case SASL_CB_ECHOPROMPT:
|
|
|
|
challenge = 1;
|
|
|
|
break;
|
2000-07-17 08:56:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if( dflt && !*dflt ) dflt = NULL;
|
|
|
|
|
2000-07-18 05:36:30 +08:00
|
|
|
if( flags != LDAP_SASL_INTERACTIVE &&
|
|
|
|
( dflt || interact->id == SASL_CB_USER ) )
|
|
|
|
{
|
2000-07-17 08:56:29 +08:00
|
|
|
goto use_default;
|
|
|
|
}
|
|
|
|
|
2000-07-18 05:23:59 +08:00
|
|
|
if( flags == LDAP_SASL_QUIET ) {
|
2000-07-17 08:56:29 +08:00
|
|
|
/* don't prompt */
|
|
|
|
return LDAP_OTHER;
|
2000-07-14 06:54:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if( challenge ) {
|
|
|
|
if( interact->challenge ) {
|
|
|
|
fprintf( stderr, "Challenge: %s\n", interact->challenge );
|
|
|
|
}
|
2000-07-17 08:56:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if( dflt ) {
|
|
|
|
fprintf( stderr, "Default: %s\n", dflt );
|
2000-07-14 06:54:38 +08:00
|
|
|
}
|
|
|
|
|
2002-07-24 02:26:33 +08:00
|
|
|
snprintf( input, sizeof input, "%s: ",
|
2000-07-17 08:56:29 +08:00
|
|
|
interact->prompt ? interact->prompt : "Interact" );
|
2000-07-14 06:54:38 +08:00
|
|
|
|
|
|
|
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;
|
2000-07-14 06:54:38 +08:00
|
|
|
interact->result = strdup( p );
|
|
|
|
|
|
|
|
/* zap */
|
|
|
|
memset( p, '\0', interact->len );
|
|
|
|
|
|
|
|
} else {
|
2000-07-17 08:56:29 +08:00
|
|
|
use_default:
|
2000-07-18 05:45:18 +08:00
|
|
|
/* input must be empty */
|
2000-07-17 08:56:29 +08:00
|
|
|
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;
|
2000-07-14 06:54:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int lutil_sasl_interact(
|
|
|
|
LDAP *ld,
|
2000-07-18 05:23:59 +08:00
|
|
|
unsigned flags,
|
2000-07-17 08:56:29 +08:00
|
|
|
void *defaults,
|
2000-07-14 06:54:38 +08:00
|
|
|
void *in )
|
|
|
|
{
|
|
|
|
sasl_interact_t *interact = in;
|
|
|
|
|
2000-07-18 05:36:30 +08:00
|
|
|
if( flags == LDAP_SASL_INTERACTIVE ) {
|
2000-07-18 05:23:59 +08:00
|
|
|
fputs( "SASL Interaction\n", stderr );
|
|
|
|
}
|
2000-07-15 09:28:16 +08:00
|
|
|
|
2000-07-14 06:54:38 +08:00
|
|
|
while( interact->id != SASL_CB_LIST_END ) {
|
2000-07-18 05:23:59 +08:00
|
|
|
int rc = interaction( flags, interact, defaults );
|
2000-07-14 06:54:38 +08:00
|
|
|
|
|
|
|
if( rc ) return rc;
|
|
|
|
interact++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
#endif
|