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

📄 mod_tls.c

📁 apache 安装教程 apache 安装教程
💻 C
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. *//* * mod_tls.c - Apache SSL/TLS module for NetWare by Mike Gardiner. * * This module gives Apache the ability to do SSL/TLS with a minimum amount * of effort.  All of the SSL/TLS logic is already on NetWare versions 5 and * above and is interfaced through WinSock on NetWare.  As you can see in * the code below SSL/TLS sockets can be created with three WinSock calls. * * To load, simply place the module in the modules directory under the main * apache tree.  Then add a "SecureListen" with two arguments.  The first * argument is an address and/or port.  The second argument is the key pair * name as created in ConsoleOne. * *  Examples: * *          SecureListen 443 "SSL CertificateIP"   *          SecureListen 123.45.67.89:443 mycert */#define CORE_PRIVATE#define WS_SSL#define  MAX_ADDRESS  512#define  MAX_KEY       80#include "httpd.h"#include "http_config.h"#include "http_conf_globals.h"#include "http_log.h"#include "http_main.h"module MODULE_VAR_EXPORT tls_module;typedef struct TLSSrvConfigRec TLSSrvConfigRec;typedef struct seclisten_rec seclisten_rec;static fd_set listenfds;struct seclisten_rec {    seclisten_rec *next;    struct sockaddr_in local_addr;	/* local IP address and port */    int fd;    int used;			            /* Only used during restart */    char key[MAX_KEY];    int mutual;};struct TLSSrvConfigRec {    table *sltable;};static seclisten_rec* ap_seclisteners = NULL;#define get_tls_cfg(srv) (TLSSrvConfigRec *) ap_get_module_config(srv->module_config, &tls_module)static int find_secure_listener(seclisten_rec *lr){    seclisten_rec *sl;    for (sl = ap_seclisteners; sl; sl = sl->next) {        if (!memcmp(&sl->local_addr, &lr->local_addr, sizeof(sl->local_addr))) {            sl->used = 1;            return sl->fd;        }    }        return -1;}static int make_secure_socket(pool *p, const struct sockaddr_in *server,                              char* key, int mutual, server_rec *server_conf){    int s;    int one = 1;    char addr[MAX_ADDRESS];    struct sslserveropts opts;    struct linger li;    unsigned int optParam;    WSAPROTOCOL_INFO SecureProtoInfo;    int no = 1;        if (server->sin_addr.s_addr != htonl(INADDR_ANY))        ap_snprintf(addr, sizeof(addr), "address %s port %d",            inet_ntoa(server->sin_addr), ntohs(server->sin_port));    else        ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));    /* note that because we're about to slack we don't use psocket */    ap_block_alarms();    memset(&SecureProtoInfo, 0, sizeof(WSAPROTOCOL_INFO));    SecureProtoInfo.iAddressFamily = AF_INET;    SecureProtoInfo.iSocketType = SOCK_STREAM;    SecureProtoInfo.iProtocol = IPPROTO_TCP;       SecureProtoInfo.iSecurityScheme = SECURITY_PROTOCOL_SSL;    s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP,            (LPWSAPROTOCOL_INFO)&SecureProtoInfo, 0, 0);                if (s == INVALID_SOCKET) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,            "make_secure_socket: failed to get a socket for %s", addr);        ap_unblock_alarms();        return -1;    }            if (!mutual) {        optParam = SO_SSL_ENABLE | SO_SSL_SERVER;		            if (WSAIoctl(s, SO_SSL_SET_FLAGS, (char *)&optParam,            sizeof(optParam), NULL, 0, NULL, NULL, NULL)) {            errno = WSAGetLastError();            ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,                "make_secure_socket: for %s, WSAIoctl: (SO_SSL_SET_FLAGS)", addr);            ap_unblock_alarms();            return -1;        }    }    opts.cert = key;    opts.certlen = strlen(key);    opts.sidtimeout = 0;    opts.sidentries = 0;    opts.siddir = NULL;    if (WSAIoctl(s, SO_SSL_SET_SERVER, (char *)&opts, sizeof(opts),        NULL, 0, NULL, NULL, NULL) != 0) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,            "make_secure_socket: for %s, WSAIoctl: (SO_SSL_SET_SERVER)", addr);        ap_unblock_alarms();        return -1;    }    if (mutual) {        optParam = 0x07;               // SO_SSL_AUTH_CLIENT        if(WSAIoctl(s, SO_SSL_SET_FLAGS, (char*)&optParam,            sizeof(optParam), NULL, 0, NULL, NULL, NULL)) {            errno = WSAGetLastError();            ap_log_error( APLOG_MARK, APLOG_CRIT, server_conf,                "make_secure_socket: for %s, WSAIoctl: (SO_SSL_SET_FLAGS)", addr );            ap_unblock_alarms();            return -1;        }    }    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,            "make_secure_socket: for %s, setsockopt: (SO_REUSEADDR)", addr);        ap_unblock_alarms();        return -1;    }    one = 1;#ifdef SO_KEEPALIVE    if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(int)) < 0) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,            "make_secure_socket: for %s, setsockopt: (SO_KEEPALIVE)", addr);#endif        ap_unblock_alarms();        return -1;    }    if (server_conf->send_buffer_size) {        if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,            (char *) &server_conf->send_buffer_size, sizeof(int)) < 0) {            errno = WSAGetLastError();            ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf,                "make_secure_socket: failed to set SendBufferSize for %s, "			    "using default", addr);			ap_unblock_alarms();	        return -1;        }    }    if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,            "make_secure_socket: could not bind to %s", addr);        ap_unblock_alarms();        return -1;    }    if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &no, sizeof(int)) < 0) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_WARNING, server_conf,            "setsockopt: (TCP_NODELAY)");    }    if (listen(s, ap_listenbacklog) == -1) {        errno = WSAGetLastError();        ap_log_error(APLOG_MARK, APLOG_ERR, server_conf,            "make_secure_socket: unable to listen for connections on %s", addr);        ap_unblock_alarms();        return -1;    }    ap_unblock_alarms();    return s;}static const char *set_secure_listener(cmd_parms *cmd, void *dummy, char *ips, char* key, char* mutual){    TLSSrvConfigRec* sc = get_tls_cfg(cmd->server);    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);    char *ports;    unsigned short port;    seclisten_rec *new;        if (err != NULL)         return err;    ports = strchr(ips, ':');        if (ports != NULL) {    	    if (ports == ips)	        return "Missing IP address";	    else if (ports[1] == '\0')	        return "Address must end in :<port-number>";	        	    *(ports++) = '\0';    }    else {	    ports = ips;    }        new = ap_pcalloc(cmd->pool, sizeof(seclisten_rec));     new->local_addr.sin_family = AF_INET;        if (ports == ips)	    new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);    else	    new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);        port = atoi(ports);        if (!port) 	    return "Port must be numeric";	        ap_table_set(sc->sltable, ports, "T");        new->local_addr.sin_port = htons(port);    new->fd = -1;    new->used = 0;    new->next = ap_seclisteners;    strcpy(new->key, key);    new->mutual = (mutual) ? 1 : 0;    ap_seclisteners = new;    return NULL;}static void InitTLS(server_rec *s, pool *p){    seclisten_rec* sl;    listen_rec* lr;        for (sl = ap_seclisteners; sl != NULL; sl = sl->next) {        sl->fd = find_secure_listener(sl);        if (sl->fd < 0)            sl->fd = make_secure_socket(p, &sl->local_addr, sl->key, sl->mutual, s);                    else            ap_note_cleanups_for_socket(p, sl->fd);                    if (sl->fd >= 0) {            FD_SET(sl->fd, &listenfds);            ap_note_cleanups_for_socket(p, sl->fd);                        lr = ap_pcalloc(p, sizeof(listen_rec));                    if (lr) {                lr->local_addr = sl->local_addr;                lr->used = 0;                lr->fd = sl->fd;                lr->next = ap_listeners;                ap_listeners = lr;            }                                } else {            clean_parent_exit(1);        }    } }void *tls_config_server_create(pool *p, server_rec *s){    TLSSrvConfigRec *new = ap_palloc(p, sizeof(TLSSrvConfigRec));    new->sltable = ap_make_table(p, 5);    return new;}void *tls_config_server_merge(pool *p, void *basev, void *addv){    TLSSrvConfigRec *base = (TLSSrvConfigRec *)basev;    TLSSrvConfigRec *add  = (TLSSrvConfigRec *)addv;    TLSSrvConfigRec *merged  = (TLSSrvConfigRec *)ap_palloc(p, sizeof(TLSSrvConfigRec));    return merged;}int tls_hook_Fixup(request_rec *r){    TLSSrvConfigRec *sc = get_tls_cfg(r->server);    table *e = r->subprocess_env;        const char *s_secure;    char port[8];            /* For some reason r->server->port always return 80 rather than     * the current port.  So for now we will get it straight from     * the horses mouth.     */    /*  itoa(r->server->port, port, 10); */    itoa(ntohs(((r->connection)->local_addr).sin_port), port, 10);    s_secure = ap_table_get(sc->sltable, port);            if (!s_secure)        return DECLINED;        ap_table_set(e, "HTTPS", "on");        return DECLINED;}static const command_rec tls_module_cmds[] = {    { "SecureListen", set_secure_listener, NULL, RSRC_CONF, TAKE23,      "specify an address and/or port with a key pair name.\n"      "Optional third parameter of MUTUAL configures the port for mutual authentication."},    { NULL }};module MODULE_VAR_EXPORT tls_module ={    STANDARD_MODULE_STUFF,    InitTLS,                  /* initializer */    NULL,                     /* dir config creater */    NULL,                     /* dir merger --- default is to override */    tls_config_server_create, /* server config */    tls_config_server_merge,  /* merge server config */    tls_module_cmds,          /* command table */    NULL,                     /* handlers */    NULL,                     /* filename translation */    NULL,                     /* check_user_id */    NULL,                     /* check auth */    NULL,                     /* check access */    NULL,                     /* type_checker */        NULL,			          /* fixups */    NULL,                     /* logger */    NULL,               	  /* header parser */    NULL,               	  /* child_init */    NULL,			       	  /* child_exit */    tls_hook_Fixup         	  /* post read request */};

⌨️ 快捷键说明

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