/* expected hook, this is where custom stuff happens */ PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char **argv) { int ret = 0; const char *pUsername = NULL; const char *pAccountId = NULL; const char *pOperation = NULL; const char *pSecretKey = NULL; const char *pAppId = NULL; const char *pOperationId = NULL; const char *pAccounts = NULL; const char *pConfig = NULL; const char *pOtp = NULL; const char *pHost = NULL; const char *pTimeout = NULL; char *pDefaultOption = NULL; char *buffer; int timeout = 2; int default_option = PAM_SUCCESS; int res = PAM_SUCCESS; char *otp = NULL; struct pam_message msg[1],*pmsg[1]; struct pam_response *resp; // setting up conversation call prompting for one-time code pmsg[0] = &msg[0] ; msg[0].msg_style = PAM_PROMPT_ECHO_ON ; msg[0].msg = "One-time code: " ; resp = NULL ; if (pam_get_user(pamh, &pUsername, NULL) != PAM_SUCCESS) { return PAM_AUTH_ERR; } pAccounts = getArg("accounts", argc, argv); if (!pAccounts) { pAccounts = DEFAULT_LATCH_ACCOUNTS_FILE; } pAccountId = getAccountId(pUsername, pAccounts); if (pAccountId == NULL) { return PAM_SUCCESS; } pConfig = getArg("config", argc, argv); if (!pConfig) { pConfig = DEFAULT_LATCH_CONFIG_FILE; } pOperation = getArg("operation", argc, argv); if (!pOperation) { pOperationId = NULL; } else { pOperationId = getConfig(OPERATION_ID_LENGTH, pOperation, pConfig); if (pOperationId == NULL) { send_syslog_alert("PAM", "Latch-auth-pam error: Failed to find operation"); perror("Failed to find operation"); return PAM_SUCCESS; } } pOtp = getArg("otp", argc, argv); if (!pOtp) { pOtp = "no"; } pDefaultOption = (char *)getConfig(DEFAULT_OPTION_MAX_LENGTH, "action", pConfig); if (pDefaultOption == NULL) { pDefaultOption = malloc(4 + 1); memset(pDefaultOption, 0, 4 + 1); strncpy(pDefaultOption, "open", 4); } else if (strcmp(pDefaultOption,"open") != 0 && strcmp(pDefaultOption,"close") != 0){ pDefaultOption = realloc(pDefaultOption, 4 + 1); memset(pDefaultOption, 0, 4 + 1); strncpy(pDefaultOption, "open", 4); } if (strcmp(pDefaultOption,"open") == 0) { default_option = PAM_SUCCESS; } else { default_option = PAM_AUTH_ERR; } free(pDefaultOption); pAppId = getConfig(APP_ID_LENGTH, "app_id", pConfig); pSecretKey = getConfig(SECRET_KEY_LENGTH, "secret_key", pConfig); if(pAppId == NULL || pSecretKey == NULL || strcmp(pAppId, "") == 0 || strcmp(pSecretKey, "") == 0){ send_syslog_alert("PAM", "Latch-auth-pam error: Failed to read \"latch.conf\""); perror("Failed to read \"latch.conf\""); free((char*)pAccountId); free((char*)pOperationId); return PAM_SUCCESS; } pHost = getConfig(MAX_SIZE, "latch_host", pConfig); if(pHost == NULL) { pHost = malloc(LATCH_API_HOST_LENGTH + 1); memset((char*)pHost, 0, LATCH_API_HOST_LENGTH + 1); strncpy((char*)pHost, LATCH_API_HOST, LATCH_API_HOST_LENGTH); } pTimeout = getConfig(TIMEOUT_MAX_LENGTH, "timeout", pConfig); if(pTimeout == NULL || ((timeout = atoi(pTimeout)) < TIMEOUT_MIN) || timeout > TIMEOUT_MAX) { timeout = 2; } free((char*)pTimeout); if (drop_privileges(0)) { send_syslog_alert("PAM", "Latch-auth-pam error: Couldn't drop privileges"); } init(pAppId, pSecretKey); setHost(pHost); setTimeout(timeout); if (pOperationId != NULL) { buffer = operationStatus(pAccountId, pOperationId); } else { buffer = status(pAccountId); } free((char*)pAppId); free((char*)pSecretKey); free((char*)pAccountId); free((char*)pOperationId); free((char*)pHost); if (restore_privileges()) { send_syslog_alert("PAM", "Latch-auth-pam error: Couldn't restore privileges"); } if(buffer == NULL || strcmp(buffer,"") == 0){ free(buffer); return default_option; } if (strstr(buffer, "\"status\":\"off\"") != NULL){ fprintf (stderr, "AUTH-PAM: latch locked\n"); send_syslog_alert("PAM", "Latch-auth-pam warning: Someone tried to access. Latch locked"); res = PAM_AUTH_ERR; }else if (strstr(buffer, "\"status\":\"on\"") != NULL) { if(strncmp(pOtp, "yes", 3) == 0){ char *pch; if((pch = strstr(buffer, "\"two_factor\"")) != NULL){ char code[OTP_LENGTH]; memset(code, 0, OTP_LENGTH); strncpy (code, pch + strlen("\"two_factor\":{\"token\":\""), OTP_LENGTH); otp = get_response(pamh, "One-time password", 1); // comparing user input with known code if(strncmp(code, otp, OTP_LENGTH) != 0 || strlen(otp) != OTP_LENGTH){ send_syslog_alert("PAM", "Latch-auth-pam warning: Someone tried to access. Bad OTP"); res = PAM_AUTH_ERR; } else { res = PAM_SUCCESS; } } }else{ res = PAM_SUCCESS; } } free(buffer); return res; }
/* expected hook, this is where custom stuff happens */ PAM_EXTERN int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char **argv) { //int ret = 0; const char* pUsername = NULL; const char* pAccountId = NULL; const char* pSecretKey = NULL; const char* pAppId = NULL; const char* pAccounts = NULL; const char* pConfig = NULL; char *buffer; /* struct pam_message msg[1],*pmsg[1]; struct pam_response *resp; // setting up conversation call prompting for one-time code pmsg[0] = &msg[0] ; msg[0].msg_style = PAM_PROMPT_ECHO_ON ; msg[0].msg = "One-time code: " ; resp = NULL ; */ if (pam_get_user(pamh, &pUsername, NULL) != PAM_SUCCESS) { return PAM_AUTH_ERR; } pAccounts = getArg("accounts", argc, argv); if (!pAccounts) { return PAM_AUTH_ERR; } pConfig = getArg("config", argc, argv); if (!pConfig) { return PAM_AUTH_ERR; } pAccountId = getAccountId(pUsername, pAccounts); if (pAccountId == NULL) { return PAM_SUCCESS; } pAppId = getConfig("app_id", pConfig); pSecretKey = getConfig("secret_key", pConfig); if(pAppId == NULL || pSecretKey == NULL){ perror("Failed to read \"latch.conf\""); return PAM_AUTH_ERR; } if(strcmp(pAppId,"") == 0 || strcmp(pSecretKey,"") == 0){ perror("Failed to read \"latch.conf\""); return PAM_AUTH_ERR; } init(pAppId, pSecretKey); setHost("https://latch.elevenpaths.com"); buffer = status(pAccountId); if(buffer == NULL || strcmp(buffer,"") == 0) return PAM_SUCCESS; if (strstr(buffer, "\"status\":\"off\"") != NULL){ fprintf (stderr, "AUTH-PAM: latch locked\n"); send_syslog_alert(); return PAM_AUTH_ERR; } /* if (strstr(buffer, "\"status\":\"on\"") != NULL) { char *pch; if((pch = strstr(buffer, "\"two_factor\"")) != NULL){ char code[6] ; char *input; strncpy (code, pch + strlen("\"two_factor\":{\"token\":\""), 6); if( (ret = converse(pamh, 1 , pmsg, &resp)) != PAM_SUCCESS ) { // if this function fails, make sure that ChallengeResponseAuthentication in sshd_config is set to yes return ret ; } // retrieving user input if( resp ) { if( (flags & PAM_DISALLOW_NULL_AUTHTOK) && resp[0].resp == NULL ) { free( resp ); return PAM_AUTH_ERR; } input = resp[ 0 ].resp; resp[ 0 ].resp = NULL; } else { return PAM_CONV_ERR; } // comparing user input with known code if(strncmp(code,input,6) != 0){ free( input ) ; return PAM_AUTH_ERR; } free( input ) ; } } */ //printf("buffer response from status call -> %s\n",buffer); return PAM_SUCCESS; }