static void
_rs_rekey(unsigned char *dat, size_t datlen)
{
#ifndef KEYSTREAM_ONLY
    pure_memzero(rs_buf, RSBUFSZ);
#endif
    /* fill rs_buf with the keystream */
    chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ);
    /* mix in optional user provided data */
    if (dat != NULL) {
        size_t i, m;

        if (datlen < KEYSZ + IVSZ) {
            m = datlen;
        } else {
            m = KEYSZ + IVSZ;
        }
        for (i = 0; i < m; i++) {
            rs_buf[i] ^= dat[i];
        }
    }
    /* immediately reinit for backtracking resistance */
    _rs_init(rs_buf, KEYSZ + IVSZ);
    pure_memzero(rs_buf, KEYSZ + IVSZ);
    rs_have = RSBUFSZ - KEYSZ - IVSZ;
}
static void
_rs_stir(void)
{
    unsigned char rnd[KEYSZ + IVSZ];

    if (!rs_initialized) {
        random_data_source_fd = _rs_random_dev_open();
    }
    if (random_data_source_fd != -1) {
        safe_read(random_data_source_fd, rnd, sizeof rnd);
    } else {
#ifdef HAVE_RANDOM_DEV
        _exit(1);
#else
        size_t i = (size_t) 0U;
# ifdef HAVE_ARC4RANDOM
        crypto_uint4 r;
        do {
            r = arc4random();
            memcpy(&rnd[i], &r, (size_t) 4U);
            i += (size_t) 4U;
        } while (i < sizeof(rnd));
# elif defined(HAVE_RANDOM)
        unsigned short r;
        do {
            r = (unsigned short) random();
            rnd[i++] = r & 0xFF;
            rnd[i++] = (r << 8) & 0xFF;
        } while (i < sizeof(rnd));
# else
        unsigned char r;
        do {
            r = (unsigned char) rand();
            rnd[i++] = r;
        } while (i < sizeof(rnd));
# endif
#endif
    }
    if (!rs_initialized) {
        rs_initialized = 1;
        _rs_init(rnd, sizeof rnd);
    } else {
        _rs_rekey(rnd, sizeof rnd);
    }
    pure_memzero(rnd, sizeof rnd);

    /* invalidate rs_buf */
    rs_have = 0;
    pure_memzero(rs_buf, RSBUFSZ);

    rs_count = 1600000;
}
Esempio n. 3
0
static char *do_get_passwd(void)
{
    static char pwd[LINE_MAX];
    char pwd2[LINE_MAX];
    int tries = MAX_PASSWD_CHANGE_TRIES;

    *pwd = 0;
    *pwd2 = 0;

    again:
    printf("Password: "******"\nEnter it again: ");
    fflush(stdout);
    disable_echo();
    if (fgets(pwd2, (int) (sizeof pwd2 - 1U), stdin) == NULL) {
        enable_echo();
        return NULL;
    }
    strip_lf(pwd2);
    puts("");
    if (strcmp(pwd, pwd2) != 0) {
        if (*pwd2 != 0) {
            pure_memzero(pwd2, strlen(pwd2));
        }
        if (*pwd != 0) {
            pure_memzero(pwd, strlen(pwd));
        }
        puts("You didn't enter the same password");
        if (--tries > 0) {
            goto again;
        }
        enable_echo();

        return NULL;
    }
    if (*pwd2 != 0) {
        pure_memzero(pwd2, strlen(pwd2));
    }
    enable_echo();

    return pwd;
}
static void
_rs_random_buf(void *_buf, size_t n)
{
    unsigned char *buf = (unsigned char *)_buf;
    size_t m;

    _rs_stir_if_needed(n);
    while (n > 0) {
        if (rs_have > 0) {
            if (n < rs_have) {
                m = n;
            } else {
                m = rs_have;
            }
            memcpy(buf, rs_buf + RSBUFSZ - rs_have, m);
            pure_memzero(rs_buf + RSBUFSZ - rs_have, m);
            buf += m;
            n -= m;
            rs_have -= m;
        }
        if (rs_have == 0) {
            _rs_rekey(NULL, 0);
        }
    }
}
static inline void
_rs_random_u32(crypto_uint4 *val)
{
    _rs_stir_if_needed(sizeof(*val));
    if (rs_have < sizeof(*val)) {
        _rs_rekey(NULL, 0);
    }
    memcpy(val, rs_buf + RSBUFSZ - rs_have, sizeof(*val));
    pure_memzero(rs_buf + RSBUFSZ - rs_have, sizeof(*val));
    rs_have -= sizeof(*val);
}
Esempio n. 6
0
static int do_usermod(const char * const file,
                      const PWInfo *pwinfo,
                      const unsigned long max_concurrent_logins,
                      const unsigned long long max_auth_memory)
{
    char *file2;
    FILE *fp2;
    PWInfo fetched_info;
    static char line[LINE_MAX];

    if (pwinfo->login == NULL || *(pwinfo->login) == 0) {
        fprintf(stderr, "Missing login\n");
        return PW_ERROR_MISSING_LOGIN;
    }
    if (file == NULL) {
        fprintf(stderr, "Missing passwd file\n");
        return PW_ERROR_MISSING_PASSWD_FILE;
    }
    if (fetch_pw_account(file, &fetched_info, line, sizeof line,
                         pwinfo->login) != 0) {
        fprintf(stderr, "Unable to fetch info about user [%s] in file [%s]\n",
                pwinfo->login, file);
        return PW_ERROR_UNABLE_TO_FETCH;
    }
    if (pwinfo->pwd != NULL) {
        char *cleartext = pwinfo->pwd;

        fetched_info.pwd = best_crypt(cleartext,
                                      max_concurrent_logins, max_auth_memory);
        if (*cleartext != 0) {
            pure_memzero(cleartext, strlen(cleartext));
        }
    }
    if (pwinfo->uid > (uid_t) 0) {
        fetched_info.uid = pwinfo->uid;
    }
    if (pwinfo->gid > (gid_t) 0) {
        fetched_info.gid = pwinfo->gid;
    }
    if (pwinfo->home != NULL) {
        fetched_info.home = pwinfo->home;
    }
    if (pwinfo->gecos != NULL) {
        fetched_info.gecos = pwinfo->gecos;
    }
    if (pwinfo->has_bw_dl != 0) {
        if (pwinfo->has_bw_dl < 0) {
            fetched_info.has_bw_dl = 0;
        } else {
            fetched_info.has_bw_dl = pwinfo->has_bw_dl;
            fetched_info.bw_dl = pwinfo->bw_dl;
        }
    }
    if (pwinfo->has_bw_ul != 0) {
        if (pwinfo->has_bw_ul < 0) {
            fetched_info.has_bw_ul = 0;
        } else {
            fetched_info.has_bw_ul = pwinfo->has_bw_ul;
            fetched_info.bw_ul = pwinfo->bw_ul;
        }
    }
    if (pwinfo->has_quota_files != 0) {
        if (pwinfo->has_quota_files < 0) {
            fetched_info.has_quota_files = 0;
        } else {
            fetched_info.has_quota_files = pwinfo->has_quota_files;
            fetched_info.quota_files = pwinfo->quota_files;
        }
    }
    if (pwinfo->has_quota_size != 0) {
        if (pwinfo->has_quota_size < 0) {
            fetched_info.has_quota_size = 0;
        } else {
            fetched_info.has_quota_size = pwinfo->has_quota_size;
            fetched_info.quota_size = pwinfo->quota_size;
        }
    }
    if (pwinfo->has_ul_ratio != 0) {
        if (pwinfo->has_ul_ratio < 0) {
            fetched_info.has_ul_ratio = 0;
        } else {
            fetched_info.has_ul_ratio = pwinfo->has_ul_ratio;
            fetched_info.ul_ratio = pwinfo->ul_ratio;
        }
    }
    if (pwinfo->has_dl_ratio != 0) {
        if (pwinfo->has_dl_ratio < 0) {
            fetched_info.has_dl_ratio = 0;
        } else {
            fetched_info.has_dl_ratio = pwinfo->has_dl_ratio;
            fetched_info.dl_ratio = pwinfo->dl_ratio;
        }
    }
    if (pwinfo->allow_local_ip != NULL) {
        fetched_info.allow_local_ip = pwinfo->allow_local_ip;
    }
    if (pwinfo->deny_local_ip != NULL) {
        fetched_info.deny_local_ip = pwinfo->deny_local_ip;
    }
    if (pwinfo->allow_client_ip != NULL) {
        fetched_info.allow_client_ip = pwinfo->allow_client_ip;
    }
    if (pwinfo->deny_client_ip != NULL) {
        fetched_info.deny_client_ip = pwinfo->deny_client_ip;
    }
    if (pwinfo->has_time != 0) {
        if (pwinfo->has_time < 0) {
            fetched_info.has_time = 0;
        } else {
            fetched_info.has_time = pwinfo->has_time;
        }
        fetched_info.time_begin = pwinfo->time_begin;
        fetched_info.time_end = pwinfo->time_end;
    }
    if (pwinfo->has_per_user_max != 0) {
        if (pwinfo->has_per_user_max < 0) {
            fetched_info.has_per_user_max = 0;
        } else {
            fetched_info.has_per_user_max = pwinfo->has_per_user_max;
            fetched_info.per_user_max = pwinfo->per_user_max;
        }
    }
    if ((file2 = newpasswd_filename(file)) == NULL) {
        no_mem();
    }
    if ((fp2 = create_newpasswd(file, file2, pwinfo->login, 0, 1)) == NULL) {
        fprintf(stderr, "Error.\n"
                "Check that [%s] already exists,\n"
                "and that [%s] can be written.\n", pwinfo->login, file2);
        free(file2);
        return PW_ERROR_USER_ALREADY_EXIST;
    }
    if (add_new_pw_line(fp2, &fetched_info) != 0) {
        fprintf(stderr, "Unable to append a line\n");
        goto bye;
    }
    fflush(fp2);
#ifdef HAVE_FILENO
    fsync(fileno(fp2));
#endif
    if (fclose(fp2) != 0) {
        perror("Unable to close the file");
        goto bye2;
    }
    if (rename(file2, file) != 0) {
        perror("Unable to rename the file");
        goto bye2;
    }
    free(file2);
    return 0;

    bye:
    fclose(fp2);
    bye2:
    unlink(file2);
    free(file2);

    return PW_ERROR_UNEXPECTED_ERROR;
}
Esempio n. 7
0
static int do_useradd(const char * const file,
                      const PWInfo * const pwinfo_,
                      const unsigned long max_concurrent_logins,
                      const unsigned long long max_auth_memory)
{
    char *file2;
    FILE *fp2;
    PWInfo pwinfo = *pwinfo_;

    if (pwinfo.login == NULL || *(pwinfo.login) == 0) {
        fprintf(stderr, "Missing login\n");
        return PW_ERROR_MISSING_LOGIN;
    }
    if (file == NULL) {
        fprintf(stderr, "Missing passwd file\n");
        return PW_ERROR_MISSING_PASSWD_FILE;
    }
#ifndef ACCEPT_ROOT_VIRTUAL_USERS
    if (pwinfo.uid <= (uid_t) 0 || pwinfo.gid <= (gid_t) 0) {
        fprintf(stderr, "You must give (non-root) uid and gid\n");
        return PW_ERROR_USERADD_NOT_ROOT;
    }
#endif
    if (pwinfo.home == NULL) {
        fprintf(stderr, "Missing home directory\n");
        return PW_ERROR_USERADD_MISSING_HOME_DIR;
    }
    if (pwinfo.gecos == NULL) {
        if ((pwinfo.gecos = strdup("")) == NULL) {
            no_mem();
        }
    }
    if ((pwinfo.pwd = do_get_passwd()) == NULL) {
        fprintf(stderr, "Error with entering password - aborting\n");
        return PW_ERROR_ENTER_PASSWD_PW_ERROR;
    }
    {
        char *cleartext = pwinfo.pwd;

        pwinfo.pwd = best_crypt(cleartext,
                                max_concurrent_logins, max_auth_memory);
        if (*cleartext != 0) {
            pure_memzero(cleartext, strlen(cleartext));
        }
    }
    if ((file2 = newpasswd_filename(file)) == NULL) {
        no_mem();
    }
    if ((fp2 = create_newpasswd(file, file2, pwinfo.login, 1, 0)) == NULL) {
        fprintf(stderr, "Error.\n"
                "Check that [%s] doesn't already exist,\n"
                "and that [%s] can be written.\n",
                pwinfo.login, file2);
        free(file2);
        return PW_ERROR_USER_ALREADY_EXIST;
    }
    if (add_new_pw_line(fp2, &pwinfo) != 0) {
        fprintf(stderr, "Unable to append a line\n");
        goto bye;
    }
    fflush(fp2);
#ifdef HAVE_FILENO
    fsync(fileno(fp2));
#endif
    if (fclose(fp2) != 0) {
        perror("Unable to close the file");
        goto bye2;
    }
    if (rename(file2, file) != 0) {
        perror("Unable to rename the file");
        goto bye2;
    }
    free(file2);
    return 0;

    bye:
    fclose(fp2);
    bye2:
    unlink(file2);
    free(file2);

    return PW_ERROR_UNEXPECTED_ERROR;
}