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

📄 jk_isapi_plugin.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 4 页
字号:
    }
    else {
        rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                          REGISTRY_LOCATION, (DWORD) 0, KEY_READ, &hkey);
        if (ERROR_SUCCESS != rc) {
            return JK_FALSE;
        }

        if (get_registry_config_parameter(hkey,
                                          JK_LOG_FILE_TAG,
                                          tmpbuf, sizeof(log_file))) {
            strcpy(log_file, tmpbuf);
        }
        else {
            ok = JK_FALSE;
        }

        if (get_registry_config_parameter(hkey,
                                          JK_LOG_LEVEL_TAG,
                                          tmpbuf, sizeof(tmpbuf))) {
            log_level = jk_parse_log_level(tmpbuf);
        }
        else {
            ok = JK_FALSE;
        }

        if (get_registry_config_parameter(hkey,
                                          EXTENSION_URI_TAG,
                                          tmpbuf, sizeof(extension_uri))) {
            strcpy(extension_uri, tmpbuf);
        }
        else {
            ok = JK_FALSE;
        }

        if (get_registry_config_parameter(hkey,
                                          JK_WORKER_FILE_TAG,
                                          tmpbuf, sizeof(worker_file))) {
            strcpy(worker_file, tmpbuf);
        }
        else {
            ok = JK_FALSE;
        }

        if (get_registry_config_parameter(hkey,
                                          JK_MOUNT_FILE_TAG,
                                          tmpbuf,
                                          sizeof(worker_mount_file))) {
            strcpy(worker_mount_file, tmpbuf);
        }
        else {
            ok = JK_FALSE;
        }

        if (get_registry_config_parameter(hkey,
                                          URI_SELECT_TAG,
                                          tmpbuf, sizeof(tmpbuf))) {
            int opt = parse_uri_select(tmpbuf);
            if (opt >= 0) {
                uri_select_option = opt;
            }
            else {
                ok = JK_FALSE;
            }
        }

        RegCloseKey(hkey);
    }
    return ok;
}

static int get_registry_config_parameter(HKEY hkey,
                                         const char *tag, char *b, DWORD sz)
{
    DWORD type = 0;
    LONG lrc;

    lrc = RegQueryValueEx(hkey, tag, (LPDWORD) 0, &type, (LPBYTE) b, &sz);
    if ((ERROR_SUCCESS != lrc) || (type != REG_SZ)) {
        return JK_FALSE;
    }

    b[sz] = '\0';

    return JK_TRUE;
}

static int init_ws_service(isapi_private_data_t * private_data,
                           jk_ws_service_t *s, char **worker_name)
{
    char huge_buf[16 * 1024];   /* should be enough for all */

    DWORD huge_buf_sz;

    s->jvm_route = NULL;

    s->start_response = start_response;
    s->read = read;
    s->write = write;
    s->flush = NULL;

    /* Clear RECO status */
    s->reco_status = RECO_NONE;

    GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME, (*worker_name));
    GET_SERVER_VARIABLE_VALUE(HTTP_URI_HEADER_NAME, s->req_uri);
    GET_SERVER_VARIABLE_VALUE(HTTP_QUERY_HEADER_NAME, s->query_string);

    if (s->req_uri == NULL) {
        s->query_string = private_data->lpEcb->lpszQueryString;
        *worker_name = DEFAULT_WORKER_NAME;
        GET_SERVER_VARIABLE_VALUE("URL", s->req_uri);
        if (unescape_url(s->req_uri) < 0)
            return JK_FALSE;
        getparents(s->req_uri);
    }

    GET_SERVER_VARIABLE_VALUE("AUTH_TYPE", s->auth_type);
    GET_SERVER_VARIABLE_VALUE("REMOTE_USER", s->remote_user);
    GET_SERVER_VARIABLE_VALUE("SERVER_PROTOCOL", s->protocol);
    GET_SERVER_VARIABLE_VALUE("REMOTE_HOST", s->remote_host);
    GET_SERVER_VARIABLE_VALUE("REMOTE_ADDR", s->remote_addr);
    GET_SERVER_VARIABLE_VALUE(SERVER_NAME, s->server_name);
    GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT", s->server_port, 80);
    GET_SERVER_VARIABLE_VALUE(SERVER_SOFTWARE, s->server_software);
    GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT_SECURE", s->is_ssl, 0);

    s->method = private_data->lpEcb->lpszMethod;
    s->content_length = private_data->lpEcb->cbTotalBytes;

    s->ssl_cert = NULL;
    s->ssl_cert_len = 0;
    s->ssl_cipher = NULL;
    s->ssl_session = NULL;
    s->ssl_key_size = -1;

    s->headers_names = NULL;
    s->headers_values = NULL;
    s->num_headers = 0;
    s->uw_map = uw_map;
    /*
     * Add SSL IIS environment
     */
    if (s->is_ssl) {
        char *ssl_env_names[9] = {
            "CERT_ISSUER",
            "CERT_SUBJECT",
            "CERT_COOKIE",
            "HTTPS_SERVER_SUBJECT",
            "CERT_FLAGS",
            "HTTPS_SECRETKEYSIZE",
            "CERT_SERIALNUMBER",
            "HTTPS_SERVER_ISSUER",
            "HTTPS_KEYSIZE"
        };
        char *ssl_env_values[9] = {
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL,
            NULL
        };
        unsigned int i;
        unsigned int num_of_vars = 0;

        for (i = 0; i < 9; i++) {
            GET_SERVER_VARIABLE_VALUE(ssl_env_names[i], ssl_env_values[i]);
            if (ssl_env_values[i]) {
                num_of_vars++;
            }
        }
        if (num_of_vars) {
            unsigned int j;

            s->attributes_names =
                jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *));
            s->attributes_values =
                jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *));

            j = 0;
            for (i = 0; i < 9; i++) {
                if (ssl_env_values[i]) {
                    s->attributes_names[j] = ssl_env_names[i];
                    s->attributes_values[j] = ssl_env_values[i];
                    j++;
                }
            }
            s->num_attributes = num_of_vars;
            if (ssl_env_values[4] && ssl_env_values[4][0] == '1') {
                CERT_CONTEXT_EX cc;
                cc.cbAllocated = sizeof(huge_buf);
                cc.CertContext.pbCertEncoded = (BYTE *) huge_buf;
                cc.CertContext.cbCertEncoded = 0;

                if (private_data->lpEcb->
                    ServerSupportFunction(private_data->lpEcb->ConnID,
                                          (DWORD) HSE_REQ_GET_CERT_INFO_EX,
                                          (LPVOID) & cc, NULL,
                                          NULL) != FALSE) {
                    jk_log(logger, JK_LOG_DEBUG,
                           "Client Certificate encoding:%d sz:%d flags:%ld",
                           cc.CertContext.
                           dwCertEncodingType & X509_ASN_ENCODING,
                           cc.CertContext.cbCertEncoded,
                           cc.dwCertificateFlags);
                    s->ssl_cert =
                        jk_pool_alloc(&private_data->p,
                                      base64_encode_cert_len(cc.CertContext.
                                                             cbCertEncoded));

                    s->ssl_cert_len = base64_encode_cert(s->ssl_cert,
                                                         huge_buf,
                                                         cc.CertContext.
                                                         cbCertEncoded) - 1;
                }
            }
        }
    }

    huge_buf_sz = sizeof(huge_buf);
    if (get_server_value(private_data->lpEcb,
                         "ALL_HTTP", huge_buf, huge_buf_sz)) {
        unsigned int cnt = 0;
        char *tmp;

        for (tmp = huge_buf; *tmp; tmp++) {
            if (*tmp == '\n') {
                cnt++;
            }
        }

        if (cnt) {
            char *headers_buf = jk_pool_strdup(&private_data->p, huge_buf);
            unsigned int i;
            size_t len_of_http_prefix = strlen("HTTP_");
            BOOL need_content_length_header = (s->content_length == 0);

            cnt -= 2;           /* For our two special headers:
                                 * HTTP_TOMCATURI_XXXXXXXX
                                 * HTTP_TOMCATWORKER_XXXXXXXX
                                 */
            /* allocate an extra header slot in case we need to add a content-length header */
            s->headers_names =
                jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *));
            s->headers_values =
                jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *));

            if (!s->headers_names || !s->headers_values || !headers_buf) {
                return JK_FALSE;
            }

            for (i = 0, tmp = headers_buf; *tmp && i < cnt;) {
                int real_header = JK_TRUE;

                /* Skipp the HTTP_ prefix to the beginning of th header name */
                tmp += len_of_http_prefix;

                if (!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME))
                    || !strnicmp(tmp, WORKER_HEADER_NAME,
                                 strlen(WORKER_HEADER_NAME))) {
                    real_header = JK_FALSE;
                }
                else if (!strnicmp(tmp, QUERY_HEADER_NAME,
                                   strlen(QUERY_HEADER_NAME))) {
                    /* HTTP_TOMCATQUERY_XXXXXXXX was supplied,
                     * remove it from the count and skip
                     */
                    cnt--;
                    real_header = JK_FALSE;
                }
                else if (need_content_length_header &&
                         !strnicmp(tmp, CONTENT_LENGTH,
                                   strlen(CONTENT_LENGTH))) {
                    need_content_length_header = FALSE;
                    s->headers_names[i] = tmp;
                }
                else if (!strnicmp(tmp, TOMCAT_TRANSLATE_HEADER_NAME,
                                   strlen(TOMCAT_TRANSLATE_HEADER_NAME))) {
                    s->headers_names[i] = TRANSLATE_HEADER_NAME_LC;
                }
                else {
                    s->headers_names[i] = tmp;
                }

                while (':' != *tmp && *tmp) {
                    if ('_' == *tmp) {
                        *tmp = '-';
                    }
                    else {
                        *tmp = JK_TOLOWER(*tmp);
                    }
                    tmp++;
                }
                *tmp = '\0';
                tmp++;

                /* Skip all the WS chars after the ':' to the beginning of th header value */
                while (' ' == *tmp || '\t' == *tmp || '\v' == *tmp) {
                    tmp++;
                }

                if (real_header) {
                    s->headers_values[i] = tmp;
                }

                while (*tmp != '\n' && *tmp != '\r') {
                    tmp++;
                }
                *tmp = '\0';
                tmp++;

                /* skipp CR LF */
                while (*tmp == '\n' || *tmp == '\r') {
                    tmp++;
                }

                if (real_header) {
                    i++;
                }
            }
            /* Add a content-length = 0 header if needed.
             * Ajp13 assumes an absent content-length header means an unknown,
             * but non-zero length body.
             */
            if (need_content_length_header) {
                s->headers_names[cnt] = "Content-Length";
                s->headers_values[cnt] = "0";
                cnt++;
            }
            s->num_headers = cnt;
        }
        else {
            /* We must have our two headers */
            return JK_FALSE;
        }
    }
    else {
        return JK_FALSE;
    }

    return JK_TRUE;
}

