Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ project(libonion)

# Some tweak parameters
SET(ONION_USE_SSL true CACHE BOOL "Use SSL, requires GnuTLS")
SET(ONION_USE_OPENSSL false CACHE BOOL "Use SSL, requires OpenSSL")
SET(ONION_USE_PAM true CACHE BOOL "Compile PAM handler. Needs libpam")
SET(ONION_USE_PTHREADS true CACHE BOOL "Compile with pthreads support. Needed for O_THREAD and O_POOL modes")
SET(ONION_USE_PNG true CACHE BOOL "Adds support for simple image handler")
Expand Down Expand Up @@ -72,6 +73,18 @@ endif (${ONION_POLLER} STREQUAL "default")

message(STATUS "Using ${ONION_POLLER} as poller")

if (${ONION_USE_OPENSSL})
set(ONION_USE_SSL false)
set(GNUTLS_ENABLED false)
find_package(OpenSSL)
if (OPENSSL_FOUND)
set(OPENSSL_ENABLED true)
message(STATUS "SSL support(OpenSSL) is compiled in.")
else(OPENSSL_FOUND)
message("OpenSSL not found. SSL support is not compiled in.")
endif(OPENSSL_FOUND)
endif(${ONION_USE_OPENSSL})

if (${ONION_USE_SSL})
find_package(GnuTLS)
find_package(GCrypt)
Expand Down Expand Up @@ -202,6 +215,10 @@ if (GNUTLS_ENABLED)
add_definitions(-DHAVE_GNUTLS)
add_definitions(${GNUTLS_DEFINITIONS})
endif(GNUTLS_ENABLED)
if (OPENSSL_ENABLED)
add_definitions(-DHAVE_OPENSSL)
include_directories(${PROJECT_SOURCE_DIR}/src/onion/openssl)
endif(OPENSSL_ENABLED)
if (PTHREADS)
add_definitions(-DHAVE_PTHREADS)
endif(PTHREADS)
Expand Down
2 changes: 1 addition & 1 deletion examples/multiport-cpp/multiport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ int main(int argc, char*argv[]){
o.addListenPoint("localhost", "8080", Onion::HttpListenPoint());
o.addListenPoint("localhost", "8081", Onion::HttpListenPoint());

#ifdef HAVE_GNUTLS
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
Onion::HttpsListenPoint https;
https.setCertificate(O_SSL_CERTIFICATE_KEY, "cert.pem", "cert.key");
o.addListenPoint("localhost", "4443", std::move(https));
Expand Down
6 changes: 4 additions & 2 deletions examples/multiport/multiport.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ int main(int argc, char **argv){
onion_set_root_handler(o, onion_handler_export_local_new("."));
onion_add_listen_point(o, "localhost", "8080", onion_http_new());
onion_add_listen_point(o, "localhost", "8081", onion_http_new());
#ifdef HAVE_GNUTLS
onion_add_listen_point(o, "localhost", "4443", onion_https_new(O_SSL_CERTIFICATE_KEY, "cert.pem", "cert.key"));
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
onion_listen_point *https = onion_https_new();
onion_https_set_certificate(https, O_SSL_CERTIFICATE_KEY, "cert.pem", "cert.key");
onion_add_listen_point(o, "localhost", "4443", https);
#else
ONION_WARNING("HTTPS support is not enabled. Recompile with gnutls");
#endif
Expand Down
9 changes: 6 additions & 3 deletions src/onion/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ if (${REDIS_ENABLED})
LIST(APPEND SOURCES sessions_redis.c)
LIST(APPEND INCLUDES sessions_redis.h)
endif(${REDIS_ENABLED})
if (${GNUTLS_ENABLED})
if (GNUTLS_ENABLED OR OPENSSL_ENABLED)
MESSAGE(STATUS "Compiling HTTPS support")
LIST(APPEND SOURCES https.c random-gnutls.c)
else(${GNUTLS_ENABLED})
else(GNUTLS_ENABLED OR OPENSSL_ENABLED)
LIST(APPEND SOURCES random-default.c)
endif(${GNUTLS_ENABLED})
endif(GNUTLS_ENABLED OR OPENSSL_ENABLED)
if (${XML2_ENABLED})
MESSAGE(STATUS "Compiling WebDAV support")
include_directories(${LIBXML2_INCLUDE_DIR})
Expand All @@ -60,6 +60,9 @@ endif (${PAM_ENABLED})
if (GNUTLS_ENABLED)
LIST(APPEND LIBRARIES ${GCRYPT_LIBRARIES} ${GNUTLS_LIBRARIES})
endif(GNUTLS_ENABLED)
if (OPENSSL_ENABLED)
LIST(APPEND LIBRARIES ${OPENSSL_LIBRARIES})
endif(OPENSSL_ENABLED)
if (PTHREADS)
LIST(APPEND LIBRARIES pthread)
endif(PTHREADS)
Expand Down
4 changes: 2 additions & 2 deletions src/onion/codecs.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_GNUTLS
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#if GNUTLS_VERSION_NUMBER < 0x020A00
Expand Down Expand Up @@ -385,7 +385,7 @@ char *onion_c_quote(const char *str, char *ret, int l){
* @ingroup codecs
*/
void onion_sha1(const char *data, int length, char *result){
#ifndef HAVE_GNUTLS
#if !defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL)
ONION_ERROR("Cant calculate SHA1 if gnutls is not compiled in! Aborting now");
exit(1);
#else
Expand Down
74 changes: 74 additions & 0 deletions src/onion/https.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,16 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL;
* It has the main data for the connection; the setup certificate and such.
*/
struct onion_https_t{
#ifdef HAVE_GNUTLS
gnutls_certificate_credentials_t x509_cred;
gnutls_dh_params_t dh_params;
gnutls_priority_t priority_cache;
#else /* HAVE_GNUTLS */
#define x509_cred ctx
#define priority_cache ctx
SSL_CTX *ctx;
DH *dh_params;
#endif /* HAVE_GNUTLS */
};

typedef struct onion_https_t onion_https;
Expand Down Expand Up @@ -110,6 +117,9 @@ onion_listen_point *onion_https_new(){
//}

gnutls_global_init ();

#ifdef HAVE_GNUTLS

gnutls_certificate_allocate_credentials (&https->x509_cred);

// set cert here??
Expand Down Expand Up @@ -150,6 +160,32 @@ onion_listen_point *onion_https_new(){
}
gnutls_certificate_set_dh_params (https->x509_cred, https->dh_params);

#else /* HAVE_GNUTLS */

https->ctx = SSL_CTX_new(SSLv23_server_method());
https->dh_params = DH_get_1024_160();

if (!SSL_CTX_set_tmp_dh(https->ctx, https->dh_params)){
ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror());
SSL_CTX_free(https->ctx);
DH_free(https->dh_params);
op->free_user_data=NULL;
onion_listen_point_free(op);
onion_low_free(https);
return NULL;
}
if (!SSL_CTX_set_cipher_list(https->ctx, "HIGH:!aNULL:!MD5:!RC4")){
ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror());
SSL_CTX_free(https->ctx);
DH_free(https->dh_params);
op->free_user_data=NULL;
onion_listen_point_free(op);
onion_low_free(https);
return NULL;
}

#endif /* HAVE_GNUTLS */

ONION_DEBUG("HTTPS connection ready");

return op;
Expand Down Expand Up @@ -182,9 +218,14 @@ static void onion_https_free_user_data(onion_listen_point *op){
ONION_DEBUG("Free HTTPS %s:%s", op->hostname, op->port);
onion_https *https=(onion_https*)op->user_data;

#ifdef HAVE_GNUTLS
gnutls_certificate_free_credentials (https->x509_cred);
gnutls_dh_params_deinit(https->dh_params);
gnutls_priority_deinit (https->priority_cache);
#else /* HAVE_GNUTLS */
SSL_CTX_free(https->ctx);
DH_free(https->dh_params);
#endif /* HAVE_GNUTLS */
//if (op->server->flags&O_SSL_NO_DEINIT)
gnutls_global_deinit(); // This may cause problems if several characters use the gnutls on the same binary.
onion_low_free(https);
Expand All @@ -208,6 +249,8 @@ static int onion_https_request_init(onion_request *req){

gnutls_session_t session;

#ifdef HAVE_GNUTLS

gnutls_init (&session, GNUTLS_SERVER);
gnutls_priority_set (session, https->priority_cache);
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, https->x509_cred);
Expand All @@ -229,6 +272,37 @@ static int onion_https_request_init(onion_request *req){
return -1;
}

#else /* HAVE_GNUTLS */

session = SSL_new(https->ctx);

SSL_set_fd(session, req->connection.fd);
int ret = SSL_accept(session);
while (ret <= 0) {
switch (SSL_get_error(session, ret)) {
case SSL_ERROR_NONE:
break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
continue;
case SSL_ERROR_SYSCALL:
case SSL_ERROR_SSL:
case SSL_ERROR_ZERO_RETURN:
ONION_ERROR("Handshake has failed (%s)", gnutls_strerror());
gnutls_bye (session, GNUTLS_SHUT_WR);
gnutls_deinit(session);
onion_listen_point_request_close_socket(req);
return -1;
default:
break;
}

SSL_renegotiate(session);
SSL_write(session, NULL, 0);
}

#endif /* HAVE_GNUTLS */

req->connection.user_data=(void*)session;
return 0;
}
Expand Down
8 changes: 4 additions & 4 deletions src/onion/onion.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ onion_url_add_url(url, ...); // Nesting
*
* @subsection SSL SSL support
*
* libonion has SSL support by using GNUTLS. This is however optional, and you can disable compilation by
* libonion has SSL support by using GNUTLS/OpenSSL. This is however optional, and you can disable compilation by
* not having the development libraries, or modifing /CMakeLists.txt.
*
* Once you have support most basic use is just to set a certificate and key file (can be be on the same PEM file).
Expand Down Expand Up @@ -171,7 +171,7 @@ onion_url_add_url(url, ...); // Nesting
static int onion_default_error(void *handler, onion_request *req, onion_response *res);
// Import it here as I need it to know if we have a HTTP port.
ssize_t onion_http_write(onion_request *req, const char *data, size_t len);
#ifdef HAVE_GNUTLS
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
ssize_t onion_https_write(onion_request *req, const char *data, size_t len);
#endif

Expand Down Expand Up @@ -827,7 +827,7 @@ int onion_set_certificate(onion *onion, onion_ssl_certificate_type type, const c

/// Set a certificate for use in the connection
int onion_set_certificate_va(onion *onion, onion_ssl_certificate_type type, const char *filename, va_list va){
#ifdef HAVE_GNUTLS
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
if (!onion->listen_points){
onion_add_listen_point(onion,NULL,NULL,onion_https_new());
}
Expand Down Expand Up @@ -859,7 +859,7 @@ int onion_set_certificate_va(onion *onion, onion_ssl_certificate_type type, cons

return r;
#else
ONION_ERROR("GNUTLS is not enabled. Recompile onion with GNUTLS support");
ONION_ERROR("SSL is not enabled. Recompile onion with SSL support");
return -1;
#endif
}
Expand Down
50 changes: 50 additions & 0 deletions src/onion/openssl/gcrypt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Onion HTTP server library
Copyright (C) 2010-2016 David Moreno Montero and others

This library is free software; you can redistribute it and/or
modify it under the terms of, at your choice:

a. the Apache License Version 2.0.

b. the GNU General Public License as published by the
Free Software Foundation; either version 2.0 of the License,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of both libraries, if not see
<http://www.gnu.org/licenses/> and
<http://www.apache.org/licenses/LICENSE-2.0>.
*/

#ifndef ONION_OPENSSL_GCRYPT_H
#define ONION_OPENSSL_GCRYPT_H

#include <openssl/evp.h>

#ifdef __cplusplus
extern "C"{
#endif

#define GCRYPT_VERSION_NUMBER 000000

#define GCRY_THREAD_OPTION_PTHREAD_IMPL

#define GCRY_MD_SHA1 EVP_sha1()

#define gcry_control(...)

#define gcry_md_hash_buffer(MD, R, D, L) \
EVP_Digest(D, L, (unsigned char *)R, NULL, MD, NULL)

#define gcry_create_nonce RAND_pseudo_bytes

#ifdef __cplusplus
}
#endif

#endif
35 changes: 35 additions & 0 deletions src/onion/openssl/gnutls/crypto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Onion HTTP server library
Copyright (C) 2010-2016 David Moreno Montero and others

This library is free software; you can redistribute it and/or
modify it under the terms of, at your choice:

a. the Apache License Version 2.0.

b. the GNU General Public License as published by the
Free Software Foundation; either version 2.0 of the License,
or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of both libraries, if not see
<http://www.gnu.org/licenses/> and
<http://www.apache.org/licenses/LICENSE-2.0>.
*/

#ifndef ONION_OPENSSL_CRYPTO_H
#define ONION_OPENSSL_CRYPTO_H

#ifdef __cplusplus
extern "C"{
#endif

#ifdef __cplusplus
}
#endif

#endif
Loading