📄 mod_nw_ssl.c
字号:
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; ap_listen_rec **walk; apr_sockaddr_t *sa; int found_listener = 0; 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->server->process->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->server->process->pool, "0.0.0.0"); } else { new->local_addr.sin_addr.s_addr = parse_addr(ips, NULL); addr = apr_pstrdup(cmd->server->process->pool, ips); } port = atoi(ports); if (!port) return "Port must be numeric"; /* If the specified addr:port was created previously, put the listen socket record back on the ap_listeners list so that the socket will be reused rather than recreated */ for (walk = &nw_old_listeners; *walk;) { sa = (*walk)->bind_addr; if (sa) { ap_listen_rec *new; apr_port_t oldport; oldport = sa->port; /* If both ports are equivalent, then if their names are equivalent, * then we will re-use the existing record. */ if (port == oldport && ((!addr && !sa->hostname) || ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { new = *walk; *walk = new->next; new->next = ap_listeners; ap_listeners = new; found_listener = 1; continue; } } walk = &(*walk)->next; } apr_table_add(sc->sltable, ports, addr); /* If we found a pre-existing listen socket record, then there is no need to create a new secure listen socket record. */ if (found_listener) { return NULL; } 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){ seclisten_rec* ap_old_seclisteners; char *ports, *addr; unsigned short port; ap_listen_rec **walk; seclisten_rec **secwalk; apr_sockaddr_t *sa; int found; /* Pull all of the listeners that were created by mod_nw_ssl out of the ap_listeners list so that the normal listen socket processing does automatically close them */ nw_old_listeners = NULL; ap_old_seclisteners = NULL; for (secwalk = &ap_seclisteners; *secwalk;) { found = 0; for (walk = &ap_listeners; *walk;) { sa = (*walk)->bind_addr; if (sa) { ap_listen_rec *new; seclisten_rec *secnew; apr_port_t oldport; oldport = sa->port; /* If both ports are equivalent, then if their names are equivalent, * then we will re-use the existing record. */ if ((*secwalk)->port == oldport && ((!(*secwalk)->addr && !sa->hostname) || (((*secwalk)->addr && sa->hostname) && !strcmp(sa->hostname, (*secwalk)->addr)))) { /* Move the listen socket from ap_listeners to nw_old_listeners */ new = *walk; *walk = new->next; new->next = nw_old_listeners; nw_old_listeners = new; /* Move the secure socket record to ap_old_seclisterners */ secnew = *secwalk; *secwalk = secnew->next; secnew->next = ap_old_seclisteners; ap_old_seclisteners = secnew; found = 1; break; } } walk = &(*walk)->next; } if (!found && &(*secwalk)->next) { secwalk = &(*secwalk)->next; } } /* Restore the secure socket records list so that the post config can process all of the sockets normally */ ap_seclisteners = ap_old_seclisteners; ap_seclistenersup = NULL; certlist = apr_array_make(pconf, 1, sizeof(char *)); /* Now that we have removed all of the mod_nw_ssl created socket records, allow the normal listen socket handling to occur. NOTE: If for any reason mod_nw_ssl is removed as a built-in module, the following call must be put back into the pre-config handler of the MPM. It is only here to ensure that mod_nw_ssl fixes up the listen socket list before anything else looks at it. */ ap_listen_pre_config(); 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; ap_listen_rec *walk; seclisten_rec *secwalk, *lastsecwalk; apr_sockaddr_t *sa; int found_listener = 0; /* Walk the old listeners list and compare it to the secure listeners list and remove any secure listener records that are not being reused */ for (walk = nw_old_listeners; walk; walk = walk->next) { sa = walk->bind_addr; if (sa) { ap_listen_rec *new; apr_port_t oldport; oldport = sa->port; for (secwalk = ap_seclisteners, lastsecwalk = ap_seclisteners; secwalk; secwalk = lastsecwalk->next) { unsigned short port = secwalk->port; char *addr = secwalk->addr; /* If both ports are equivalent, then if their names are equivalent, * then we will re-use the existing record. */ if (port == oldport && ((!addr && !sa->hostname) || ((addr && sa->hostname) && !strcmp(sa->hostname, addr)))) { if (secwalk == ap_seclisteners) { ap_seclisteners = secwalk->next; } else { lastsecwalk->next = secwalk->next; } apr_socket_close(walk->sd); walk->active = 0; break; } else { lastsecwalk = secwalk; } } } } for (sl = ap_seclisteners; sl != NULL; sl = sl->next) { /* If we find a pre-existing listen socket and it has already been created, then no neeed to go any further, just reuse it. */ if (((sl->fd = find_secure_listener(sl)) >= 0) && (sl->used)) { continue; } if (sl->fd < 0) sl->fd = make_secure_socket(s->process->pool, &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, s->process->pool); lr = apr_pcalloc(s->process->pool, 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, s->process->pool)) != 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(s->process->pool, 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(s->process->pool); 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -