📄 jk_isapi_plugin.c
字号:
}
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 + -