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

📄 ssl_engine_pphrase.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 2 页
字号:
                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                                 "Init: SSLPassPhraseDialog builtin is not "                                 "supported on Win32 (key file "                                 "%s)", szPath);                    ssl_die();                }#endif /* WIN32 */                /*                 * Ok, anything else now means a fatal error.                 */                if (cpPassPhraseCur == NULL) {                    if (nPassPhraseDialogCur && pkey_mtime &&                        !(isterm = isatty(fileno(stdout)))) /* XXX: apr_isatty() */                    {                        ap_log_error(APLOG_MARK, APLOG_ERR, 0,                                     pServ,                                     "Init: Unable to read pass phrase "                                     "[Hint: key introduced or changed "                                     "before restart?]");                        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ);                    }                    else {                        ap_log_error(APLOG_MARK, APLOG_ERR, 0,                                     pServ, "Init: Private key not found");                        ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ);                    }                    if (writetty) {                        apr_file_printf(writetty, "Apache:mod_ssl:Error: Private key not found.\n");                        apr_file_printf(writetty, "**Stopped\n");                    }                }                else {                    ap_log_error(APLOG_MARK, APLOG_ERR, 0,                                 pServ, "Init: Pass phrase incorrect");                    ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ);                    if (writetty) {                        apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase incorrect.\n");                        apr_file_printf(writetty, "**Stopped\n");                    }                }                ssl_die();            }            if (pPrivateKey == NULL) {                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                            "Init: Unable to read server private key from "                            "file %s [Hint: Perhaps it is in a separate file? "                            "  See SSLCertificateKeyFile]", szPath);                ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);                ssl_die();            }            /*             * check algorithm type of private key and make             * sure only one private key per type is used.             */            at = ssl_util_algotypeof(NULL, pPrivateKey);            an = ssl_util_algotypestr(at);            if (algoKey & at) {                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                             "Init: Multiple %s server private keys not "                             "allowed", an);                ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);                ssl_die();            }            algoKey |= at;            /*             * Log the type of reading             */            if (nPassPhraseDialogCur == 0) {                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServ,                             "unencrypted %s private key - pass phrase not "                             "required", an);            }            else {                if (cpPassPhraseCur != NULL) {                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,                                 pServ,                                 "encrypted %s private key - pass phrase "                                 "requested", an);                }                else {                    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,                                 pServ,                                 "encrypted %s private key - pass phrase"                                 " reused", an);                }            }            /*             * Ok, when we have one more pass phrase store it             */            if (cpPassPhraseCur != NULL) {                cpp = (char **)apr_array_push(aPassPhrase);                *cpp = cpPassPhraseCur;                nPassPhrase++;            }            /*             * Insert private key into the global module configuration             * (we convert it to a stand-alone DER byte sequence             * because the SSL library uses static variables inside a             * RSA structure which do not survive DSO reloads!)             */            cp = asn1_table_vhost_key(mc, p, cpVHostID, an);            length = i2d_PrivateKey(pPrivateKey, NULL);            ucp = ssl_asn1_table_set(mc->tPrivateKey, cp, length);            (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */            if (nPassPhraseDialogCur != 0) {                /* remember mtime of encrypted keys */                asn1 = ssl_asn1_table_get(mc->tPrivateKey, cp);                asn1->source_mtime = pkey_mtime;            }            /*             * Free the private key structure             */            EVP_PKEY_free(pPrivateKey);        }    }    /*     * Let the user know when we're successful.     */    if (nPassPhraseDialog > 0) {        sc = mySrvConfig(s);        if (writetty) {            apr_file_printf(writetty, "\n"                            "OK: Pass Phrase Dialog successful.\n");        }    }    /*     * Wipe out the used memory from the     * pass phrase array and then deallocate it     */    if (aPassPhrase->nelts) {        pphrase_array_clear(aPassPhrase);        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,                     "Init: Wiped out the queried pass phrases from memory");    }    /* Close the pipes if they were opened     */    if (readtty) {        apr_file_close(readtty);        apr_file_close(writetty);        readtty = writetty = NULL;    }    return;}static apr_status_t ssl_pipe_child_create(apr_pool_t *p, const char *progname){    /* Child process code for 'ErrorLog "|..."';     * may want a common framework for this, since I expect it will     * be common for other foo-loggers to want this sort of thing...     */    apr_status_t rc;    apr_procattr_t *procattr;    apr_proc_t *procnew;    if (((rc = apr_procattr_create(&procattr, p)) == APR_SUCCESS) &&        ((rc = apr_procattr_io_set(procattr,                                   APR_FULL_BLOCK,                                   APR_FULL_BLOCK,                                   APR_NO_PIPE)) == APR_SUCCESS)) {        char **args;        const char *pname;        apr_tokenize_to_argv(progname, &args, p);        pname = apr_pstrdup(p, args[0]);        procnew = (apr_proc_t *)apr_pcalloc(p, sizeof(*procnew));        rc = apr_proc_create(procnew, pname, (const char * const *)args,                             NULL, procattr, p);        if (rc == APR_SUCCESS) {            /* XXX: not sure if we aught to...             * apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT);             */            writetty = procnew->in;            readtty = procnew->out;        }    }    return rc;}static int pipe_get_passwd_cb(char *buf, int length, char *prompt, int verify){    apr_status_t rc;    char *p;    apr_file_puts(prompt, writetty);    buf[0]='\0';    rc = apr_file_gets(buf, length, readtty);    apr_file_puts(APR_EOL_STR, writetty);    if (rc != APR_SUCCESS || apr_file_eof(readtty)) {        memset(buf, 0, length);        return 1;  /* failure */    }    if ((p = strchr(buf, '\n')) != NULL) {        *p = '\0';    }#ifdef WIN32    /* XXX: apr_sometest */    if ((p = strchr(buf, '\r')) != NULL) {        *p = '\0';    }#endif    return 0;}#ifdef SSLC_VERSION_NUMBERint ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify){    void *srv = ssl_pphrase_server_rec;#elseint ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv){#endif    SSLModConfigRec *mc;    server_rec *s;    apr_pool_t *p;    apr_array_header_t *aPassPhrase;    SSLSrvConfigRec *sc;    int *pnPassPhraseCur;    char **cppPassPhraseCur;    char *cpVHostID;    char *cpAlgoType;    int *pnPassPhraseDialog;    int *pnPassPhraseDialogCur;    BOOL *pbPassPhraseDialogOnce;    char *cpp;    int len = -1;    mc = myModConfig((server_rec *)srv);    /*     * Reconnect to the context of ssl_phrase_Handle()     */    s                      = myCtxVarGet(mc,  1, server_rec *);    p                      = myCtxVarGet(mc,  2, apr_pool_t *);    aPassPhrase            = myCtxVarGet(mc,  3, apr_array_header_t *);    pnPassPhraseCur        = myCtxVarGet(mc,  4, int *);    cppPassPhraseCur       = myCtxVarGet(mc,  5, char **);    cpVHostID              = myCtxVarGet(mc,  6, char *);    cpAlgoType             = myCtxVarGet(mc,  7, char *);    pnPassPhraseDialog     = myCtxVarGet(mc,  8, int *);    pnPassPhraseDialogCur  = myCtxVarGet(mc,  9, int *);    pbPassPhraseDialogOnce = myCtxVarGet(mc, 10, BOOL *);    sc                     = mySrvConfig(s);    (*pnPassPhraseDialog)++;    (*pnPassPhraseDialogCur)++;    /*     * When remembered pass phrases are available use them...     */    if ((cpp = pphrase_array_get(aPassPhrase, *pnPassPhraseCur)) != NULL) {        apr_cpystrn(buf, cpp, bufsize);        len = strlen(buf);        return len;    }    /*     * Builtin or Pipe dialog     */    if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN          || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {        char *prompt;        int i;        if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {            if (!readtty) {                ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,                             "Init: Creating pass phrase dialog pipe child "                             "'%s'", sc->server->pphrase_dialog_path);                if (ssl_pipe_child_create(p, sc->server->pphrase_dialog_path)                        != APR_SUCCESS) {                    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,                                 "Init: Failed to create pass phrase pipe '%s'",                                 sc->server->pphrase_dialog_path);                    PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);                    memset(buf, 0, (unsigned int)bufsize);                    return (-1);                }            }            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,                         "Init: Requesting pass phrase via piped dialog");        }        else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */#ifdef WIN32            PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);            memset(buf, 0, (unsigned int)bufsize);            return (-1);#else            /*             * stderr has already been redirected to the error_log.             * rather than attempting to temporarily rehook it to the terminal,             * we print the prompt to stdout before EVP_read_pw_string turns             * off tty echo             */            apr_file_open_stdout(&writetty, p);            ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,                         "Init: Requesting pass phrase via builtin terminal "                         "dialog");#endif        }        /*         * The first time display a header to inform the user about what         * program he actually speaks to, which module is responsible for         * this terminal dialog and why to the hell he has to enter         * something...         */        if (*pnPassPhraseDialog == 1) {            apr_file_printf(writetty, "%s mod_ssl/%s (Pass Phrase Dialog)\n",                            AP_SERVER_BASEVERSION, MOD_SSL_VERSION);            apr_file_printf(writetty, "Some of your private key files are encrypted for security reasons.\n");            apr_file_printf(writetty, "In order to read them you have to provide the pass phrases.\n");        }        if (*pbPassPhraseDialogOnce) {            *pbPassPhraseDialogOnce = FALSE;            apr_file_printf(writetty, "\n");            apr_file_printf(writetty, "Server %s (%s)\n", cpVHostID, cpAlgoType);        }        /*         * Emulate the OpenSSL internal pass phrase dialog         * (see crypto/pem/pem_lib.c:def_callback() for details)         */        prompt = "Enter pass phrase:";        for (;;) {            apr_file_puts(prompt, writetty);            if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {                i = pipe_get_passwd_cb(buf, bufsize, "", FALSE);            }            else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */                i = EVP_read_pw_string(buf, bufsize, "", FALSE);            }            if (i != 0) {                PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);                memset(buf, 0, (unsigned int)bufsize);                return (-1);            }            len = strlen(buf);            if (len < 1)                apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase empty (needs to be at least 1 character).\n");            else                break;        }    }    /*     * Filter program     */    else if (sc->server->pphrase_dialog_type == SSL_PPTYPE_FILTER) {        const char *cmd = sc->server->pphrase_dialog_path;        const char **argv = apr_palloc(p, sizeof(char *) * 4);        char *result;        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,                     "Init: Requesting pass phrase from dialog filter "                     "program (%s)", cmd);        argv[0] = cmd;        argv[1] = cpVHostID;        argv[2] = cpAlgoType;        argv[3] = NULL;        result = ssl_util_readfilter(s, p, cmd, argv);        apr_cpystrn(buf, result, bufsize);        len = strlen(buf);    }    /*     * Ok, we now have the pass phrase, so give it back     */    *cppPassPhraseCur = apr_pstrdup(p, buf);    /*     * And return it's length to OpenSSL...     */    return (len);}

⌨️ 快捷键说明

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