int get_password(struct passwd_ctx *ctx)
{
    char buf[MAX_STRING_LEN + 1];
    if (ctx->passwd_src == PW_STDIN) {
        apr_file_t *file_stdin;
        apr_size_t nread;
        if (apr_file_open_stdin(&file_stdin, ctx->pool) != APR_SUCCESS) {
            ctx->errstr = "Unable to read from stdin.";
            return ERR_GENERAL;
        }
        if (apr_file_read_full(file_stdin, buf, sizeof(buf) - 1,
                               &nread) != APR_EOF
            || nread == sizeof(buf) - 1) {
            goto err_too_long;
        }
        buf[nread] = '\0';
        if (nread >= 1 && buf[nread-1] == '\n') {
            buf[nread-1] = '\0';
            if (nread >= 2 && buf[nread-2] == '\r')
                buf[nread-2] = '\0';
        }
        apr_file_close(file_stdin);
        ctx->passwd = apr_pstrdup(ctx->pool, buf);
    }
    else if (ctx->passwd_src == PW_PROMPT_VERIFY) {
        apr_size_t bufsize = sizeof(buf);
        if (apr_password_get("Enter password: "******"New password: "******"Re-type new password: "******"password verification error";
            memset(ctx->passwd, '\0', strlen(ctx->passwd));
            memset(buf, '\0', sizeof(buf));
            return ERR_PWMISMATCH;
        }
    }
    memset(buf, '\0', sizeof(buf));
    return 0;

err_too_long:
    ctx->errstr = apr_psprintf(ctx->pool,
                               "password too long (>%" APR_SIZE_T_FMT ")",
                               ctx->out_len - 1);
    return ERR_OVERFLOW;
}
Exemplo n.º 2
0
static void add_password(const char *user, const char *realm, apr_file_t *f)
{
    char *pw;
    apr_md5_ctx_t context;
    unsigned char digest[16];
    char string[MAX_STRING_LEN];
    char pwin[MAX_STRING_LEN];
    char pwv[MAX_STRING_LEN];
    unsigned int i;
    apr_size_t len = sizeof(pwin);

    if (apr_password_get("New password: "******"password too long");
        cleanup_tempfile_and_exit(5);
    }
    len = sizeof(pwin);
    apr_password_get("Re-type new password: "******"They don't match, sorry.\n");
        cleanup_tempfile_and_exit(1);
    }
    pw = pwin;
    apr_file_printf(f, "%s:%s:", user, realm);

    /* Do MD5 stuff */
    sprintf(string, "%s:%s:%s", user, realm, pw);

    apr_md5_init(&context);
#if APR_CHARSET_EBCDIC
    apr_md5_set_xlate(&context, to_ascii);
#endif
    apr_md5_update(&context, (unsigned char *) string, strlen(string));
    apr_md5_final(digest, &context);

    for (i = 0; i < 16; i++)
        apr_file_printf(f, "%02x", digest[i]);

    apr_file_printf(f, "\n");
}
Exemplo n.º 3
0
/*
 * Make a password record from the given information.  A zero return
 * indicates success; failure means that the output buffer contains an
 * error message instead.
 */
