コード例 #1
0
ファイル: test.c プロジェクト: naviprojects/drop_privileges
int main(){

  printf("Efective user: %s\n", get_effective_user_name());
  printf("Real user: %s\n", get_user_name());
  printf("\n");

  printf("drop_privs temp\n");
  int ret1 = drop_privileges(0); 
  printf("Efective user: %s\n", get_effective_user_name());
  printf("Real user: %s\n", get_user_name());
  printf("\n");

  printf("restore privs\n");
  int ret2 = restore_privileges();
  printf("Efective user: %s\n", get_effective_user_name());
  printf("Real user: %s\n", get_user_name());
  printf("\n");

  printf("drop_privs definitive\n");
  int ret3 = drop_privileges(1); 
  printf("Efective user: %s\n", get_effective_user_name());
  printf("Real user: %s\n", get_user_name());
  printf("\n");

  printf("restore privs\n");
  int ret4 = restore_privileges();
  printf("Efective user: %s\n", get_effective_user_name());
  printf("Real user: %s\n", get_user_name());
  printf("\n");

  printf("return values: %d, %d, %d, %d\n", ret1, ret2, ret3, ret4);

  return 0;
}
コード例 #2
0
int mqtt3_log_init(struct mqtt3_config *config)
{
	int rc = 0;

	log_priorities = config->log_type;
	log_destinations = config->log_dest;

	if(log_destinations & MQTT3_LOG_SYSLOG){
#ifndef WIN32
		openlog("mosquitto", LOG_PID|LOG_CONS, config->log_facility);
#else
		syslog_h = OpenEventLog(NULL, "mosquitto");
#endif
	}

	if(log_destinations & MQTT3_LOG_FILE){
		if(drop_privileges(config, true)){
			return 1;
		}
		config->log_fptr = _mosquitto_fopen(config->log_file, "at");
		if(!config->log_fptr){
			log_destinations = MQTT3_LOG_STDERR;
			log_priorities = MOSQ_LOG_ERR;
			_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Error: Unable to open log file %s for writing.", config->log_file);
			return MOSQ_ERR_INVAL;
		}
		restore_privileges();
	}
	return rc;
}
コード例 #3
0
ファイル: pam_yubico.c プロジェクト: JKDingwall/yubico-pam
/*
 * Authorize authenticated OTP_ID for login as USERNAME using
 * AUTHFILE.  Return 0 on failures, otherwise success.
 */