static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb,
                            char *name, char *buf, DWORD bufsz)
{
    DWORD sz = bufsz;
    buf[0]   = '\0';
    if (!lpEcb->GetServerVariable(lpEcb->ConnID, name,
                                  buf, (LPDWORD) &sz))
        return JK_FALSE;

    if (sz <= bufsz)
        buf[sz-1] = '\0';
    return JK_TRUE;
}

static const char begin_cert[] = "-----BEGIN CERTIFICATE-----\r\n";

static const char end_cert[] = "-----END CERTIFICATE-----\r\n";

static const char basis_64[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static int base64_encode_cert_len(int len)
{
    int n = ((len + 2) / 3 * 4) + 1;    /* base64 encoded size */
    n += (n + 63 / 64) * 2;             /* add CRLF's */
    n += sizeof(begin_cert) + sizeof(end_cert) - 2;  /* add enclosing strings. */
    return n;
}

static int base64_encode_cert(char *encoded,
                              const char *string, int len)
{
    int i, c;
    char *p;
    const char *t;

    p = encoded;

    t = begin_cert;
    while (*t != '\0')
        *p++ = *t++;

    c = 0;
    for (i = 0; i < len - 2; i += 3) {
        *p++ = basis_64[(string[i] >> 2) & 0x3F];
        *p++ = basis_64[((string[i] & 0x3) << 4) |
                        ((int)(string[i + 1] & 0xF0) >> 4)];
        *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
                        ((int)(string[i + 2] & 0xC0) >> 6)];
        *p++ = basis_64[string[i + 2] & 0x3F];
        c += 4;
        if (c >= 64) {
            *p++ = '\r';
            *p++ = '\n';
            c = 0;
        }
    }
    if (i < len) {
        *p++ = basis_64[(string[i] >> 2) & 0x3F];
        if (i == (len - 1)) {
            *p++ = basis_64[((string[i] & 0x3) << 4)];
            *p++ = '=';
        }
        else {
            *p++ = basis_64[((string[i] & 0x3) << 4) |
                            ((int)(string[i + 1] & 0xF0) >> 4)];
            *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
        }
        *p++ = '=';
        c++;
    }
    if (c != 0) {
        *p++ = '\r';
        *p++ = '\n';
    }

    t = end_cert;
    while (*t != '\0')
        *p++ = *t++;

    *p++ = '\0';
    return (int)(p - encoded);
}

⌨️ 快捷键说明

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