Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…r applied
  • Loading branch information
p-alik committed Mar 16, 2017
1 parent 3e04a5e commit 39c0269
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 14 deletions.
7 changes: 7 additions & 0 deletions libgearman-1.0/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ int gearman_client_timeout(gearman_client_st *client);
GEARMAN_API
void gearman_client_set_timeout(gearman_client_st *client, int timeout);

/**
* See gearman_universal_set_ssl() for details.
*/
GEARMAN_API
void gearman_client_set_ssl(gearman_client_st *client, bool ssl,
const char *ca_file, const char *certificate, const char *key_file);

/**
* Get the application context for a client.
*
Expand Down
7 changes: 7 additions & 0 deletions libgearman-1.0/worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ int gearman_worker_timeout(gearman_worker_st *worker);
GEARMAN_API
void gearman_worker_set_timeout(gearman_worker_st *worker, int timeout);

/**
* See gearman_universal_set_ssl() for details.
*/
GEARMAN_API
void gearman_worker_set_ssl(gearman_worker_st *worker, bool ssl,
const char *ca_file, const char *certificate, const char *key_file);

/**
* Get the application context for a worker.
*
Expand Down
4 changes: 4 additions & 0 deletions libgearman-server/io.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ static size_t _connection_read(gearman_server_con_st *con, void *data, size_t da
case SSL_ERROR_SSL:
default:
{ // All other errors
if (ERR_peek_last_error())
{
ssl_error = ERR_peek_last_error();
}
char errorString[SSL_ERROR_SIZE];
ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
ret= GEARMAND_LOST_CONNECTION;
Expand Down
49 changes: 40 additions & 9 deletions libgearman-server/plugins/protocol/gear/protocol.cc
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,10 @@ static gearmand_error_t _gear_con_add(gearman_server_con_st *connection)
case SSL_ERROR_SSL:
case SSL_ERROR_ZERO_RETURN:
default:
if (ERR_peek_last_error())
{
cyassl_error = ERR_peek_last_error();
}
char cyassl_error_buffer[SSL_ERROR_SIZE]= { 0 };
ERR_error_string_n(cyassl_error, cyassl_error_buffer, sizeof(cyassl_error_buffer));
return gearmand_log_gerror(GEARMAN_DEFAULT_LOG_PARAM, GEARMAND_LOST_CONNECTION, "%s(%d)",
Expand All @@ -418,9 +422,9 @@ namespace protocol {
Gear::Gear() :
Plugin("Gear"),
_port(GEARMAN_DEFAULT_TCP_PORT_STRING),
_ssl_ca_file(GEARMAND_CA_CERTIFICATE),
_ssl_certificate(GEARMAND_SERVER_PEM),
_ssl_key(GEARMAND_SERVER_KEY),
_ssl_ca_file(""),
_ssl_certificate(""),
_ssl_key(""),
opt_ssl(false)
{
command_line_options().add_options()
Expand Down Expand Up @@ -477,19 +481,40 @@ gearmand_error_t Gear::start(gearmand_st *gearmand)

if (opt_ssl)
{
if (getenv("GEARMAND_CA_CERTIFICATE"))
if (_ssl_ca_file.empty())
{
_ssl_ca_file= getenv("GEARMAND_CA_CERTIFICATE");
if (getenv("GEARMAND_CA_CERTIFICATE"))
{
_ssl_ca_file= getenv("GEARMAND_CA_CERTIFICATE");
}
else
{
_ssl_ca_file= GEARMAND_CA_CERTIFICATE;
}
}

if (getenv("GEARMAND_SERVER_PEM"))
if (_ssl_certificate.empty())
{
_ssl_certificate= getenv("GEARMAND_SERVER_PEM");
if (getenv("GEARMAND_SERVER_PEM"))
{
_ssl_certificate= getenv("GEARMAND_SERVER_PEM");
}
else
{
_ssl_certificate= GEARMAND_SERVER_PEM;
}
}

if (getenv("GEARMAND_SERVER_KEY"))
if (_ssl_key.empty())
{
_ssl_key= getenv("GEARMAND_SERVER_KEY");
if (getenv("GEARMAND_SERVER_KEY"))
{
_ssl_key= getenv("GEARMAND_SERVER_KEY");
}
else
{
_ssl_key= GEARMAND_SERVER_KEY;
}
}

gearmand->init_ssl();
Expand All @@ -512,6 +537,12 @@ gearmand_error_t Gear::start(gearmand_st *gearmand)
}
gearmand_log_info(GEARMAN_DEFAULT_LOG_PARAM, "Loading certificate key : %s", _ssl_key.c_str());

if (SSL_CTX_check_private_key(gearmand->ctx_ssl()) != SSL_SUCCESS)
{
gearmand_log_fatal(GEARMAN_DEFAULT_LOG_PARAM, "SSL_CTX_check_private_key() cannot check certificate %s", _ssl_key.c_str());
}
gearmand_log_info(GEARMAN_DEFAULT_LOG_PARAM, "Checking certificate key : %s", _ssl_key.c_str());

assert(gearmand->ctx_ssl());
}
#endif
Expand Down
9 changes: 9 additions & 0 deletions libgearman/client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,15 @@ void gearman_client_set_timeout(gearman_client_st *client_shell, int timeout)
}
}

void gearman_client_set_ssl(gearman_client_st *client_shell, bool ssl,
const char *ca_file, const char *certificate, const char *key_file)
{
if (client_shell && client_shell->impl())
{
gearman_universal_set_ssl(client_shell->impl()->universal, ssl, ca_file, certificate, key_file);
}
}

void *gearman_client_context(const gearman_client_st *client_shell)
{
if (client_shell and client_shell->impl())
Expand Down
14 changes: 12 additions & 2 deletions libgearman/connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,8 @@ gearman_return_t gearman_connection_st::enable_ssl()
ERR_error_string_n(SSL_get_error(_ssl, 0), errorString, sizeof(errorString));
return gearman_error(universal, GEARMAN_COULD_NOT_CONNECT, errorString);
}

SSL_set_connect_state(_ssl);
}
#endif

Expand Down Expand Up @@ -858,7 +860,11 @@ gearman_return_t gearman_connection_st::flush()
case SSL_ERROR_SSL:
default:
{
char errorString[80];
if (ERR_peek_last_error())
{
ssl_error = ERR_peek_last_error();
}
char errorString[SSL_ERROR_SIZE];
ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
close_socket();
return gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT, "SSL failure(%s)", errorString);
Expand Down Expand Up @@ -1163,7 +1169,11 @@ size_t gearman_connection_st::recv_socket(void *data, size_t data_size, gearman_
case SSL_ERROR_SSL:
default:
{
char errorString[80];
if (ERR_peek_last_error())
{
ssl_error = ERR_peek_last_error();
}
char errorString[SSL_ERROR_SIZE];
ERR_error_string_n(ssl_error, errorString, sizeof(errorString));
close_socket();
return gearman_universal_set_error(universal, GEARMAN_LOST_CONNECTION, GEARMAN_AT, "SSL failure(%s)", errorString);
Expand Down
65 changes: 64 additions & 1 deletion libgearman/interface/universal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,18 @@ struct gearman_universal_st : public error_st
bool non_blocking;
bool no_new_data;
bool _ssl;
struct gearman_vector_st *_ssl_ca_file;
struct gearman_vector_st *_ssl_certificate;
struct gearman_vector_st *_ssl_key;

Options() :
dont_track_packets(false),
non_blocking(false),
no_new_data(false),
_ssl(false)
_ssl(false),
_ssl_ca_file(NULL),
_ssl_certificate(NULL),
_ssl_key(NULL)
{ }
} options;
gearman_verbose_t verbose;
Expand Down Expand Up @@ -208,6 +214,11 @@ struct gearman_universal_st : public error_st

const char* ssl_ca_file() const
{
if (options._ssl_ca_file && options._ssl_ca_file->size())
{
return options._ssl_ca_file->c_str();
}

if (getenv("GEARMAND_CA_CERTIFICATE"))
{
return getenv("GEARMAND_CA_CERTIFICATE");
Expand All @@ -216,8 +227,27 @@ struct gearman_universal_st : public error_st
return GEARMAND_CA_CERTIFICATE;
}

void ssl_ca_file(const char* ssl_ca_file_)
{
gearman_string_free(options._ssl_ca_file);
size_t ssl_ca_file_size_ = 0;
if (ssl_ca_file_ && (ssl_ca_file_size_ = strlen(ssl_ca_file_)))
{
options._ssl_ca_file = gearman_string_create(NULL, ssl_ca_file_, ssl_ca_file_size_);
}
else
{
options._ssl_ca_file = NULL;
}
}

const char* ssl_certificate() const
{
if (options._ssl_certificate && options._ssl_certificate->size())
{
return options._ssl_certificate->c_str();
}

if (getenv("GEARMAN_CLIENT_PEM"))
{
return getenv("GEARMAN_CLIENT_PEM");
Expand All @@ -226,8 +256,27 @@ struct gearman_universal_st : public error_st
return GEARMAN_CLIENT_PEM;
}

void ssl_certificate(const char *ssl_certificate_)
{
gearman_string_free(options._ssl_certificate);
size_t ssl_certificate_size_ = 0;
if (ssl_certificate_ && (ssl_certificate_size_ = strlen(ssl_certificate_)))
{
options._ssl_certificate = gearman_string_create(NULL, ssl_certificate_, ssl_certificate_size_);
}
else
{
options._ssl_certificate = NULL;
}
}

const char* ssl_key() const
{
if (options._ssl_key && options._ssl_key->size())
{
return options._ssl_key->c_str();
}

if (getenv("GEARMAN_CLIENT_KEY"))
{
return getenv("GEARMAN_CLIENT_KEY");
Expand All @@ -236,6 +285,20 @@ struct gearman_universal_st : public error_st
return GEARMAN_CLIENT_KEY;
}

void ssl_key(const char *ssl_key_)
{
gearman_string_free(options._ssl_key);
size_t ssl_key_size_ = 0;
if (ssl_key_ && (ssl_key_size_ = strlen(ssl_key_)))
{
options._ssl_key = gearman_string_create(NULL, ssl_key_, ssl_key_size_);
}
else
{
options._ssl_key = NULL;
}
}

private:
bool init_ssl();

Expand Down
38 changes: 37 additions & 1 deletion libgearman/universal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ void gearman_universal_set_timeout(gearman_universal_st &self, int timeout)
self.timeout= timeout;
}

void gearman_universal_set_ssl(gearman_universal_st &self, bool ssl,
const char *ca_file, const char *certificate, const char *key_file)
{
self.ssl(ssl);
self.ssl_ca_file(ca_file);
self.ssl_certificate(certificate);
self.ssl_key(key_file);
}

void gearman_set_log_fn(gearman_universal_st &self, gearman_log_fn *function,
void *context, gearman_verbose_t verbose)
{
Expand Down Expand Up @@ -470,10 +479,31 @@ bool gearman_universal_st::init_ssl()
if (ssl())
{
#if defined(HAVE_SSL) && HAVE_SSL
// Check these files exist or not to avoid coredump.
FILE *file = NULL;
if ((file = fopen(ssl_ca_file(), "r")) == NULL)
{
gearman_universal_set_error(*this, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT, "Failed to open CA certificate %s (%d: %s)", ssl_ca_file(), errno, strerror(errno));
return false;
}
fclose(file);
if ((file = fopen(ssl_certificate(), "r")) == NULL)
{
gearman_universal_set_error(*this, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT, "Failed to open certificate %s (%d: %s)", ssl_certificate(), errno, strerror(errno));
return false;
}
fclose(file);
if ((file = fopen(ssl_key(), "r")) == NULL)
{
gearman_universal_set_error(*this, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT, "Failed to open certificate key %s (%d: %s)", ssl_key(), errno, strerror(errno));
return false;
}
fclose(file);

SSL_load_error_strings();
SSL_library_init();

if ((_ctx_ssl= SSL_CTX_new(TLSv1_client_method())) == NULL)
if ((_ctx_ssl= SSL_CTX_new(SSLv23_client_method())) == NULL)
{
gearman_universal_set_error(*this, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT, "CyaTLSv1_client_method() failed");
return false;
Expand All @@ -496,6 +526,12 @@ bool gearman_universal_st::init_ssl()
gearman_universal_set_error(*this, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT, "Failed to load certificate key %s", ssl_key());
return false;
}

if (SSL_CTX_check_private_key(_ctx_ssl) != SSL_SUCCESS)
{
gearman_universal_set_error(*this, GEARMAN_INVALID_ARGUMENT, GEARMAN_AT, "Failed to check private key");
return false;
}
#endif // defined(HAVE_SSL) && HAVE_SSL
}

Expand Down
3 changes: 3 additions & 0 deletions libgearman/universal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ void gearman_universal_set_timeout(gearman_universal_st &self, int timeout);

int gearman_universal_timeout(gearman_universal_st &self);

void gearman_universal_set_ssl(gearman_universal_st &self, bool ssl,
const char *ca_file, const char *certificate, const char *key_file);

void gearman_universal_set_namespace(gearman_universal_st &self, const char *namespace_key, size_t namespace_key_size);

gearman_return_t cancel_job(gearman_universal_st& universal,
Expand Down
9 changes: 9 additions & 0 deletions libgearman/worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,15 @@ void gearman_worker_set_timeout(gearman_worker_st *worker, int timeout)
}
}

void gearman_worker_set_ssl(gearman_worker_st *worker_shell, bool ssl,
const char *ca_file, const char *certificate, const char *key_file)
{
if (worker_shell && worker_shell->impl())
{
gearman_universal_set_ssl(worker_shell->impl()->universal, ssl, ca_file, certificate, key_file);
}
}

void *gearman_worker_context(const gearman_worker_st *worker)
{
if (worker and worker->impl())
Expand Down
1 change: 1 addition & 0 deletions libgearman/worker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class Worker {

void enable_ssl()
{
return;
if (getenv("GEARMAND_CA_CERTIFICATE"))
{
gearman_worker_add_options(_worker, GEARMAN_WORKER_SSL);
Expand Down
Loading

0 comments on commit 39c0269

Please sign in to comment.