int config_uplink_ssl_setup(struct uplink_config_t *l) { l->ssl = ssl_alloc(); if (ssl_create(l->ssl, (void *)l)) { hlog(LOG_ERR, "Uplink: Failed to create SSL context for '%s*'", l->name); return -1; } /* optional client cert for server-side validation */ if (l->certfile && l->keyfile) { if (ssl_certificate(l->ssl, l->certfile, l->keyfile)) { hlog(LOG_ERR, "Uplink '%s': Failed to load SSL certificatess", l->name); ssl_free(l->ssl); l->ssl = NULL; return -1; } } /* optional server cert validation */ if (l->cafile) { if (ssl_ca_certificate(l->ssl, l->cafile, 2)) { hlog(LOG_ERR, "Uplink '%s': Failed to load trusted SSL CA certificates", l->name); ssl_free(l->ssl); l->ssl = NULL; return -1; } } hlog(LOG_INFO, "Uplink %s: SSL initialized%s%s", l->name, (l->cafile) ? ", server validated" : "", (l->certfile) ? ", client cert loaded" : ""); return 0; }
static int open_listener(struct listen_config_t *lc) { struct listen_t *l; int i; l = listener_alloc(); l->id = lc->id; l->hidden = lc->hidden; l->corepeer = lc->corepeer; l->client_flags = lc->client_flags; l->clients_max = lc->clients_max; l->portaccount = port_accounter_alloc(); /* Pick first of the AIs for this listen definition */ l->addr_s = strsockaddr( lc->ai->ai_addr, lc->ai->ai_addrlen ); l->name = hstrdup(lc->name); l->portnum = lc->portnum; l->ai_protocol = lc->ai->ai_protocol; l->listener_id = keyhash(l->addr_s, strlen(l->addr_s), 0); l->listener_id = keyhash(&lc->ai->ai_socktype, sizeof(lc->ai->ai_socktype), l->listener_id); l->listener_id = keyhash(&lc->ai->ai_protocol, sizeof(lc->ai->ai_protocol), l->listener_id); hlog(LOG_DEBUG, "Opening listener %d/%d '%s': %s", lc->id, l->listener_id, lc->name, l->addr_s); if (lc->ai->ai_socktype == SOCK_DGRAM && lc->ai->ai_protocol == IPPROTO_UDP) { /* UDP listenting is not quite same as TCP listening.. */ i = open_udp_listener(l, lc->ai); } else if (lc->ai->ai_socktype == SOCK_STREAM && lc->ai->ai_protocol == IPPROTO_TCP) { /* TCP listenting... */ i = open_tcp_listener(l, lc->ai, "TCP"); #ifdef USE_SCTP } else if (lc->ai->ai_socktype == SOCK_STREAM && lc->ai->ai_protocol == IPPROTO_SCTP) { i = open_tcp_listener(l, lc->ai, "SCTP"); if (i >= 0) i = sctp_set_listen_params(l); #endif } else { hlog(LOG_ERR, "Unsupported listener protocol for '%s'", l->name); listener_free(l); return -1; } if (i < 0) { hlog(LOG_DEBUG, "... failed"); listener_free(l); return -1; } hlog(LOG_DEBUG, "... ok, bound"); /* Set up an SSL context if necessary */ #ifdef USE_SSL if (lc->keyfile && lc->certfile) { l->ssl = ssl_alloc(); if (ssl_create(l->ssl, (void *)l)) { hlog(LOG_ERR, "Failed to create SSL context for '%s*': %s", lc->name, l->addr_s); listener_free(l); return -1; } if (ssl_certificate(l->ssl, lc->certfile, lc->keyfile)) { hlog(LOG_ERR, "Failed to load SSL key and certificates for '%s*': %s", lc->name, l->addr_s); listener_free(l); return -1; } /* optional client cert validation */ if (lc->cafile) { if (ssl_ca_certificate(l->ssl, lc->cafile, 2)) { hlog(LOG_ERR, "Failed to load trusted SSL CA certificates for '%s*': %s", lc->name, l->addr_s); listener_free(l); return -1; } } hlog(LOG_INFO, "SSL initialized for '%s': %s%s", lc->name, l->addr_s, (lc->cafile) ? " (client validation enabled)" : ""); } #endif /* Copy access lists */ if (lc->acl) l->acl = acl_dup(lc->acl); /* Copy filter definitions */ listener_copy_filters(l, lc); hlog(LOG_DEBUG, "... adding %s to listened sockets", l->addr_s); // put (first) in the list of listening sockets l->next = listen_list; l->prevp = &listen_list; if (listen_list) listen_list->prevp = &l->next; listen_list = l; return 0; }