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

📄 protocol.cpp

📁 解压在c盘
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 1999-2003 Caucho Technology.  All rights reserved.
 *
 * Caucho Technology permits redistribution, modification and use
 * of this file in source and binary form ("the Software") under the
 * Caucho Public License ("the License").  In particular, the following
 * conditions must be met:
 *
 * 1. Each copy or derived work of the Software must preserve the copyright
 *    notice and this notice unmodified.
 *
 * 2. Redistributions of the Software in source or binary form must include 
 *    an unmodified copy of the License, normally in a plain ASCII text
 *
 * 3. The names "Resin" or "Caucho" are trademarks of Caucho Technology and
 *    may not be used to endorse products derived from this software.
 *    "Resin" or "Caucho" may not appear in the names of products derived
 *    from this software.
 *
 * 4. Caucho Technology requests that attribution be given to Resin
 *    in any manner possible.  We suggest using the "Resin Powered"
 *    button or creating a "powered by Resin(tm)" link to
 *    http://www.caucho.com for each page served by Resin.
 *
 * This Software is provided "AS IS," without a warranty of any kind. 
 * ALL EXPRESS OR IMPLIED REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
 *
 * CAUCHO TECHNOLOGY AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A RESULT OF USING OR
 * DISTRIBUTING SOFTWARE. IN NO EVENT WILL Caucho OR ITS LICENSORS BE LIABLE
 * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
 * INABILITY TO USE SOFTWARE, EVEN IF HE HAS BEEN ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGES.
 *
 * @author Scott Ferguson
 */

/*
 * SSL client certificate contributed by Ahn Le
 */

/*
 * Anh: We have to define _WIN32_WINNT as 0x0400 to have access to
 * the Crypto API.  By definning as this way, the dll can only work
 * with Windows 95 OEM Service Release 2 or above.
 */ 
#define _WIN32_WINNT 0x0400

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <windows.h>
#include "httpext.h"
#include <errno.h>
#include <ctype.h>
#include <string.h>

#define ISAPI_SCRIPT "/scripts/isapi_srun.dll"

extern "C" {
#include "../common/cse.h"
#include "../common/version.h"
}

extern "C" {

void
cse_error(config_t *config, char *fmt, ...)
{
	va_list arg;
	char buf[1024];

	va_start(arg, fmt);
	if (fmt)
		vsprintf(buf, fmt, arg);
	else
		buf[0] = 0;

	va_end(arg);

	if (buf[0]) {
		config->error = strdup(buf);
                config->disable_caucho_status = 0;
        }
#ifdef DEBUG
	{
		FILE *file;
	    file = fopen("/temp/isapi.log", "a+b");
		fprintf(file, "%s\n", buf);
		fclose(file);
	}
#endif
}

void *
cse_malloc(int size)
{
  return malloc(size);
}

void cse_free(void *value) {}

void
cse_set_socket_cleanup(int socket, void *pool)
{
}

void
cse_kill_socket_cleanup(int socket, void *pool)
{
}

}

void
cse_log(char *fmt, ...)
{
#ifdef DEBUG
	va_list arg;
	FILE *file;
	file = fopen("/temp/isapi.log", "a+");
	va_start(arg, fmt);
	if (file)
		vfprintf(file, fmt, arg);
	va_end(arg);
	fclose(file);
#endif
}

void *
cse_create_lock(config_t *config)
{
	return CreateMutex(0, false, 0);
}

int
cse_lock(void *lock)
{
	if (lock) {
		WaitForSingleObject(lock, INFINITE);
	}

	return 1;
}

void
cse_unlock(void *lock)
{
	if (lock) {
		ReleaseMutex(lock);
	}
}

static void
cse_printf(EXTENSION_CONTROL_BLOCK *r, char *fmt, ...)
{
  va_list args;
  char buf[4096];
  unsigned long len;

  va_start(args, fmt);
  vsprintf(buf, fmt, args);

  va_end(args);

  len = strlen(buf);

  r->WriteClient(r->ConnID, buf, &len, 0);
}

static void
cse_pad(EXTENSION_CONTROL_BLOCK *r)
{
  cse_printf(r, "\n\n\n\n");
  cse_printf(r, "<!--\n");
  cse_printf(r, "   - Unfortunately, Microsoft has added a clever new\n");
  cse_printf(r, "   - \"feature\" to Internet Explorer.  If the text in\n");
  cse_printf(r, "   - an error's message is \"too small\", specifically\n");
  cse_printf(r, "   - less than 512 bytes, Internet Explorer returns\n");
  cse_printf(r, "   - its own error message.  Yes, you can turn that\n");
  cse_printf(r, "   - off, but *surprise* it's pretty tricky to find\n");
  cse_printf(r, "   - buried as a switch called \"smart error\n");
  cse_printf(r, "   - messages\"  That means, of course, that many of\n");
  cse_printf(r, "   - Resin's error messages are censored by default.\n");
  cse_printf(r, "   - And, of course, you'll be shocked to learn that\n");
  cse_printf(r, "   - IIS always returns error messages that are long\n");
  cse_printf(r, "   - enough to make Internet Explorer happy.  The\n");
  cse_printf(r, "   - workaround is pretty simple: pad the error\n");
  cse_printf(r, "   - message with a big comment to push it over the\n");
  cse_printf(r, "   - five hundred and twelve byte minimum.  Of course,\n");
  cse_printf(r, "   - that's exactly what you're reading right now.\n");
  cse_printf(r, "   -->\n");
}


static int
connection_error(config_t *config, EXTENSION_CONTROL_BLOCK *r)
{
  // r->content_type = "text/html";
  // ap_send_http_header(r);
  char *hostname = 0;
  int port = 0;

  if (config->error_page) {
	  DWORD size = strlen(config->error_page);
	  DWORD type = 0;

          cse_printf(r, "HTTP/1.0 302 Redirect\r\n");
          cse_printf(r, "Location: %s\r\n", config->error_page);
          cse_printf(r, "\r\n");
          
	  return 1;
  }

  cse_printf(r, "HTTP/1.0 503 Server Error\n\n");
  cse_printf(r, "<html><body bgcolor='white'>\n");
  cse_printf(r, "<h1>Can't contact Servlet Runner at %s:%d\n",
	     (hostname ? hostname : "localhost"),
	     (port ? port : 6802));
  cse_printf(r, "</h1>\n");
  cse_printf(r, "</body></html>\n");
  
  cse_pad(r);

   return 1;
}

static int
cse_error(config_t *config, EXTENSION_CONTROL_BLOCK *r)
{
  // r->content_type = "text/html";
  // ap_send_http_header(r);

  if (config->error_page) {
	  DWORD size = strlen(config->error_page);
	  DWORD type = 0;

		cse_printf(r, "HTTP/1.0 302 Redirect\n");
		cse_printf(r, "Location: %s\n", config->error_page);
		cse_printf(r, "\n");

		return 1;
  }

  cse_printf(r, "HTTP/1.0 500 Server Error\n\n");
  cse_printf(r, "<html><body bgcolor='white'>\n");
  cse_printf(r, "<h1>Can't access URL</h1>\n");
  if (config->error)
	  cse_printf(r, "<pre>%s</pre>", config->error);
  cse_printf(r, "</body></html>\n");
  
  cse_pad(r);

   return 1;
}

static void
write_var(stream_t *s, EXTENSION_CONTROL_BLOCK *r, char *name, int code)
{
	char buf[8192];
        char *ptr;
	unsigned long size = sizeof(buf);

	buf[0] = 0;
	if (r->GetServerVariable(r->ConnID, name, buf, &size) && size > 0 && buf[0]) {
		buf[size] = 0;
                
                for (ptr = buf; isspace(*ptr); ptr++) {
                }
                
		cse_write_string(s, code, ptr);
	}
}

static void
write_header(stream_t *s, EXTENSION_CONTROL_BLOCK *r, char *name)
{
  char buf[8192];
  unsigned long size = sizeof(buf);
  char *ptr = buf;

  buf[0] = 0;
	if (r->GetServerVariable(r->ConnID, name, buf, &size) && size > 0 && buf[0]) {
                for (; size > 0 && buf[size - 1] <= ' '; size--) {
                }
		buf[size] = 0;
		cse_write_string(s, CSE_HEADER, name);
                for (ptr = buf; isspace(*ptr); ptr++) {
                }
                
		cse_write_string(s, CSE_VALUE, ptr);
 	}
}

/**
 * Writes SSL data, including client certificates.
 */
static void
write_ssl(stream_t *s, EXTENSION_CONTROL_BLOCK *r)
{
  char buf[8192];
  unsigned long size = sizeof(buf);

	if (! r->GetServerVariable(r->ConnID, "SERVER_PORT_SECURE", buf, &size) ||
            size <= 0 || buf[0] != '1')
          return;

	cse_write_string(s, CSE_IS_SECURE, "");

	// Anh : Add SSL connection informations
	cse_write_string(s, CSE_HEADER, "HTTPS");
	cse_write_string(s, CSE_VALUE, "on");
	write_header(s, r, "HTTPS_KEYSIZE");
	write_header(s, r, "HTTPS_SECRETKEYSIZE");
			
	// Anh : Check client certificate existence
	size = sizeof(buf);
	buf[0] = 0;

	if (! r->GetServerVariable(r->ConnID, "CERT_FLAGS", buf, &size) || 
		size <= 0 || buf[0] != '1')
		return;

	// There is a client certificate
    char cert_buf[8192]={0};
    CERT_CONTEXT_EX cert;
    cert.cbAllocated = sizeof(cert_buf);
    cert.CertContext.pbCertEncoded = (BYTE*) cert_buf;
    cert.CertContext.cbCertEncoded = 0;
    DWORD dwSize = sizeof(cert);

    if (r->ServerSupportFunction(r->ConnID,
                                 (DWORD)HSE_REQ_GET_CERT_INFO_EX,                               
                                 (LPVOID)&cert, &dwSize,NULL) != FALSE)
    {
      // cert now contains valid client certificate information	
      LOG(("\ndwCertEncodingType = %d (%d) %ld\n",
                    cert.CertContext.dwCertEncodingType & X509_ASN_ENCODING ,
                    cert.CertContext.cbCertEncoded,
                    cert.dwCertificateFlags));
               
      cse_write_packet(s, CSE_CLIENT_CERT, 
                       (char *)cert.CertContext.pbCertEncoded,
                       cert.CertContext.cbCertEncoded);
               
      write_header(s, r, "CERT_ISSUER");
      write_header(s, r, "CERT_SERIALNUMBER");
      write_header(s, r, "CERT_SUBJECT");
      write_header(s, r, "CERT_SERVER_ISSUER");
      write_header(s, r, "CERT_SERVER_SUBJECT");
	}
}

static int 
write_env(stream_t *s, EXTENSION_CONTROL_BLOCK *r)
{
	int isHttp11 = 0;

	char protocol[8192];
	char rawUri[8192];
	char *uri = rawUri;
	char buf[1024];
	unsigned long size = sizeof(protocol);

	if (r->GetServerVariable(r->ConnID, "SERVER_PROTOCOL", protocol, &size) && size > 0) {
		protocol[size] = 0;
		isHttp11 = ! strcmp(protocol, "HTTP/1.1");
	}
	size = sizeof(rawUri);
	if (r->GetServerVariable(r->ConnID, "PATH_INFO", uri, &size) && size > 0) {
		uri[size] = 0;
		if (! strncmp(uri, ISAPI_SCRIPT, sizeof(ISAPI_SCRIPT) - 1))
			uri += sizeof(ISAPI_SCRIPT) - 1;
	}
	else
		uri[size] = 0;
	
	write_var(s, r, "SERVER_PROTOCOL", CSE_PROTOCOL);
	write_var(s, r, "REQUEST_METHOD", CSE_METHOD);
	cse_write_string(s, CSE_URI, uri);
	//	write_var(s, r, "PATH_TRANSLATED", CSE_PATH_TRANSLATED);
	write_var(s, r, "QUERY_STRING", CSE_QUERY_STRING);
	write_var(s, r, "SERVER_NAME", CSE_SERVER_NAME);
	write_var(s, r, "SERVER_PORT", CSE_SERVER_PORT);
	write_var(s, r, "REMOTE_HOST", CSE_REMOTE_HOST);
	write_var(s, r, "REMOTE_ADDR", CSE_REMOTE_ADDR);
	write_var(s, r, "REMOTE_USER", CSE_REMOTE_USER);
	write_var(s, r, "AUTH_TYPE", CSE_AUTH_TYPE);

	// write_var(s, r, "CONTENT_TYPE", CSE_CONTENT_TYPE);
	// write_var(s, r, "CONTENT_LENGTH", CSE_CONTENT_LENGTH);
  // cse_write_string(s, CSE_DOCROOT, ap_document_root(r));
	sprintf(buf, "%d", s->srun->session);
	cse_write_string(s, CSE_SESSION_GROUP, buf);
	cse_write_string(s, CSE_SERVER_TYPE, "ISAPI");

	size = sizeof(buf);

	write_ssl(s, r);

	return isHttp11;
}

static void
write_headers(stream_t *s, EXTENSION_CONTROL_BLOCK *r)
{
	char buf[16384];
	unsigned long i = 0;
	unsigned long len = sizeof(buf);

	if (! r->GetServerVariable(r->ConnID, "ALL_RAW", buf, &len))
		return;

	while (i < len) {
		for (; i < len && isspace(buf[i]); i++) {
		}

		int head = i;
		int tail;

		for (; i < len && buf[i] != ':'; i++) {
		}
		buf[i] = 0;

		for (i++; i < len && buf[i] == ' ' && buf[i] != '\n'; i++) {
		}

		tail = i;
		for (; i < len && (buf[i] != '\n' || isspace(buf[i+1])); i++) {
			if (isspace(buf[i]))
				buf[i] = ' ';
		}
		if (buf[i - 1] == ' ')
			buf[i - 1] = 0;
		buf[i++] = 0;
		if (buf[head]) {
			cse_write_string(s, CSE_HEADER, buf + head);
			cse_write_string(s, CSE_VALUE, buf + tail);
		}
	}
}

static int
cse_write_response(stream_t *s, unsigned long len, EXTENSION_CONTROL_BLOCK *r)
{
	while (len > 0) {
		unsigned long sublen;

⌨️ 快捷键说明

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