Added ssl handshake to mysql_client
This commit is contained in:
parent
449c186a66
commit
a572166ffd
@ -345,7 +345,7 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
|
||||
char *weightby;
|
||||
char *version_string;
|
||||
char *subservices;
|
||||
char* ssl;
|
||||
char *ssl,*ssl_cert,*ssl_key,*ssl_ca_cert;
|
||||
bool is_rwsplit = false;
|
||||
bool is_schemarouter = false;
|
||||
char *allow_localhost_match_wildcard_host;
|
||||
@ -355,7 +355,9 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
|
||||
auth = config_get_value(obj->parameters, "passwd");
|
||||
subservices = config_get_value(obj->parameters, "subservices");
|
||||
ssl = config_get_value(obj->parameters, "ssl");
|
||||
|
||||
ssl_cert = config_get_value(obj->parameters, "ssl_cert");
|
||||
ssl_key = config_get_value(obj->parameters, "ssl_key");
|
||||
ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert");
|
||||
enable_root_user = config_get_value(
|
||||
obj->parameters,
|
||||
"enable_root_user");
|
||||
@ -448,8 +450,28 @@ hashtable_memory_fns(monitorhash,strdup,NULL,free,NULL);
|
||||
"max_slave_replication_lag");
|
||||
|
||||
if(ssl)
|
||||
if(serviceSetSSL(obj->element,ssl) != 0)
|
||||
skygw_log_write(LE,"Error: Unknown parameter for service '%s': %s",obj->object,ssl);
|
||||
{
|
||||
if(ssl_cert == NULL)
|
||||
skygw_log_write(LE,"Error: Server certificate missing for service '%s'.",obj->object);
|
||||
if(ssl_ca_cert == NULL)
|
||||
skygw_log_write(LE,"Error: CA Certificate missing for service '%s'.",obj->object);
|
||||
if(ssl_key == NULL)
|
||||
skygw_log_write(LE,"Error: Server private key missing for service '%s'.",obj->object);
|
||||
|
||||
if(ssl_ca_cert != NULL && ssl_cert != NULL && ssl_key != NULL)
|
||||
{
|
||||
|
||||
if(serviceSetSSL(obj->element,ssl) != 0)
|
||||
{
|
||||
skygw_log_write(LE,"Error: Unknown parameter for service '%s': %s",obj->object,ssl);
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceSetCertificates(obj->element,ssl_cert,ssl_key,ssl_ca_cert);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (enable_root_user)
|
||||
serviceEnableRootUser(
|
||||
|
@ -137,6 +137,10 @@ SERVICE *service;
|
||||
service->users_from_all = false;
|
||||
service->resources = NULL;
|
||||
service->ssl_mode = SSL_DISABLED;
|
||||
service->ssl_init_done = false;
|
||||
service->ssl_ca_cert = NULL;
|
||||
service->ssl_cert = NULL;
|
||||
service->ssl_key = NULL;
|
||||
|
||||
if (service->name == NULL || service->routerModule == NULL)
|
||||
{
|
||||
@ -856,6 +860,14 @@ serviceOptimizeWildcard(SERVICE *service, int action)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
serviceSetCertificates(SERVICE *service, char* cert,char* key, char* ca_cert)
|
||||
{
|
||||
service->ssl_cert = strdup(cert);
|
||||
service->ssl_key = strdup(key);
|
||||
service->ssl_ca_cert = strdup(ca_cert);
|
||||
}
|
||||
|
||||
/** Enable or disable the service SSL capability*/
|
||||
int
|
||||
serviceSetSSL(SERVICE *service, char* action)
|
||||
@ -1798,3 +1810,41 @@ int *data;
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
int serviceInitSSL(SERVICE* service)
|
||||
{
|
||||
if(!service->ssl_init_done)
|
||||
{
|
||||
service->method = (SSL_METHOD*)SSLv23_server_method();
|
||||
service->ctx = SSL_CTX_new(service->method);
|
||||
|
||||
if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Load the private-key corresponding to the server certificate */
|
||||
if (SSL_CTX_use_PrivateKey_file(service->ctx, service->ssl_key, SSL_FILETYPE_PEM) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if the server certificate and private-key matches */
|
||||
if (!SSL_CTX_check_private_key(service->ctx)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Load the RSA CA certificate into the SSL_CTX structure */
|
||||
if (!SSL_CTX_load_verify_locations(service->ctx, service->ssl_ca_cert, NULL)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set to require peer (client) certificate verification */
|
||||
SSL_CTX_set_verify(service->ctx,SSL_VERIFY_PEER,NULL);
|
||||
|
||||
/* Set the verification depth to 1 */
|
||||
SSL_CTX_set_verify_depth(service->ctx,10);
|
||||
service->ssl_init_done = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,7 +26,9 @@
|
||||
#include <hashtable.h>
|
||||
#include <resultset.h>
|
||||
#include <maxconfig.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
/**
|
||||
* @file service.h
|
||||
*
|
||||
@ -158,6 +160,15 @@ typedef struct service {
|
||||
ssl_mode_t ssl_mode; /*< one of DISABLED, ENABLED or REQUIRED */
|
||||
char *weightby;
|
||||
struct service *next; /**< The next service in the linked list */
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl;
|
||||
SSL_METHOD *method; /*< SSLv2/3 or TLSv1/2 methods
|
||||
* see: https://www.openssl.org/docs/ssl/SSL_CTX_new.html */
|
||||
char* ssl_cert;
|
||||
char* ssl_key;
|
||||
char* ssl_ca_cert;
|
||||
bool ssl_init_done;
|
||||
|
||||
} SERVICE;
|
||||
|
||||
typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
|
||||
@ -186,6 +197,8 @@ extern int serviceSetUser(SERVICE *, char *, char *);
|
||||
extern int serviceGetUser(SERVICE *, char **, char **);
|
||||
extern void serviceSetFilters(SERVICE *, char *);
|
||||
extern int serviceSetSSL(SERVICE *service, char* action);
|
||||
extern int serviceInitSSL(SERVICE* service);
|
||||
extern void serviceSetCertificates(SERVICE *service, char* cert,char* key, char* ca_cert);
|
||||
extern int serviceEnableRootUser(SERVICE *, int );
|
||||
extern int serviceSetTimeout(SERVICE *, int );
|
||||
extern void serviceWeightBy(SERVICE *, char *);
|
||||
|
@ -54,7 +54,9 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <service.h>
|
||||
#include <router.h>
|
||||
#include <poll.h>
|
||||
@ -294,6 +296,7 @@ typedef struct {
|
||||
unsigned long tid; /*< MySQL Thread ID, in
|
||||
* handshake */
|
||||
unsigned int charset; /*< MySQL character set at connect time */
|
||||
SSL* ssl; /*< SSL struct for client connection */
|
||||
#if defined(SS_DEBUG)
|
||||
skygw_chk_t protocol_chk_tail;
|
||||
#endif
|
||||
|
@ -46,9 +46,7 @@
|
||||
#include <modinfo.h>
|
||||
#include <sys/stat.h>
|
||||
#include <modutil.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_GA,
|
||||
@ -116,6 +114,7 @@ void
|
||||
ModuleInit()
|
||||
{
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -484,9 +483,47 @@ static int gw_mysql_do_authentication(DCB *dcb, GWBUF *queue) {
|
||||
protocol->owner_dcb->service->name);
|
||||
}
|
||||
|
||||
/** Do the SSL Handshake */
|
||||
if(ssl && protocol->owner_dcb->service->ssl_mode != SSL_DISABLED)
|
||||
{
|
||||
if(serviceInitSSL(protocol->owner_dcb->service) != 0)
|
||||
{
|
||||
skygw_log_write(LOGFILE_ERROR,"Error: SSL initialization for service '%s' failed.",
|
||||
protocol->owner_dcb->service->name);
|
||||
return 1;
|
||||
}
|
||||
protocol->ssl = SSL_new(protocol->owner_dcb->service->ctx);
|
||||
SSL_set_fd(protocol->ssl,dcb->fd);
|
||||
protocol->protocol_auth_state = MYSQL_AUTH_SSL_REQ;
|
||||
printf("%s\n",SSL_get_version(protocol->ssl));
|
||||
int errnum,rval;
|
||||
char errbuf[1024];
|
||||
switch((rval = SSL_accept(protocol->ssl)))
|
||||
{
|
||||
case 0:
|
||||
errnum = SSL_get_error(protocol->ssl,rval);
|
||||
ERR_error_string(errnum,errbuf);
|
||||
skygw_log_write_flush(LOGFILE_ERROR,"SSL_accept: %s",errbuf);
|
||||
ERR_print_errors_fp(stdout);
|
||||
ERR_error_string(errnum,errbuf);
|
||||
printf("%s\n",errbuf);
|
||||
fflush(stdout);
|
||||
break;
|
||||
case 1:
|
||||
protocol->protocol_auth_state = MYSQL_AUTH_SSL_EXCHANGE_DONE;
|
||||
break;
|
||||
|
||||
default:
|
||||
errnum = SSL_get_error(protocol->ssl,rval);
|
||||
ERR_print_errors_fp(stdout);
|
||||
ERR_error_string(errnum,errbuf);
|
||||
printf("%s\n",errbuf);
|
||||
fflush(stdout);
|
||||
skygw_log_write_flush(LOGFILE_ERROR,"Error: Fatal error in SSL_accept: %s",errbuf);
|
||||
protocol->protocol_auth_state = MYSQL_AUTH_SSL_EXCHANGE_ERR;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
username = get_username_from_auth(username, client_auth_packet);
|
||||
@ -1700,4 +1737,3 @@ return_str:
|
||||
return str;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user