static int
authorize_user_token (struct cfg *cfg,
                      const char *username,
                      const char *otp_id,
                      pam_handle_t *pamh)
{
    int retval;

    if (cfg->auth_file)
    {
        /* Administrator had configured the file and specified is name
           as an argument for this module.
         */
        DBG (("Using system-wide auth_file %s", cfg->auth_file));
        retval = check_user_token (cfg, cfg->auth_file, username, otp_id);
    }
    else
    {
        char *userfile = NULL;
        struct passwd *p;

        p = getpwnam (username);
        if (p == NULL) {
            DBG (("getpwnam: %s", strerror(errno)));
            return 0;
        }

        /* Getting file from user home directory
           ..... i.e. ~/.yubico/authorized_yubikeys
         */
        if (! get_user_cfgfile_path (NULL, "authorized_yubikeys", username, &userfile)) {
            D (("Failed figuring out per-user cfgfile"));
            return 0;
        }

        DBG (("Dropping privileges"));

        if (drop_privileges(p, pamh) < 0) {
            D (("could not drop privileges"));
            return 0;
        }

        retval = check_user_token (cfg, userfile, username, otp_id);

        if (restore_privileges(pamh) < 0)
        {
            DBG (("could not restore privileges"));
            return 0;
        }

        free (userfile);
    }

    return retval;
}
コード例 #4
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;
}
コード例 #5
0
ファイル: pam_yubico.c プロジェクト: JKDingwall/yubico-pam
static int
do_challenge_response(pam_handle_t *pamh, struct cfg *cfg, const char *username)
{
    char *userfile = NULL, *tmpfile = NULL;
    FILE *f = NULL;
    char buf[CR_RESPONSE_SIZE + 16], response_hex[CR_RESPONSE_SIZE * 2 + 1];
    int ret, fd;

    unsigned int flags = 0;
    unsigned int response_len = 0;
    YK_KEY *yk = NULL;
    CR_STATE state;

    char *errstr = NULL;

    struct passwd *p;
    struct stat st;

    ret = PAM_AUTH_ERR;
    flags |= YK_FLAG_MAYBLOCK;

    if (! init_yubikey(&yk)) {
        D(("Failed initializing YubiKey"));
        goto out;
    }

    if (! check_firmware_version(yk, false, true)) {
        D(("YubiKey does not support Challenge-Response (version 2.2 required)"));
        goto out;
    }


    if (! get_user_challenge_file (yk, cfg->chalresp_path, username, &userfile)) {
        D(("Failed getting user challenge file for user %s", username));
        goto out;
    }

    DBG(("Loading challenge from file %s", userfile));

    p = getpwnam (username);
    if (p == NULL) {
        DBG (("getpwnam: %s", strerror(errno)));
        goto out;
    }

    /* Drop privileges before opening user file. */
    if (drop_privileges(p, pamh) < 0) {
        D (("could not drop privileges"));
        goto out;
    }

    fd = open(userfile, O_RDONLY, 0);
    if (fd < 0) {
        DBG (("Cannot open file: %s (%s)", userfile, strerror(errno)));
        goto out;
    }

    if (fstat(fd, &st) < 0) {
        DBG (("Cannot stat file: %s (%s)", userfile, strerror(errno)));
        close(fd);
        goto out;
    }

    if (!S_ISREG(st.st_mode)) {
        DBG (("%s is not a regular file", userfile));
        close(fd);
        goto out;
    }

    f = fdopen(fd, "r");
    if (f == NULL) {
        DBG (("fdopen: %s", strerror(errno)));
        close(fd);
        goto out;
    }

    if (! load_chalresp_state(f, &state, cfg->debug))
        goto out;

    if (fclose(f) < 0) {
        f = NULL;
        goto out;
    }
    f = NULL;

    if (restore_privileges(pamh) < 0) {
        DBG (("could not restore privileges"));
        goto out;
    }

    if (! challenge_response(yk, state.slot, state.challenge, state.challenge_len,
                             true, flags, false,
                             buf, sizeof(buf), &response_len)) {
        D(("Challenge-response FAILED"));
        goto out;
    }

    /*
     * Check YubiKey response against the expected response
     */

    yubikey_hex_encode(response_hex, buf, response_len);

    if (memcmp(buf, state.response, response_len) == 0) {
        ret = PAM_SUCCESS;
    } else {
        D(("Unexpected C/R response : %s", response_hex));
        goto out;
    }

    DBG(("Got the expected response, generating new challenge (%i bytes).", CR_CHALLENGE_SIZE));

    errstr = "Error generating new challenge, please check syslog or contact your system administrator";
    if (generate_random(state.challenge, sizeof(state.challenge))) {
        D(("Failed generating new challenge!"));
        goto out;
    }

    errstr = "Error communicating with Yubikey, please check syslog or contact your system administrator";
    if (! challenge_response(yk, state.slot, state.challenge, CR_CHALLENGE_SIZE,
                             true, flags, false,
                             buf, sizeof(buf), &response_len)) {
        D(("Second challenge-response FAILED"));
        goto out;
    }

    /* the yk_* functions leave 'junk' in errno */
    errno = 0;

    /*
     * Write the challenge and response we will expect the next time to the state file.
     */
    if (response_len > sizeof(state.response)) {
        D(("Got too long response ??? (%u/%lu)", response_len, (unsigned long) sizeof(state.response)));
        goto out;
    }
    memcpy (state.response, buf, response_len);
    state.response_len = response_len;

    /* Drop privileges before creating new challenge file. */
    if (drop_privileges(p, pamh) < 0) {
        D (("could not drop privileges"));
        goto out;
    }

    /* Write out the new file */
    tmpfile = malloc(strlen(userfile) + 1 + 4);
    if (! tmpfile)
        goto out;
    strcpy(tmpfile, userfile);
    strcat(tmpfile, ".tmp");

    f = fopen(tmpfile, "w");
    if (! f)
        goto out;

    errstr = "Error updating Yubikey challenge, please check syslog or contact your system administrator";
    if (! write_chalresp_state (f, &state))
        goto out;
    if (fclose(f) < 0) {
        f = NULL;
        goto out;
    }
    f = NULL;
    if (rename(tmpfile, userfile) < 0) {
        goto out;
    }

    if (restore_privileges(pamh) < 0) {
        DBG (("could not restore privileges"));
        goto out;
    }

    DBG(("Challenge-response success!"));
    errstr = NULL;
    errno = 0;

out:
    if (yk_errno) {
        if (yk_errno == YK_EUSBERR) {
            syslog(LOG_ERR, "USB error: %s", yk_usb_strerror());
            D(("USB error: %s", yk_usb_strerror()));
        } else {
            syslog(LOG_ERR, "Yubikey core error: %s", yk_strerror(yk_errno));
            D(("Yubikey core error: %s", yk_strerror(yk_errno)));
        }
    }

    if (errstr)
        display_error(pamh, errstr);

    if (errno) {
        syslog(LOG_ERR, "Challenge response failed: %s", strerror(errno));
        D(("Challenge response failed: %s", strerror(errno)));
    }

    if (yk)
        yk_close_key(yk);
    yk_release();

    if (f)
        fclose(f);

    free(userfile);
    free(tmpfile);
    return ret;
}
コード例 #6
0
void test_drop_privileges()
{
    char *e_user_name_initial = get_effective_user_name();
    char *r_user_name_initial = get_user_name();

    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name_initial);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name_initial);

    // drop_privs temp
    int response1 = drop_privileges(0);
    char *e_user_name1 = get_effective_user_name();
    char *r_user_name1 = get_user_name();

    CU_ASSERT_FALSE(response1);
    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name1);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name1);
    CU_ASSERT_STRING_EQUAL(r_user_name1, e_user_name1);

    // drop_privs temp again
    int response2 = drop_privileges(0);
    char *e_user_name2 = get_effective_user_name();
    char *r_user_name2 = get_user_name();

    CU_ASSERT_FALSE(response2);
    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name2);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name2);
    CU_ASSERT_STRING_EQUAL(r_user_name2, e_user_name2);

    // restore privs
    int response3 = restore_privileges();
    char *e_user_name3 = get_effective_user_name();
    char *r_user_name3 = get_user_name();

    CU_ASSERT_FALSE(response3);
    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name3);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name3);
    CU_ASSERT_STRING_EQUAL(e_user_name_initial, e_user_name3);

    // drop_privs definitely
    int response4 = drop_privileges(1);
    char *e_user_name4 = get_effective_user_name();
    char *r_user_name4 = get_user_name();

    CU_ASSERT_FALSE(response4);
    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name4);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name4);
    CU_ASSERT_STRING_EQUAL(r_user_name4, e_user_name4);

    // restore privs
    int response5 = restore_privileges();
    char *e_user_name5 = get_effective_user_name();
    char *r_user_name5 = get_user_name();

    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name5);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name5);
    CU_ASSERT_STRING_EQUAL(r_user_name5, e_user_name5);

    // drop_privs temp (being dropped definitely)
    int response6 = drop_privileges(0);
    char *e_user_name6 = get_effective_user_name();
    char *r_user_name6 = get_user_name();

    CU_ASSERT_FALSE(response6);
    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name6);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name6);
    CU_ASSERT_STRING_EQUAL(r_user_name6, e_user_name6);

    // drop_privs definitely again
    int response7 = drop_privileges(1);
    char *e_user_name7 = get_effective_user_name();
    char *r_user_name7 = get_user_name();

    CU_ASSERT_FALSE(response7);
    CU_ASSERT_PTR_NOT_NULL_FATAL(e_user_name7);
    CU_ASSERT_PTR_NOT_NULL_FATAL(r_user_name7);
    CU_ASSERT_STRING_EQUAL(r_user_name7, e_user_name7);
}