R: how to avoid echo prompt with SSH-PAM conv routine?

Francesco Grossi ITQL f.grossi at itql.it
Tue Dec 23 03:33:25 EST 2008


 

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 at itql.it] 
Inviato: 18 December 2008 19:37
A: 'cyrus-sasl at lists.andrew.cmu.edu'
Oggetto: how to avoid echo prompt with SSH-PAM conv routine?

 

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

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.andrew.cmu.edu/pipermail/cyrus-sasl/attachments/20081223/cdf29c19/attachment-0001.html 


More information about the Cyrus-sasl mailing list