3

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.