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

📄 mod_nw_ssl.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -