/* 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 */
};


