最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - How to implement a PAM module with MFA support - Stack Overflow

programmeradmin7浏览0评论

I am writing a PAM module which will contact a https service to validate user. For the time being, the actual part is not started yet, I am just writing a toy to understand PAM and verify the whole process. Here is the function:

static const char *valid_username = "xrfang";
static const char *valid_password = "password";
static const char *valid_otpcode = "123456";

PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
    const char *username;
    char *password = NULL;
    char *otpcode = NULL;
    int rc = PAM_AUTH_ERR;
    openlog("pam_ums", LOG_PID | LOG_CONS, LOG_AUTH);

    if (pam_get_user(pamh, &username, NULL) != PAM_SUCCESS) {
        syslog(LOG_ALERT, "Failed to get username");
        goto done;
    }
    syslog(LOG_ALERT, "username:>%s<", username);

    if (pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &password, "Password: ") != PAM_SUCCESS) {
        syslog(LOG_ALERT, "Failed to get password");
        goto done;
    }
    syslog(LOG_ALERT, "password:>%s<", password);

    if (pam_prompt(pamh, PAM_PROMPT_ECHO_ON, &otpcode, "OTP Code: ") != PAM_SUCCESS) {
        syslog(LOG_ALERT, "Failed to get otp code");
        goto done;
    }
    syslog(LOG_ALERT, "otpcode:>%s<", otpcode);

    if (strcmp(username, valid_username) != 0) {
        syslog(LOG_ALERT, "invalid username: given=%s; wanted=%s;", username, valid_username);
        goto done;
    }
    if (strcmp(password, valid_password) != 0) {
        syslog(LOG_ALERT, "invalid password: given=%s; wanted=%s;", password, valid_password);
        goto done;
    }
    if (strcmp(otpcode, valid_otpcode) != 0) {
        syslog(LOG_ALERT, "invalid otpcode: given=%s; wanted=%s;", otpcode, valid_otpcode);
        goto done;
    }
    rc = PAM_SUCCESS;
    syslog(LOG_ALERT, "Authentication successful");
done:
    closelog();
    if (password) free(password);
    if (otpcode) free(otpcode);
    return rc;
}

I then install this module for sshd (/etc/pam.d/sshd):

# PAM configuration for the Secure Shell service

auth sufficient pam_ums.so

The problem is, if without the prompt for OTP code, it works fine, after adding the second prompt for otp, it failed. SSHD does not popup the prompt for otp code. log shows:

Feb  5 17:49:15 office pam_ums[1145092]: username:>xrfang<
Feb  5 17:49:15 office pam_ums[1145092]: password:>password<
Feb  5 17:49:15 office pam_ums[1145092]: pam_ums(sshd:auth): conversation failed
Feb  5 17:49:15 office pam_ums[1145092]: Failed to get otp code
Feb  5 17:49:15 office sshd[1145092]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.93.200  user=xrfang
Feb  5 17:49:17 office sshd[1145092]: Failed password for xrfang from 192.168.93.200 port 47670 ssh2

How to let sshd (or the pam framework?) to allow multiple credentials? Note that this is an integrated part of the http service I have. I do not want to use two pam modules for this (just like the google authenticator module).

发布评论

评论列表(0)

  1. 暂无评论