Пользовательский PAM завершается с ошибкой при PAM_CONVERSATION в SSH

#c #linux #ssh #pam

#c #linux #ssh #pam

Вопрос:

Я пытался реализовать пользовательский PAM для проверки 2-го фактора. Пользовательский PAM должен прочитать выбранный коэффициент (целое число) и передать его программе. Приведенный ниже код отлично работает в SUDO и SU, но при попытке использовать SSH я получаю сообщение об ошибке «Соединение закрыто хост-портом 22«. Кто-нибудь может помочь мне разобраться в проблеме.

 static char *request_pass(pam_handle_t *pamh, int echocode,PAM_CONST char *prompt) 
{
    // Query user for verification code
    PAM_CONST struct pam_message msg = { .msg_style = PAM_PROMPT_ECHO_ON,.msg = prompt };
    PAM_CONST struct pam_message *msgs = amp;msg;

    // PAM_CONST struct pam_message msg;
    struct pam_conv conv = {re,NULL};
    struct pam_response *resp = NULL;
    int retval = re(1,amp;msgs,amp;resp,"");
    return "";
}
 
 int re(int nummsg,PAM_CONST struct pam_message **msg,struct pam_response **resp, void *appdata_ptr)
{
    *resp = malloc(sizeof(struct pam_response));
    assert(*resp);
    (*resp)->resp = calloc(1024,1);

    printf("%s^^ ", msg[0]->msg);
    fflush(stdout);
    assert(fgets((*resp)->resp, 1024, stdin));
    char *ret = NULL;
    ret = (*resp)->resp;
   

  // Deallocate temporary storage
    if (*resp) 
    {
        if (!ret) 
        {
            free((*resp)->resp);
        }
        free(*resp);
    }
    factorselect = atoi(ret);
    return PAM_SUCCESS;
}
 

Редактировать: приведенный ниже код сработал для меня (решаемый)

 char *
s_prompt(void *arg, const char *prompt, char *buf, size_t bufsz)
{
    char *p = NULL;

    if (pam_prompt((pam_handle_t *)arg, PAM_PROMPT_ECHO_ON, amp;p,
        "%s", prompt) != PAM_SUCCESS || p == NULL) {
        return (NULL);
    }
    strncpy(buf, p, bufsz);
    free(p);
    return (buf);
}
 

Комментарии:

1. Я давно не использовал PAM, но я почти уверен, что вам не следует обращаться к stdin / stdout, как вы это делаете. Вероятно, вам следует использовать pam_prompt() или использовать pam_conv полученный pam_get_item напрямую. Если только я не понимаю вашу цель полностью, и вы создаете клиент PAM, а не модуль. Возможно, вы захотите взглянуть на существующий модуль PAM, чтобы увидеть пример использования.

2. Спасибо за ответ, pam_prompt() работал для ssh