static int mkrecord(char *user, char *record, apr_size_t rlen, char *passwd,
                    int alg)
{
    char *pw;
    char cpw[120];
    char pwin[MAX_STRING_LEN];
    char pwv[MAX_STRING_LEN];
    char salt[9];
    apr_size_t bufsize;

    if (passwd != NULL) {
        pw = passwd;
    }
    else {
        bufsize = sizeof(pwin);
        if (apr_password_get("New password: "******"password too long (>%"
                         APR_SIZE_T_FMT ")", sizeof(pwin) - 1);
            return ERR_OVERFLOW;
        }
        bufsize = sizeof(pwv);
        apr_password_get("Re-type new password: "******"password verification error", (rlen - 1));
            return ERR_PWMISMATCH;
        }
        pw = pwin;
        memset(pwv, '\0', sizeof(pwin));
    }
    switch (alg) {

    case ALG_APSHA:
        /* XXX cpw >= 28 + strlen(sha1) chars - fixed len SHA */
        apr_sha1_base64(pw,strlen(pw),cpw);
        break;

    case ALG_APMD5:
        if (seed_rand()) {
            break;
        }
        generate_salt(&salt[0], 8);
        salt[8] = '\0';

        apr_md5_encode((const char *)pw, (const char *)salt,
                     cpw, sizeof(cpw));
        break;

    case ALG_PLAIN:
        /* XXX this len limitation is not in sync with any HTTPd len. */
        apr_cpystrn(cpw,pw,sizeof(cpw));
        break;

#if (!(defined(WIN32) || defined(NETWARE)))
    case ALG_CRYPT:
    default:
        if (seed_rand()) {
            break;
        }
        to64(&salt[0], rand(), 8);
        salt[8] = '\0';

        apr_cpystrn(cpw, crypt(pw, salt), sizeof(cpw) - 1);
        if (strlen(pw) > 8) {
            char *truncpw = strdup(pw);
            truncpw[8] = '\0';
            if (!strcmp(cpw, crypt(truncpw, salt))) {
                apr_file_printf(errfile, "Warning: Password truncated to 8 characters "
                                "by CRYPT algorithm." NL);
            }
            free(truncpw);
        }
        break;
#endif
    }
    memset(pw, '\0', strlen(pw));

    /*
     * Check to see if the buffer is large enough to hold the username,
     * hash, and delimiters.
     */
    if ((strlen(user) + 1 + strlen(cpw)) > (rlen - 1)) {
        apr_cpystrn(record, "resultant record too long", (rlen - 1));
        return ERR_OVERFLOW;
    }
    strcpy(record, user);
    strcat(record, ":");
    strcat(record, cpw);
    strcat(record, "\n");
    return 0;
}
Exemplo n.º 4
0
int main(int argc, const char * const argv[])
{
    apr_pool_t *pool;
    apr_status_t rv;
    apr_size_t l;
    char pwi[MAX_STRING_LEN];
    char pwc[MAX_STRING_LEN];
    char errbuf[MAX_STRING_LEN];
    const char *arg;
    int  need_file = 1;
    int  need_user = 1;
    int  need_pwd  = 1;
    int  need_cmnt = 0;
    int  pwd_supplied = 0;
    int  changed = 0;
    int  cmd = HTDBM_MAKE;
    int  i;
    int args_left = 2;

    apr_app_initialize(&argc, &argv, NULL);
    atexit(terminate);

    if ((rv = htdbm_init(&pool, &h)) != APR_SUCCESS) {
        fprintf(stderr, "Unable to initialize htdbm terminating!\n");
        apr_strerror(rv, errbuf, sizeof(errbuf));
        exit(1);
    }
    /*
     * Preliminary check to make sure they provided at least
     * three arguments, we'll do better argument checking as
     * we parse the command line.
     */
    if (argc < 3)
       htdbm_usage();
    /*
     * Go through the argument list and pick out any options.  They
     * have to precede any other arguments.
     */
    for (i = 1; i < argc; i++) {
        arg = argv[i];
        if (*arg != '-')
            break;

        while (*++arg != '\0') {
            switch (*arg) {
            case 'b':
                pwd_supplied = 1;
                need_pwd = 0;
                args_left++;
                break;
            case 'c':
                h->create = 1;
                break;
            case 'n':
                need_file = 0;
                cmd = HTDBM_NOFILE;
                    args_left--;
                break;
            case 'l':
                need_pwd = 0;
                need_user = 0;
                cmd = HTDBM_LIST;
                h->rdonly = 1;
                args_left--;
                break;
            case 't':
                need_cmnt = 1;
                args_left++;
                break;
            case 'T':
                h->type = apr_pstrdup(h->pool, ++arg);
                while (*arg != '\0')
                    ++arg;
                --arg; /* so incrementing this in the loop with find a null */
                break;
            case 'v':
                h->rdonly = 1;
                cmd = HTDBM_VERIFY;
                break;
            case 'x':
                need_pwd = 0;
                cmd = HTDBM_DELETE;
                break;
            case 'm':
                h->alg = ALG_APMD5;
                break;
            case 'p':
                h->alg = ALG_PLAIN;
                break;
            case 's':
                h->alg = ALG_APSHA;
                break;
#if (!(defined(WIN32) || defined(TPF) || defined(NETWARE)))
            case 'd':
                h->alg = ALG_CRYPT;
                break;
#endif
            default:
                htdbm_usage();
                break;
            }
        }
    }
    /*
     * Make sure we still have exactly the right number of arguments left
     * (the filename, the username, and possibly the password if -b was
     * specified).
     */
    if ((argc - i) != args_left)
        htdbm_usage();

    if (!need_file)
        i--;
    else {
        h->filename = apr_pstrdup(h->pool, argv[i]);
            if ((rv = htdbm_open(h)) != APR_SUCCESS) {
            fprintf(stderr, "Error opening database %s\n", argv[i]);
            apr_strerror(rv, errbuf, sizeof(errbuf));
            fprintf(stderr,"%s\n",errbuf);
            exit(ERR_FILEPERM);
        }
    }
    if (need_user) {
        h->username = apr_pstrdup(pool, argv[i+1]);
        if (htdbm_valid_username(h) != APR_SUCCESS)
            exit(ERR_BADUSER);
    }
    if (pwd_supplied)
        h->userpass = apr_pstrdup(pool, argv[i+2]);

    if (need_pwd) {
        l = sizeof(pwc);
        if (apr_password_get("Enter password        : "******"Password too long\n");
            exit(ERR_OVERFLOW);
        }
        l = sizeof(pwc);
        if (apr_password_get("Re-type password      : "******"Password too long\n");
            exit(ERR_OVERFLOW);
        }
        if (strcmp(pwi, pwc) != 0) {
            fprintf(stderr, "Password verification error\n");
            exit(ERR_PWMISMATCH);
        }

        h->userpass = apr_pstrdup(pool,  pwi);
    }
    if (need_cmnt && pwd_supplied)
        h->comment = apr_pstrdup(pool, argv[i+3]);
    else if (need_cmnt)
        h->comment = apr_pstrdup(pool, argv[i+2]);

    switch (cmd) {
        case HTDBM_VERIFY:
            if ((rv = htdbm_verify(h)) != APR_SUCCESS) {
                if(rv == APR_ENOENT) {
                    fprintf(stderr, "The user '%s' could not be found in database\n", h->username);
                    exit(ERR_BADUSER);
                }
                else {
                    fprintf(stderr, "Password mismatch for user '%s'\n", h->username);
                    exit(ERR_PWMISMATCH);
                }
            }
            else
                fprintf(stderr, "Password validated for user '%s'\n", h->username);
            break;
        case HTDBM_DELETE:
            if (htdbm_del(h) != APR_SUCCESS) {
                fprintf(stderr, "Cannot find user '%s' in database\n", h->username);
                exit(ERR_BADUSER);
            }
            h->username = NULL;
            changed = 1;
            break;
        case HTDBM_LIST:
            htdbm_list(h);
            break;
        default:
            htdbm_make(h);
            break;

    }
    if (need_file && !h->rdonly) {
        if ((rv = htdbm_save(h, &changed)) != APR_SUCCESS) {
            apr_strerror(rv, errbuf, sizeof(errbuf));
            exit(ERR_FILEPERM);
        }
        fprintf(stdout, "Database %s %s.\n", h->filename,
                h->create ? "created" : (changed ? "modified" : "updated"));
    }
    if (cmd == HTDBM_NOFILE) {
        if (!need_cmnt) {
            fprintf(stderr, "%s:%s\n", h->username, h->userpass);
        }
        else {
            fprintf(stderr, "%s:%s:%s\n", h->username, h->userpass,
                    h->comment);
        }
    }
    htdbm_terminate(h);

    return 0; /* Suppress compiler warning. */
}