📄 mod_nw_ssl.c
字号:
ulFlag = SO_TLS_ENABLE;
rcode = WSAIoctl(socketHnd, SO_TLS_SET_FLAGS, &ulFlag, sizeof(unsigned long), NULL, 0, NULL, NULL, NULL);
if(rcode)
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"Error: %d with WSAIoctl(SO_TLS_SET_FLAGS, SO_TLS_ENABLE)", WSAGetLastError());
goto ERR;
}
ulFlag = SO_TLS_SERVER;
rcode = WSAIoctl(socketHnd, SO_TLS_SET_FLAGS, &ulFlag, sizeof(unsigned long),NULL, 0, NULL, NULL, NULL);
if(rcode)
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"Error: %d with WSAIoctl(SO_TLS_SET_FLAGS, SO_TLS_SERVER)", WSAGetLastError());
goto ERR;
}
loc2uni(UNI_LOCAL_DEFAULT, SASKey, key, 0, 0);
//setup the tlsserveropts struct
sWS2Opts.wallet = SASKey;
sWS2Opts.walletlen = unilen(SASKey);
sWS2Opts.sidtimeout = 0;
sWS2Opts.sidentries = 0;
sWS2Opts.siddir = NULL;
sWS2Opts.options = &sNWTLSOpts;
//setup the nwtlsopts structure
sNWTLSOpts.walletProvider = WAL_PROV_KMO;
sNWTLSOpts.keysList = NULL;
sNWTLSOpts.numElementsInKeyList = 0;
sNWTLSOpts.reservedforfutureuse = NULL;
sNWTLSOpts.reservedforfutureCRL = NULL;
sNWTLSOpts.reservedforfutureCRLLen = 0;
sNWTLSOpts.reserved1 = NULL;
sNWTLSOpts.reserved2 = NULL;
sNWTLSOpts.reserved3 = NULL;
rcode = WSAIoctl(socketHnd,
SO_TLS_SET_SERVER,
&sWS2Opts,
sizeof(struct tlsserveropts),
NULL,
0,
NULL,
NULL,
NULL);
if(SOCKET_ERROR == rcode) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
"Error: %d with WSAIoctl(SO_TLS_SET_SERVER)", WSAGetLastError());
goto ERR;
}
ERR:
return rcode;
}
static const char *set_secure_listener(cmd_parms *cmd, void *dummy,
const char *ips, const char* key,
const char* mutual)
{
NWSSLSrvConfigRec* sc = get_nwssl_cfg(cmd->server);
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
char *ports, *addr;
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 = (char*)ips;
}
new = apr_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);
addr = apr_pstrdup(cmd->pool, "0.0.0.0");
}
else {
new->local_addr.sin_addr.s_addr = parse_addr(ips, NULL);
addr = apr_pstrdup(cmd->pool, ips);
}
port = atoi(ports);
if (!port)
return "Port must be numeric";
apr_table_add(sc->sltable, ports, addr);
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;
new->addr = addr;
new->port = port;
ap_seclisteners = new;
return NULL;
}
static const char *set_secure_upgradeable_listener(cmd_parms *cmd, void *dummy,
const char *ips, const char* key)
{
NWSSLSrvConfigRec* sc = get_nwssl_cfg(cmd->server);
seclistenup_rec *listen_node;
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
char *ports, *addr;
unsigned short port;
seclistenup_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 = (char*)ips;
}
if (ports == ips) {
addr = apr_pstrdup(cmd->pool, "0.0.0.0");
}
else {
addr = apr_pstrdup(cmd->pool, ips);
}
port = atoi(ports);
if (!port)
return "Port must be numeric";
apr_table_set(sc->slutable, ports, addr);
new = apr_pcalloc(cmd->pool, sizeof(seclistenup_rec));
new->next = ap_seclistenersup;
strcpy(new->key, key);
new->addr = addr;
new->port = port;
ap_seclistenersup = new;
return err;
}
static apr_status_t nwssl_socket_cleanup(void *data)
{
ap_listen_rec* slr = (ap_listen_rec*)data;
ap_listen_rec* lr;
/* Remove our secure listener from the listener list */
for (lr = ap_listeners; lr; lr = lr->next) {
/* slr is at the head of the list */
if (lr == slr) {
ap_listeners = slr->next;
break;
}
/* slr is somewhere in between or at the end*/
if (lr->next == slr) {
lr->next = slr->next;
break;
}
}
return APR_SUCCESS;
}
static const char *set_trusted_certs(cmd_parms *cmd, void *dummy, char *arg)
{
char **ptr = (char **)apr_array_push(certlist);
*ptr = apr_pstrdup(cmd->pool, arg);
return NULL;
}
static int nwssl_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp)
{
ap_seclisteners = NULL;
ap_seclistenersup = NULL;
certlist = apr_array_make(pconf, 1, sizeof(char *));
return OK;
}
static int nwssl_pre_connection(conn_rec *c, void *csd)
{
if (apr_table_get(c->notes, "nwconv-ssl")) {
convert_secure_socket(c, (apr_socket_t*)csd);
}
else {
secsocket_data *csd_data = apr_palloc(c->pool, sizeof(secsocket_data));
csd_data->csd = (apr_socket_t*)csd;
csd_data->is_secure = 0;
ap_set_module_config(c->conn_config, &nwssl_module, (void*)csd_data);
}
return OK;
}
static int nwssl_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *s)
{
seclisten_rec* sl;
ap_listen_rec* lr;
apr_socket_t* sd;
apr_status_t status;
seclistenup_rec *slu;
int found;
for (sl = ap_seclisteners; sl != NULL; sl = sl->next) {
sl->fd = find_secure_listener(sl);
if (sl->fd < 0)
sl->fd = make_secure_socket(pconf, &sl->local_addr, sl->key, sl->mutual, s);
if (sl->fd >= 0) {
apr_os_sock_info_t sock_info;
sock_info.os_sock = &(sl->fd);
sock_info.local = (struct sockaddr*)&(sl->local_addr);
sock_info.remote = NULL;
sock_info.family = APR_INET;
sock_info.type = SOCK_STREAM;
apr_os_sock_make(&sd, &sock_info, pconf);
lr = apr_pcalloc(pconf, sizeof(ap_listen_rec));
if (lr) {
lr->sd = sd;
if ((status = apr_sockaddr_info_get(&lr->bind_addr, sl->addr, APR_UNSPEC, sl->port, 0,
pconf)) != APR_SUCCESS) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, status, pconf,
"alloc_listener: failed to set up sockaddr for %s:%d", sl->addr, sl->port);
return HTTP_INTERNAL_SERVER_ERROR;
}
lr->next = ap_listeners;
ap_listeners = lr;
apr_pool_cleanup_register(pconf, lr, nwssl_socket_cleanup, apr_pool_cleanup_null);
}
} else {
return HTTP_INTERNAL_SERVER_ERROR;
}
}
for (slu = ap_seclistenersup; slu; slu = slu->next) {
/* Check the listener list for a matching upgradeable listener */
found = 0;
for (lr = ap_listeners; lr; lr = lr->next) {
if (slu->port == lr->bind_addr->port) {
found = 1;
break;
}
}
if (!found) {
ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, plog,
"No Listen directive found for upgradeable listener %s:%d", slu->addr, slu->port);
}
}
build_cert_list(pconf);
return OK;
}
static void *nwssl_config_server_create(apr_pool_t *p, server_rec *s)
{
NWSSLSrvConfigRec *new = apr_palloc(p, sizeof(NWSSLSrvConfigRec));
new->sltable = apr_table_make(p, 5);
new->slutable = apr_table_make(p, 5);
return new;
}
static void *nwssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
{
NWSSLSrvConfigRec *base = (NWSSLSrvConfigRec *)basev;
NWSSLSrvConfigRec *add = (NWSSLSrvConfigRec *)addv;
NWSSLSrvConfigRec *merged = (NWSSLSrvConfigRec *)apr_palloc(p, sizeof(NWSSLSrvConfigRec));
return merged;
}
static int compare_ipports(void *rec, const char *key, const char *value)
{
conn_rec *c = (conn_rec*)rec;
if (value &&
((strcmp(value, "0.0.0.0") == 0) || (strcmp(value, c->local_ip) == 0)))
{
return 0;
}
return 1;
}
static int isSecureConnEx (const server_rec *s, const conn_rec *c, const apr_table_t *t)
{
char port[8];
itoa((c->local_addr)->port, port, 10);
if (!apr_table_do(compare_ipports, (void*)c, t, port, NULL))
{
return 1;
}
return 0;
}
static int isSecureConn (const server_rec *s, const conn_rec *c)
{
NWSSLSrvConfigRec *sc = get_nwssl_cfg(s);
return isSecureConnEx (s, c, sc->sltable);
}
static int isSecureConnUpgradeable (const server_rec *s, const conn_rec *c)
{
NWSSLSrvConfigRec *sc = get_nwssl_cfg(s);
return isSecureConnEx (s, c, sc->slutable);
}
static int isSecure (const request_rec *r)
{
return isSecureConn (r->server, r->connection);
}
static int isSecureUpgradeable (const request_rec *r)
{
return isSecureConnUpgradeable (r->server, r->connection);
}
static int isSecureUpgraded (const request_rec *r)
{
secsocket_data *csd_data = (secsocket_data*)ap_get_module_config(r->connection->conn_config, &nwssl_module);
return csd_data->is_secure;
}
static int nwssl_hook_Fixup(request_rec *r)
{
int i;
if (!isSecure(r) && !isSecureUpgraded(r))
return DECLINED;
apr_table_set(r->subprocess_env, "HTTPS", "on");
return DECLINED;
}
static const char *nwssl_hook_http_method (const request_rec *r)
{
if (isSecure(r) && !isSecureUpgraded(r))
return "https";
return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -