⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htpasswd.c

📁 Apache HTTP Server 是一个功能强大的灵活的与HTTP/1.1相兼容的web服务器.这里给出的是Apache HTTP服务器的源码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 1999-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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        8apr_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--;            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -