/** * @short Removes the allocated data * @memberof onion_t */ void onion_free(onion *onion){ ONION_DEBUG("Onion free"); onion_listen_stop(onion); if (onion->poller) onion_poller_free(onion->poller); if (onion->username) free(onion->username); if (onion->listen_points){ onion_listen_point **p=onion->listen_points; while(*p!=NULL){ ONION_DEBUG("Free %p listen_point", *p); onion_listen_point_free(*p++); } free(onion->listen_points); } if (onion->root_handler) onion_handler_free(onion->root_handler); if (onion->internal_error_handler) onion_handler_free(onion->internal_error_handler); onion_mime_set(NULL); if (onion->sessions) onion_sessions_free(onion->sessions); #ifdef HAVE_PTHREADS if (onion->threads) free(onion->threads); #endif free(onion); }
/** * @short Removes the allocated data * @memberof onion_t */ void onion_free(onion *onion){ ONION_DEBUG("Onion free"); if (onion->flags&O_LISTENING) onion_listen_stop(onion); if (onion->poller) onion_poller_free(onion->poller); if (onion->username) onion_low_free(onion->username); if (onion->listen_points){ onion_listen_point **p=onion->listen_points; while(*p!=NULL){ ONION_DEBUG("Free %p listen_point", *p); onion_listen_point_free(*p++); } onion_low_free(onion->listen_points); } if (onion->root_handler) onion_handler_free(onion->root_handler); if (onion->internal_error_handler) onion_handler_free(onion->internal_error_handler); onion_mime_set(NULL); if (onion->sessions) onion_sessions_free(onion->sessions); { #ifdef HAVE_PTHREADS pthread_mutex_lock (&onion->mutex); #endif void* data = onion->client_data; onion->client_data = NULL; if (data && onion->client_data_free) onion->client_data_free (data); onion->client_data_free = NULL; #ifdef HAVE_PTHREADS pthread_mutex_unlock (&onion->mutex); pthread_mutex_destroy (&onion->mutex); #endif }; #ifdef HAVE_PTHREADS if (onion->threads) onion_low_free(onion->threads); #endif if (!(onion->flags&O_NO_SIGTERM)){ signal(SIGINT,SIG_DFL); signal(SIGTERM,SIG_DFL); } last_onion=NULL; onion_low_free(onion); }
/// Set a certificate for use in the connection int onion_set_certificate(onion *onion, onion_ssl_certificate_type type, const char *filename,...){ #ifdef HAVE_GNUTLS if (!onion->listen_points){ onion_add_listen_point(onion,NULL,NULL,onion_https_new()); } else{ onion_listen_point *first_listen_point=onion->listen_points[0]; if (first_listen_point->write!=onion_https_write){ if (first_listen_point->write!=onion_http_write){ ONION_ERROR("First listen point is not HTTP not HTTPS. Refusing to promote it to HTTPS. Use proper onion_https_new."); return -1; } ONION_DEBUG("Promoting from HTTP to HTTPS"); char *port=first_listen_point->port ? strdup(first_listen_point->port) : NULL; char *hostname=first_listen_point->hostname ? strdup(first_listen_point->hostname) : NULL; onion_listen_point_free(first_listen_point); onion_listen_point *https=onion_https_new(); if (NULL==https){ ONION_ERROR("Could not promote from HTTP to HTTPS. Certificate not set."); } https->port=port; https->hostname=hostname; onion->listen_points[0]=https; first_listen_point=https; } } va_list va; va_start(va, filename); int r=onion_https_set_certificate_argv(onion->listen_points[0], type, filename,va); va_end(va); return r; #else ONION_ERROR("GNUTLS is not enabled. Recompile onion with GNUTLS support"); return -1; #endif }
/** * @short Creates a new listen point with HTTPS powers. * @memberof onion_https_t * * Creates the HTTPS listen point. * * Might be called with (O_SSL_NONE,NULL), and set up the certificate later with onion_https_set_certificate. * * @param type Type of certificate to setup * @param filename File from where to get the data * @param ... More types and filenames until O_SSL_NONE. * @returns An onion_listen_point with the desired data, ready to start listening. */ onion_listen_point *onion_https_new(){ onion_listen_point *op=onion_listen_point_new(); op->request_init=onion_https_request_init; op->free_user_data=onion_https_free_user_data; op->listen_stop=onion_https_listen_stop; op->read=onion_https_read; op->write=onion_https_write; op->close=onion_https_close; op->read_ready=onion_http_read_ready; op->secure = true; op->user_data=onion_low_calloc(1,sizeof(onion_https)); onion_https *https=(onion_https*)op->user_data; #ifdef HAVE_PTHREADS gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif //if (!(o->flags&O_USE_DEV_RANDOM)){ gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); //} gnutls_global_init (); gnutls_certificate_allocate_credentials (&https->x509_cred); // set cert here?? //onion_https_set_certificate(op,O_SSL_CERTIFICATE_KEY, "mycert.pem","mycert.pem"); int e; int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW); e=gnutls_dh_params_init (&https->dh_params); if (e<0){ ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e)); gnutls_certificate_free_credentials (https->x509_cred); op->free_user_data=NULL; onion_listen_point_free(op); onion_low_free(https); return NULL; } e=gnutls_dh_params_generate2 (https->dh_params, bits); if (e<0){ ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e)); gnutls_certificate_free_credentials (https->x509_cred); op->free_user_data=NULL; onion_listen_point_free(op); onion_low_free(https); return NULL; } e=gnutls_priority_init (&https->priority_cache, "PERFORMANCE:%SAFE_RENEGOTIATION:-VERS-TLS1.0", NULL); if (e<0){ ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e)); gnutls_certificate_free_credentials (https->x509_cred); gnutls_dh_params_deinit(https->dh_params); op->free_user_data=NULL; onion_listen_point_free(op); onion_low_free(https); return NULL; } gnutls_certificate_set_dh_params (https->x509_cred, https->dh_params); gnutls_priority_init (&https->priority_cache, "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL); // PERFORMANCE:%SAFE_RENEGOTIATION:-VERS-TLS1.0:%COMPAT" ONION_DEBUG("HTTPS connection ready"); return op; }