Solution was pretty
obvious (of course not for me): Introduction: _plug_make_prompts builds
a sasl_interact_t array, one per prompt, successively exploited by the plug_challenge_prompt
(in a second call of the client_mech_step). As _plug_make_prompts supports
and builds all kinds of prompt entries (user, password, echoprompt, realm) but
noechoprompt it happened that plug_challenge_prompt didn’t find any SASL_CB_NOECHOPROMPT
entry in the prompts array. Solution: By providing a small counterpart
of _plug_make_prompts we build a one-entry array of prompts with a SASL_CB_NOECHOPROMPT
entry. This way plug_challenge_prompt
can find a matching entry for SASL_CB_NOECHOPROMPT. Now PAM_LDAP receives interact->id
== SASL_COB_NOECHOPROMPT and in turn calls misc_conv with PAM_PROMPT_ECHO_OFF. This is how it works now: =============== client mymech
step ================================ if (echo) // such boolean is obtained
by the serverin value (user simple reply / secret reply)
echo_result = _plug_challenge_prompt(params->utils, SASL_CB_ECHOPROMPT, NULL, promptText, (const char**)&text->echoresponse,
prompt_need); else
echo_result = _plug_challenge_prompt(params->utils, SASL_CB_NOECHOPROMPT, NULL, promptText2, (const char**)&text->echoresponse,
prompt_need); if
((echo_result != SASL_OK) && (echo_result != SASL_INTERACT)) return echo_result;
/* free prompts we got */
if (prompt_need
&& *prompt_need) { params->utils->free(*prompt_need); *prompt_need
= NULL;
} /* if there are prompts not filled in */ if (echo_result ==
SASL_INTERACT) { /* make the prompt list */ if (echo)
result =
_plug_make_prompts(params->utils, prompt_need,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, promptText,
NULL,
NULL, NULL, NULL); else result
= my_plug_make_noechoprompt(params->utils,
prompt_need, NULL,
promptText2,
//noecho NULL); if
(result != SASL_OK) return
result; return SASL_INTERACT; } ==================================================================================== Where my_plug_make_noechoprompt is as follows: ==================================================================================== /* * Make the requested noechoed prompt. (prompt==NULL not
allowed) */ int my_plug_make_noechoprompt (const sasl_utils_t *utils,
sasl_interact_t **prompts_res,
const char *echo_chal,
const char *noecho_prompt,
const char *echo_def) {
int num = 1;
int alloc_size;
sasl_interact_t *prompts;
if (noecho_prompt)
num++;
if (num == 1) { SETERROR(
utils, "make_prompts() called with no actual prompts" ); return SASL_FAIL;
}
alloc_size = sizeof(sasl_interact_t)*num;
prompts = utils->malloc(alloc_size);
if (!prompts) { MEMERROR(
utils ); return SASL_NOMEM;
}
memset(prompts, 0, alloc_size);
*prompts_res = prompts;
if (noecho_prompt) { (prompts)->id
= SASL_CB_NOECHOPROMPT; (prompts)->challenge
= echo_chal; (prompts)->prompt
= noecho_prompt; (prompts)->defresult
= echo_def; prompts++;
}
/* add the ending one */
(prompts)->id = SASL_CB_LIST_END;
(prompts)->challenge = NULL;
(prompts)->prompt = NULL;
(prompts)->defresult = NULL;
return SASL_OK; } ==================================================================================== Francesco Da: Francesco Grossi
ITQL [mailto:f.grossi@xxxxxxx] Hello Everybody I need help We are trying to make a new SASL mechanism to enable
ldap authentication via third-party password-validation tool. User Authentication is routed to the tool which might
ask the client for a new password to be keyed in. We succeeded handling all the conversation though in
a unseemly fashion for the new password is echoed (which, of course, is not
welcome by the customer). Our 3 main keys have been: 1) enabling
SSH interaction with ChallengeResponseAuthentication=yes in sshd_config 2) enabling
PAM_LDAP via etc/pam.d/system-auth 3) enabling
the pam_conv routine by the following mechanism code:
echo_result = _plug_challenge_prompt(params->utils, SASL_CB_ECHOPROMPT,
NULL,
promptText,
(const char**)&text->echoresponse,
prompt_need);
if ((echo_result != SASL_OK) && (echo_result !=
SASL_INTERACT))
return echo_result;
/* free prompts we got */
if (prompt_need
&& *prompt_need) {
params->utils->free(*prompt_need);
*prompt_need = NULL;
}
/* if there are
prompts not filled in */
if (echo_result ==
SASL_INTERACT)
{
/* make the prompt list */
result =
_plug_make_prompts(params->utils, prompt_need,
NULL,
NULL,
NULL, NULL,
NULL, NULL,
NULL, promptText,
NULL, NULL, NULL, NULL);
if (result != SASL_OK) return
result;
return SASL_INTERACT;
}
/* the application provided
us with a new password so use it */
if
(text->echoresponse) {
*clientout = text->echoresponse;
*clientoutlen = strlen(text->echoresponse); } Now what we expected was just to turn SASL_CB_ECHOPROMPT to SASL_CB_NOECHOPROMPT to reach our goal The result is the pam_conv routine returns empty
response to sasl and the mech_client_step function keeps being called (looping)
by the glue code. In human terms the client keeps giving his new password
and still in clear (echoprompted) . Do you have any idea on what I’m missing? Is it available any reference about chalprompt_cb function and its
parameters used by
_plug_challenge_prompt? We also tried with _plug_get_password without any
outcome Any help would be appreciated Many many thanks Francesco Grossi |