/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************************************************
 ******************************************************************************
 * NOTE! This program is not safe as a setuid executable!  Do not make it
 * setuid!
 ******************************************************************************
 *****************************************************************************/
/*
 * htpasswd.c: simple program for manipulating password file for
 * the Apache HTTP server
 *
 * Originally by Rob McCool
 *
 * Exit values:
 *  0: Success
 *  1: Failure; file access/permission problem
 *  2: Failure; command line syntax problem (usage message issued)
 *  3: Failure; password verification failure
 *  4: Failure; operation interrupted (such as with CTRL/C)
 *  5: Failure; buffer would overflow (username, filename, or computed
 *     record too long)
 *  6: Failure; username contains illegal or reserved characters
 *  7: Failure; file is not a valid htpasswd file
 */

#include "passwd_common.h"
#include "apr_signal.h"
#include "apr_getopt.h"

#if APR_HAVE_STDIO_H
#include <stdio.h>
#endif

#include "apr_md5.h"
#include "apr_sha1.h"

#if APR_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif
#if APR_HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifdef WIN32
#include <conio.h>
#define unlink _unlink
#endif

#define APHTP_NEWFILE        1
#define APHTP_NOFILE         2
#define APHTP_DELUSER        4
#define APHTP_VERIFY         8

apr_file_t *ftemp = NULL;

static int mkrecord(struct passwd_ctx *ctx, char *user)
{
    char hash_str[MAX_STRING_LEN];
    int ret;
    ctx->out = hash_str;
    ctx->out_len = sizeof(hash_str);

    ret = mkhash(ctx);
    if (ret)
        return ret;

    ctx->out = apr_pstrcat(ctx->pool, user, ":", hash_str, NL, NULL);
    if (strlen(ctx->out) >= MAX_STRING_LEN) {
        ctx->errstr = "resultant record too long";
        return ERR_OVERFLOW;
    }
    return 0;
}

static void usage(void)
{
    apr_file_printf(errfile, "Usage:" NL
        "\thtpasswd [-cimBdpsDv] [-C cost] passwordfile username" NL
        "\thtpasswd -b[cmBdpsDv] [-C cost] passwordfile username password" NL
        NL
        "\thtpasswd -n[imBdps] [-C cost] username" NL
        "\thtpasswd -nb[mBdps] [-C cost] username password" NL
        " -c  Create a new file." NL
        " -n  Don't update file; display results on stdout." NL
        " -b  Use the password from the command line rather than prompting "
            "for it." NL
        " -i  Read password from stdin without verification (for script usage)." NL
        " -m  Force MD5 encryption of the password (default)." NL
        " -B  Force bcrypt encryption of the password (very secure)." NL
        " -C  Set the computing time used for the bcrypt algorithm" NL
        "     (higher is more secure but slower, default: %d, valid: 4 to 31)." NL
        " -d  Force CRYPT encryption of the password (8 chars max, insecure)." NL
        " -s  Force SHA encryption of the password (insecure)." NL
        " -p  Do not encrypt the password (plaintext, insecure)." NL
        " -D  Delete the specified user." NL
        " -v  Verify password for the specified user." NL
        "On other systems than Windows and NetWare the '-p' flag will "
            "probably not work." NL
        "The SHA algorithm does not use a salt and is less secure than the "
            "MD5 algorithm." NL,
        BCRYPT_DEFAULT_COST
    );
    exit(ERR_SYNTAX);
}

/*
 * Check to see if the specified file can be opened for the given
 * access.
 */
static int accessible(apr_pool_t *pool, char *fname, int mode)
{
    apr_file_t *f = NULL;

    if (apr_file_open(&f, fname, mode, APR_OS_DEFAULT, pool) != APR_SUCCESS) {
        return 0;
    }
    apr_file_close(f);
    return 1;
}

/*
 * Return true if the named file exists, regardless of permissions.
 */
static int exists(char *fname, apr_pool_t *pool)
{
    apr_finfo_t sbuf;
    apr_status_t check;

    check = apr_stat(&sbuf, fname, APR_FINFO_TYPE, pool);
    return ((check || sbuf.filetype != APR_REG) ? 0 : 1);
}

static void terminate(void)
{
    apr_terminate();
#ifdef NETWARE
    pressanykey();
#endif
}

static void check_args(int argc, const char *const argv[],
                       struct passwd_ctx *ctx, unsigned *mask, char **user,
                       char **pwfilename)
{
    const char *arg;
    int args_left = 2;
    int i, ret;
    apr_getopt_t *state;
    apr_status_t rv;
    char opt;
    const char *opt_arg;
    apr_pool_t *pool = ctx->pool;

    rv = apr_getopt_init(&state, pool, argc, argv);
    if (rv != APR_SUCCESS)
        exit(ERR_SYNTAX);

    while ((rv = apr_getopt(state, "cnmspdBbDiC:v", &opt, &opt_arg)) == APR_SUCCESS) {
        switch (opt) {
        case 'c':
            *mask |= APHTP_NEWFILE;
            break;
        case 'n':
            args_left--;
            *mask |= APHTP_NOFILE;
            break;
        case 'D':
            *mask |= APHTP_DELUSER;
            break;
        case 'v':
            *mask |= APHTP_VERIFY;
            break;
        default:
            ret = parse_common_options(ctx, opt, opt_arg);
            if (ret) {
                apr_file_printf(errfile, "%s: %s" NL, argv[0], ctx->errstr);
                exit(ret);
            }
        }
    }
    if (ctx->passwd_src == PW_ARG)
        args_left++;
    if (rv != APR_EOF)
        usage();

    if ((*mask) & (*mask - 1)) {
        /* not a power of two, i.e. more than one flag specified */
        apr_file_printf(errfile, "%s: only one of -c -n -v -D may be specified" NL,
            argv[0]);
        exit(ERR_SYNTAX);
    }
    if ((*mask & APHTP_VERIFY) && ctx->passwd_src == PW_PROMPT)
        ctx->passwd_src = PW_PROMPT_VERIFY;

    /*
     * Make sure we still have exactly the right number of arguments left
     * (the filename, the username, and possibly the password if -b was
     * specified).
     */
    i = state->ind;
    if ((argc - i) != args_left) {
        usage();
    }

    if (!(*mask & APHTP_NOFILE)) {
        if (strlen(argv[i]) > (APR_PATH_MAX - 1)) {
            apr_file_printf(errfile, "%s: filename too long" NL, argv[0]);
            exit(ERR_OVERFLOW);
        }
        *pwfilename = apr_pstrdup(pool, argv[i++]);
    }
    if (strlen(argv[i]) > (MAX_STRING_LEN - 1)) {
        apr_file_printf(errfile, "%s: username too long (> %d)" NL,
                        argv[0], MAX_STRING_LEN - 1);
        exit(ERR_OVERFLOW);
    }
    *user = apr_pstrdup(pool, argv[i++]);
    if ((arg = strchr(*user, ':')) != NULL) {
        apr_file_printf(errfile, "%s: username contains illegal "
                        "character '%c'" NL, argv[0], *arg);
        exit(ERR_BADUSER);
    }
    if (ctx->passwd_src == PW_ARG) {
        if (strlen(argv[i]) > (MAX_STRING_LEN - 1)) {
            apr_file_printf(errfile, "%s: password too long (> %d)" NL,
                argv[0], MAX_STRING_LEN);
            exit(ERR_OVERFLOW);
        }
        ctx->passwd = apr_pstrdup(pool, argv[i]);
    }
}

static int verify(struct passwd_ctx *ctx, const char *hash)
{
    apr_status_t rv;
    int ret;

    if (ctx->passwd == NULL && (ret = get_password(ctx)) != 0)
       return ret;
    rv = apr_password_validate(ctx->passwd, hash);
    if (rv == APR_SUCCESS)
        return 0;
    if (APR_STATUS_IS_EMISMATCH(rv)) {
        ctx->errstr = "password verification failed";
        return ERR_PWMISMATCH;
    }
    ctx->errstr = apr_psprintf(ctx->pool, "Could not verify password: %pm",
                               &rv);
    return ERR_GENERAL;
}

/*
 * Let's do it.  We end up doing a lot of file opening and closing,
 * but what do we care?  This application isn't run constantly.
 */
int main(int argc, const char * const argv[])
{
    apr_file_t *fpw = NULL;
    char line[MAX_STRING_LEN];
    char *pwfilename = NULL;
    char *user = NULL;
    char tn[] = "htpasswd.tmp.XXXXXX";
    char *dirname;
    char *scratch, cp[MAX_STRING_LEN];
    int found = 0;
    int i;
    unsigned mask = 0;
    apr_pool_t *pool;
    int existing_file = 0;
    struct passwd_ctx ctx = { 0 };
#if APR_CHARSET_EBCDIC
    apr_status_t rv;
    apr_xlate_t *to_ascii;
#endif

    apr_app_initialize(&argc, &argv, NULL);
    atexit(terminate);
    apr_pool_create(&pool, NULL);
    apr_pool_abort_set(abort_on_oom, pool);
    apr_file_open_stderr(&errfile, pool);
    ctx.pool = pool;
    ctx.alg = ALG_APMD5;

#if APR_CHARSET_EBCDIC
    rv = apr_xlate_open(&to_ascii, "ISO-8859-1", APR_DEFAULT_CHARSET, pool);
    if (rv) {
        apr_file_printf(errfile, "apr_xlate_open(to ASCII)->%d" NL, rv);
        exit(1);
    }
    rv = apr_SHA1InitEBCDIC(to_ascii);
    if (rv) {
        apr_file_printf(errfile, "apr_SHA1InitEBCDIC()->%d" NL, rv);
        exit(1);
    }
    rv = apr_MD5InitEBCDIC(to_ascii);
    if (rv) {
        apr_file_printf(errfile, "apr_MD5InitEBCDIC()->%d" NL, rv);
        exit(1);
    }
#endif /*APR_CHARSET_EBCDIC*/

    check_args(argc, argv, &ctx, &mask, &user, &pwfilename);

    /*
     * Only do the file checks if we're supposed to frob it.
     */
    if (!(mask & APHTP_NOFILE)) {
        existing_file = exists(pwfilename, pool);
        if (existing_file) {
            /*
             * Check that this existing file is readable and writable.
             */
            if (!accessible(pool, pwfilename, APR_FOPEN_READ|APR_FOPEN_WRITE)) {
                apr_file_printf(errfile, "%s: cannot open file %s for "
                                "read/write access" NL, argv[0], pwfilename);
                exit(ERR_FILEPERM);
            }
        }
        else {
            /*
             * Error out if -c was omitted for this non-existant file.
             */
            if (!(mask & APHTP_NEWFILE)) {
                apr_file_printf(errfile,
                        "%s: cannot modify file %s; use '-c' to create it" NL,
                        argv[0], pwfilename);
                exit(ERR_FILEPERM);
            }
            /*
             * As it doesn't exist yet, verify that we can create it.
             */
            if (!accessible(pool, pwfilename, APR_FOPEN_WRITE|APR_FOPEN_CREATE)) {
                apr_file_printf(errfile, "%s: cannot create file %s" NL,
                                argv[0], pwfilename);
                exit(ERR_FILEPERM);
            }
        }
    }

    /*
     * All the file access checks (if any) have been made.  Time to go to work;
     * try to create the record for the username in question.  If that
     * fails, there's no need to waste any time on file manipulations.
     * Any error message text is returned in the record buffer, since
     * the mkrecord() routine doesn't have access to argv[].
     */
    if ((mask & (APHTP_DELUSER|APHTP_VERIFY)) == 0) {
        i = mkrecord(&ctx, user);
        if (i != 0) {
            apr_file_printf(errfile, "%s: %s" NL, argv[0], ctx.errstr);
            exit(i);
        }
        if (mask & APHTP_NOFILE) {
            printf("%s" NL, ctx.out);
            exit(0);
        }
    }

    if ((mask & APHTP_VERIFY) == 0) {
        /*
         * We can access the files the right way, and we have a record
         * to add or update.  Let's do it..
         */
        if (apr_temp_dir_get((const char**)&dirname, pool) != APR_SUCCESS) {
            apr_file_printf(errfile, "%s: could not determine temp dir" NL,
                            argv[0]);
            exit(ERR_FILEPERM);
        }
        dirname = apr_psprintf(pool, "%s/%s", dirname, tn);

        if (apr_file_mktemp(&ftemp, dirname, 0, pool) != APR_SUCCESS) {
            apr_file_printf(errfile, "%s: unable to create temporary file %s" NL,
                            argv[0], dirname);
            exit(ERR_FILEPERM);
        }
    }

    /*
     * If we're not creating a new file, copy records from the existing
     * one to the temporary file until we find the specified user.
     */
    if (existing_file && !(mask & APHTP_NEWFILE)) {
        if (apr_file_open(&fpw, pwfilename, APR_READ | APR_BUFFERED,
                          APR_OS_DEFAULT, pool) != APR_SUCCESS) {
            apr_file_printf(errfile, "%s: unable to read file %s" NL,
                            argv[0], pwfilename);
            exit(ERR_FILEPERM);
        }
        while (apr_file_gets(line, sizeof(line), fpw) == APR_SUCCESS) {
            char *colon;

            strcpy(cp, line);
            scratch = cp;
            while (apr_isspace(*scratch)) {
                ++scratch;
            }

            if (!*scratch || (*scratch == '#')) {
                putline(ftemp, line);
                continue;
            }
            /*
             * See if this is our user.
             */
            colon = strchr(scratch, ':');
            if (colon != NULL) {
                *colon = '\0';
            }
            else {
                /*
                 * If we've not got a colon on the line, this could well
                 * not be a valid htpasswd file.
                 * We should bail at this point.
                 */
                apr_file_printf(errfile, "%s: The file %s does not appear "
                                         "to be a valid htpasswd file." NL,
                                argv[0], pwfilename);
                apr_file_close(fpw);
                exit(ERR_INVALID);
            }
            if (strcmp(user, scratch) != 0) {
                putline(ftemp, line);
                continue;
            }
            else {
                /* We found the user we were looking for */
                found++;
                if ((mask & APHTP_DELUSER)) {
                    /* Delete entry from the file */
                    apr_file_printf(errfile, "Deleting ");
                }
                else if ((mask & APHTP_VERIFY)) {
                    /* Verify */
                    char *hash = colon + 1;
                    size_t len;

                    len = strcspn(hash, "\r\n");
                    if (len == 0) {
                        apr_file_printf(errfile, "Empty hash for user %s" NL,
                                        user);
                        exit(ERR_INVALID);
                    }
                    hash[len] = '\0';

                    i = verify(&ctx, hash);
                    if (i != 0) {
                        apr_file_printf(errfile, "%s" NL, ctx.errstr);
                        exit(i);
                    }
                }
                else {
                    /* Update entry */
                    apr_file_printf(errfile, "Updating ");
                    putline(ftemp, ctx.out);
                }
            }
        }
        apr_file_close(fpw);
    }
    if (!found) {
        if (mask & APHTP_DELUSER) {
            apr_file_printf(errfile, "User %s not found" NL, user);
            exit(0);
        }
        else if (mask & APHTP_VERIFY) {
            apr_file_printf(errfile, "User %s not found" NL, user);
            exit(ERR_BADUSER);
        }
        else {
            apr_file_printf(errfile, "Adding ");
            putline(ftemp, ctx.out);
        }
    }
    if (mask & APHTP_VERIFY) {
        apr_file_printf(errfile, "Password for user %s correct." NL, user);
        exit(0);
    }

    apr_file_printf(errfile, "password for user %s" NL, user);

    /* The temporary file has all the data, just copy it to the new location.
     */
    if (apr_file_copy(dirname, pwfilename, APR_FILE_SOURCE_PERMS, pool) !=
        APR_SUCCESS) {
        apr_file_printf(errfile, "%s: unable to update file %s" NL,
                        argv[0], pwfilename);
        exit(ERR_FILEPERM);
    }
    apr_file_close(ftemp);
    return 0;
}
