Аутентифицировать удаленного пользователя в Linux с учетными данными имени пользователя/пароля

Я планирую REST-сервис для собственного решения по управлению жалюзи в новом доме. Служба должна работать на сервере Linux, и, поскольку это действительно должно быть доступно, я хочу сделать это без каких-либо зависимостей во время выполнения, кроме самой ОС и очень небольшого количества стандартных библиотек. Поэтому я бы предпочел сделать это в c.

Пока что я нашел libasyncd, который должен дать мне хороший HTTPS-хост для работы. Теперь меня беспокоит, как обрабатывать аутентификацию. Для простоты подойдет базовая HTTP-аутентификация, но я хотел бы аутентифицироваться в моем системном хранилище пользователей (которое в данный момент является каталогом OpenLDAP). В идеале я хотел бы иметь решение, которое абстрагируется от этого хранилища.

Сначала я подумал, что pam может быть подходящим вариантом, но все примеры, которые я смог найти до сих пор, позволяют pam сделать запрос пароля, и вместо этого мне нужна функция, которая принимает имя пользователя и пароль и сообщает мне, аутентифицирован ли я или нет. Возможно ли это вообще с pam? Если да, то где мне искать документацию? Если нет, не могли бы вы предложить какие-либо альтернативы?


person Community    schedule 22.09.2015    source источник
comment
Я бы подумал, что pam это именно то, что нужно. Но вы должны быть более конкретными. Вы знаете правила сайта.   -  person too honest for this site    schedule 22.09.2015
comment
@ Олаф, ну, это мой частный сайт, я все равно хочу оставаться общим. Из базового заголовка Authenticate я получаю имя пользователя и пароль, и я просто не нашел никакой документации/примера (ищу уже несколько дней), как я могу позволить pam проверить их (вместо того, чтобы просто дать pam имя пользователя и аутентификация самого пользователя на консоли)   -  person    schedule 22.09.2015
comment
@Olaf, спасибо, что заверили, что pam действительно это правильный путь. Наконец-то я понял, как использовать его в своих целях.   -  person    schedule 23.09.2015
comment
Неплохо, ведь я только 10 лет назад прочитал журнальную статью о PAM. Если я когда-нибудь столкнусь с той же проблемой, я буду знать, к кому обратиться ;-)   -  person too honest for this site    schedule 23.09.2015
comment
@Olaf Да, для меня то же самое, и я сначала не был уверен, что не нашел ни одного примера проверки пароля без интерактивной подсказки. Теперь я разместил свой тестовый код здесь в качестве ответа для дальнейшего использования.   -  person    schedule 23.09.2015


Ответы (1)


После продолжения моих исследований у меня наконец-то появился рабочий пример кода, дающий мне только проверку пользователя/пароля с помощью pam я искал. Я размещаю его здесь как ответ для справки.

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <security/pam_appl.h>

static int pamconv(int num_msg, const struct pam_message **msg,
        struct pam_response **resp, void *appdata_ptr)
{
    char *pass = malloc(strlen(appdata_ptr)+1);
    strcpy(pass, appdata_ptr);

    int i;

    *resp = calloc(num_msg, sizeof(struct pam_response));

    for (i = 0; i < num_msg; ++i)
    {
        /* Ignore all PAM messages except prompting for hidden input */
        if (msg[i]->msg_style != PAM_PROMPT_ECHO_OFF)
            continue;

        /* Assume PAM is only prompting for the password as hidden input */
        resp[i]->resp = pass;
    }

    return PAM_SUCCESS;
}

bool checkAuthentication(const char *user, const char *pass)
{
    /* use own PAM conversation function just responding with the
       password passed here */
    struct pam_conv conv = { &pamconv, (void *)pass };

    pam_handle_t *handle;
    int authResult;

    pam_start("shutterd", user, &conv, &handle);
    authResult = pam_authenticate(handle,
            PAM_SILENT|PAM_DISALLOW_NULL_AUTHTOK);
    pam_end(handle, authResult);

    return (authResult == PAM_SUCCESS);
}

Конечно, проверка на ошибки должна быть добавлена ​​везде для качества производства.

person Community    schedule 23.09.2015