diff options
Diffstat (limited to 'rubbos/app/httpd-2.0.64/support/htpasswd.c')
-rw-r--r-- | rubbos/app/httpd-2.0.64/support/htpasswd.c | 610 |
1 files changed, 0 insertions, 610 deletions
diff --git a/rubbos/app/httpd-2.0.64/support/htpasswd.c b/rubbos/app/httpd-2.0.64/support/htpasswd.c deleted file mode 100644 index b76f530b..00000000 --- a/rubbos/app/httpd-2.0.64/support/htpasswd.c +++ /dev/null @@ -1,610 +0,0 @@ -/* 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 "apr.h" -#include "apr_lib.h" -#include "apr_strings.h" -#include "apr_errno.h" -#include "apr_file_io.h" -#include "apr_general.h" -#include "apr_signal.h" - -#if APR_HAVE_STDIO_H -#include <stdio.h> -#endif - -#include "apr_md5.h" -#include "apr_sha1.h" -#include <time.h> - -#if APR_HAVE_CRYPT_H -#include <crypt.h> -#endif -#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 - -#if !APR_CHARSET_EBCDIC -#define LF 10 -#define CR 13 -#else /*APR_CHARSET_EBCDIC*/ -#define LF '\n' -#define CR '\r' -#endif /*APR_CHARSET_EBCDIC*/ - -#define MAX_STRING_LEN 256 -#define ALG_PLAIN 0 -#define ALG_CRYPT 1 -#define ALG_APMD5 2 -#define ALG_APSHA 3 - -#define ERR_FILEPERM 1 -#define ERR_SYNTAX 2 -#define ERR_PWMISMATCH 3 -#define ERR_INTERRUPTED 4 -#define ERR_OVERFLOW 5 -#define ERR_BADUSER 6 -#define ERR_INVALID 7 - -#define APHTP_NEWFILE 1 -#define APHTP_NOFILE 2 -#define APHTP_NONINTERACTIVE 4 -#define APHTP_DELUSER 8 - -apr_file_t *errfile; -apr_file_t *ftemp = NULL; - -static void to64(char *s, unsigned long v, int n) -{ - static unsigned char itoa64[] = /* 0 ... 63 => ASCII - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } -} - -static void putline(apr_file_t *f, const char *l) -{ - apr_file_puts(l, f); -} - -/* - * 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: ", pwin, &bufsize) != 0) { - apr_snprintf(record, (rlen - 1), "password too long (>%" - APR_SIZE_T_FMT ")", sizeof(pwin) - 1); - return ERR_OVERFLOW; - } - bufsize = sizeof(pwv); - apr_password_get("Re-type new password: ", pwv, &bufsize); - if (strcmp(pwin, pwv) != 0) { - apr_cpystrn(record, "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: - (void) srand((int) time((time_t *) NULL)); - to64(&salt[0], rand(), 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: - (void) srand((int) time((time_t *) NULL)); - to64(&salt[0], rand(), 8); - salt[8] = '\0'; - - apr_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); - 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; -} - -static void usage(void) -{ - apr_file_printf(errfile, "Usage:\n"); - apr_file_printf(errfile, "\thtpasswd [-cmdpsD] passwordfile username\n"); - apr_file_printf(errfile, "\thtpasswd -b[cmdpsD] passwordfile username " - "password\n\n"); - apr_file_printf(errfile, "\thtpasswd -n[mdps] username\n"); - apr_file_printf(errfile, "\thtpasswd -nb[mdps] username password\n"); - apr_file_printf(errfile, " -c Create a new file.\n"); - apr_file_printf(errfile, " -n Don't update file; display results on " - "stdout.\n"); - apr_file_printf(errfile, " -m Force MD5 encryption of the password" -#if defined(WIN32) || defined(TPF) || defined(NETWARE) - " (default)" -#endif - ".\n"); - apr_file_printf(errfile, " -d Force CRYPT encryption of the password" -#if (!(defined(WIN32) || defined(TPF) || defined(NETWARE))) - " (default)" -#endif - ".\n"); - apr_file_printf(errfile, " -p Do not encrypt the password (plaintext).\n"); - apr_file_printf(errfile, " -s Force SHA encryption of the password.\n"); - apr_file_printf(errfile, " -b Use the password from the command line " - "rather than prompting for it.\n"); - apr_file_printf(errfile, " -D Delete the specified user.\n"); - apr_file_printf(errfile, - "On Windows, NetWare and TPF systems the '-m' flag is used by " - "default.\n"); - apr_file_printf(errfile, - "On all other systems, the '-p' flag will probably not work.\n"); - 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(apr_pool_t *pool, int argc, const char *const argv[], - int *alg, int *mask, char **user, char **pwfilename, - char **password) -{ - const char *arg; - int args_left = 2; - int i; - - /* - * 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) { - 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') { - if (*arg == 'c') { - *mask |= APHTP_NEWFILE; - } - else if (*arg == 'n') { - *mask |= APHTP_NOFILE; - args_left--; - } - else if (*arg == 'm') { - *alg = ALG_APMD5; - } - else if (*arg == 's') { - *alg = ALG_APSHA; - } - else if (*arg == 'p') { - *alg = ALG_PLAIN; - } - else if (*arg == 'd') { - *alg = ALG_CRYPT; - } - else if (*arg == 'b') { - *mask |= APHTP_NONINTERACTIVE; - args_left++; - } - else if (*arg == 'D') { - *mask |= APHTP_DELUSER; - } - else { - usage(); - } - } - } - - if ((*mask & APHTP_NEWFILE) && (*mask & APHTP_NOFILE)) { - apr_file_printf(errfile, "%s: -c and -n options conflict\n", argv[0]); - exit(ERR_SYNTAX); - } - if ((*mask & APHTP_NEWFILE) && (*mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "%s: -c and -D options conflict\n", argv[0]); - exit(ERR_SYNTAX); - } - if ((*mask & APHTP_NOFILE) && (*mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "%s: -n and -D options conflict\n", argv[0]); - exit(ERR_SYNTAX); - } - /* - * 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) { - usage(); - } - - if (*mask & APHTP_NOFILE) { - i--; - } - else { - if (strlen(argv[i]) > (APR_PATH_MAX - 1)) { - apr_file_printf(errfile, "%s: filename too long\n", argv[0]); - exit(ERR_OVERFLOW); - } - *pwfilename = apr_pstrdup(pool, argv[i]); - if (strlen(argv[i + 1]) > (MAX_STRING_LEN - 1)) { - apr_file_printf(errfile, "%s: username too long (> %d)\n", - argv[0], MAX_STRING_LEN - 1); - exit(ERR_OVERFLOW); - } - } - *user = apr_pstrdup(pool, argv[i + 1]); - if ((arg = strchr(*user, ':')) != NULL) { - apr_file_printf(errfile, "%s: username contains illegal " - "character '%c'\n", argv[0], *arg); - exit(ERR_BADUSER); - } - if (*mask & APHTP_NONINTERACTIVE) { - if (strlen(argv[i + 2]) > (MAX_STRING_LEN - 1)) { - apr_file_printf(errfile, "%s: password too long (> %d)\n", - argv[0], MAX_STRING_LEN); - exit(ERR_OVERFLOW); - } - *password = apr_pstrdup(pool, argv[i + 2]); - } -} - -/* - * 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 record[MAX_STRING_LEN]; - char line[MAX_STRING_LEN]; - char *password = NULL; - char *pwfilename = NULL; - char *user = NULL; - char tn[] = "htpasswd.tmp.XXXXXX"; - char *dirname; - char *scratch, cp[MAX_STRING_LEN]; - int found = 0; - int i; - int alg = ALG_CRYPT; - int mask = 0; - apr_pool_t *pool; - int existing_file = 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_file_open_stderr(&errfile, pool); - -#if APR_CHARSET_EBCDIC - rv = apr_xlate_open(&to_ascii, "ISO8859-1", APR_DEFAULT_CHARSET, pool); - if (rv) { - apr_file_printf(errfile, "apr_xlate_open(to ASCII)->%d\n", rv); - exit(1); - } - rv = apr_SHA1InitEBCDIC(to_ascii); - if (rv) { - apr_file_printf(errfile, "apr_SHA1InitEBCDIC()->%d\n", rv); - exit(1); - } - rv = apr_MD5InitEBCDIC(to_ascii); - if (rv) { - apr_file_printf(errfile, "apr_MD5InitEBCDIC()->%d\n", rv); - exit(1); - } -#endif /*APR_CHARSET_EBCDIC*/ - - check_args(pool, argc, argv, &alg, &mask, &user, &pwfilename, &password); - - -#if defined(WIN32) || defined(NETWARE) - if (alg == ALG_CRYPT) { - alg = ALG_APMD5; - apr_file_printf(errfile, "Automatically using MD5 format.\n"); - } -#endif - -#if (!(defined(WIN32) || defined(TPF) || defined(NETWARE))) - if (alg == ALG_PLAIN) { - apr_file_printf(errfile,"Warning: storing passwords as plain text " - "might just not work on this platform.\n"); - } -#endif - - /* - * 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_READ | APR_APPEND)) { - apr_file_printf(errfile, "%s: cannot open file %s for " - "read/write access\n", 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\n", - argv[0], pwfilename); - exit(ERR_FILEPERM); - } - /* - * As it doesn't exist yet, verify that we can create it. - */ - if (!accessible(pool, pwfilename, APR_CREATE | APR_WRITE)) { - apr_file_printf(errfile, "%s: cannot create file %s\n", - 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)) { - i = mkrecord(user, record, sizeof(record) - 1, - password, alg); - if (i != 0) { - apr_file_printf(errfile, "%s: %s\n", argv[0], record); - exit(i); - } - if (mask & APHTP_NOFILE) { - printf("%s\n", record); - exit(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\n", - 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\n", - 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\n", - 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, "\n%s: The file %s does not appear " - "to be a valid htpasswd file.\n", - argv[0], pwfilename); - apr_file_close(fpw); - exit(ERR_INVALID); - } - if (strcmp(user, scratch) != 0) { - putline(ftemp, line); - continue; - } - else { - if (!(mask & APHTP_DELUSER)) { - /* We found the user we were looking for. - * Add him to the file. - */ - apr_file_printf(errfile, "Updating "); - putline(ftemp, record); - found++; - } - else { - /* We found the user we were looking for. - * Delete them from the file. - */ - apr_file_printf(errfile, "Deleting "); - found++; - } - } - } - apr_file_close(fpw); - } - if (!found && !(mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "Adding "); - putline(ftemp, record); - } - else if (!found && (mask & APHTP_DELUSER)) { - apr_file_printf(errfile, "User %s not found\n", user); - exit(0); - } - apr_file_printf(errfile, "password for user %s\n", 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\n", - argv[0], pwfilename); - exit(ERR_FILEPERM); - } - apr_file_close(ftemp); - return 0; -} |