Esempio n. 1
0
/* 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;
}
Esempio n. 2
0
/* 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;
}