diff --git a/SSH/PAM/rublon.config b/SSH/PAM/rublon.config index b9fe17d..4fa6dba 100644 --- a/SSH/PAM/rublon.config +++ b/SSH/PAM/rublon.config @@ -1,5 +1,6 @@ systemToken= secretKey= -userDomain= +userDomain=astec.net rublonApiServer=https://core.rublon.net -failmode=safe \ No newline at end of file +failmode=safe +prompt=1 \ No newline at end of file diff --git a/SSH/PAM/rublonPam.c b/SSH/PAM/rublonPam.c index 8bf7517..af7361f 100644 --- a/SSH/PAM/rublonPam.c +++ b/SSH/PAM/rublonPam.c @@ -7,6 +7,16 @@ #include #include +int getPromptCnt() { + char *promptConfig = getConfigValue("prompt"); + if (promptConfig == NULL) + return 1; + int prompt = atoi(promptConfig); + if (prompt < 1 || prompt > 3) + return 1; + return prompt; +} + PAM_EXTERN int pam_sm_setcred( pam_handle_t *pamh, int flags, int argc, const char **argv ) { return PAM_SUCCESS; } @@ -17,25 +27,35 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const c PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, const char **argv ) { - int access = startRublon(pamh); - - if(access == STATUS_BYPASS){ +int promptCnt = 1; +int promptConfig = getPromptCnt(); +int access = NULL; +while(1) { + access = startRublon(pamh); + + if(access == STATUS_BYPASS) { pam_prompt(pamh, PAM_TEXT_INFO, NULL, "User bypassed."); return PAM_SUCCESS; } - if(access == STATUS_DENIED){ - pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Access denied!"); - return PAM_MAXTRIES; + if(access == STATUS_DENIED) { + if(promptConfig == promptCnt) { + pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, NULL, "Access denied!"); + return PAM_MAXTRIES; + } + pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, NULL, "Access denied! Press [Enter] to try again."); } - if(access == STATUS_PENDING){ + if(access == STATUS_PENDING) { pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Status pending...!"); return PAM_SUCCESS; } - if(access == CONNECTION_ERROR){ - pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Connection error."); - return PAM_MAXTRIES; + if(access == CONNECTION_ERROR) { + if(promptConfig == promptCnt) { + pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Connection error."); + return PAM_MAXTRIES; + } + pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, NULL, "Connection error. Press [Enter] to try again."); } - if(access == STATUS_UNKNOWN){ + if(access == STATUS_UNKNOWN) { pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Connection error : status unknown."); return PAM_MAXTRIES; } @@ -43,6 +63,7 @@ PAM_EXTERN int pam_sm_authenticate( pam_handle_t *pamh, int flags,int argc, cons pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Access confirmed by Rublon 2FA!"); return PAM_SUCCESS; } - - return PAM_MAXTRIES; + promptCnt++; +} +return PAM_MAXTRIES; } \ No newline at end of file diff --git a/SSH/PAM/src/coreHandler.c b/SSH/PAM/src/coreHandler.c index 790bfc1..7ca35b8 100644 --- a/SSH/PAM/src/coreHandler.c +++ b/SSH/PAM/src/coreHandler.c @@ -403,8 +403,10 @@ int postConfirmCode(pam_handle_t *pamh, char *secretKey, char *systemToken, char bool firstAttempt = true; do { - if(!firstAttempt) - pam_prompt(pamh, PAM_TEXT_INFO, NULL, "Invalid passcode. Try again!"); + if(!firstAttempt) { + pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, NULL, "Invalid passcode!"); + return STATUS_DENIED; + } firstAttempt = false; if(onlyOneMethod) pam_prompt(pamh, PAM_TEXT_INFO, NULL, "\nEnter passcode"); diff --git a/SSH/PAM/src/pamApp.c b/SSH/PAM/src/pamApp.c index 61a2ac6..1eb66cc 100644 --- a/SSH/PAM/src/pamApp.c +++ b/SSH/PAM/src/pamApp.c @@ -134,7 +134,7 @@ int startRublon(pam_handle_t *pamh) { if(cJSON_GetArraySize(availableMethods) < 1) { areMobileAppMethodsAvailable(methods, pamh, userEmail); - pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, NULL, "No authentication methods available"); + pam_prompt(pamh, PAM_TEXT_INFO, NULL, "No authentication methods available"); return STATUS_DENIED; }