diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index b28165bb3..03e8dc00c 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1149,13 +1149,18 @@ SSL enabled listeners. #### `ssl_version` This parameter controls the level of encryption used. Accepted values are: + * TLSv10 * TLSv11 * TLSv12 * MAX -Not all backend servers will support TLSv11 or TLSv12. If available, TLSv12 -should be used. +The default is to use the highest level of encryption available. For OpenSSL 1.0 +and newer this is TLSv1.2. Older versions use TLSv1.0 as the default transport +layer encryption. + +**Note:** It is highly recommended to leave this parameter to the default value + of _MAX_. This will guarantee that the strongest available encryption is used. #### `ssl_cert_verification_depth` diff --git a/include/maxscale/ssl.h b/include/maxscale/ssl.h index 42816c213..71e417e1d 100644 --- a/include/maxscale/ssl.h +++ b/include/maxscale/ssl.h @@ -31,7 +31,9 @@ struct dcb; typedef enum ssl_method_type { +#ifndef OPENSSL_1_1 SERVICE_TLS10, +#endif #ifdef OPENSSL_1_0 SERVICE_TLS11, SERVICE_TLS12, diff --git a/include/maxscale/utils.h b/include/maxscale/utils.h index ea5d7ef46..2e32ae6e1 100644 --- a/include/maxscale/utils.h +++ b/include/maxscale/utils.h @@ -24,7 +24,7 @@ MXS_BEGIN_DECLS -#define CALCLEN(i) ((size_t)(floor(log10(abs(i))) + 1)) +#define CALCLEN(i) ((size_t)(floor(log10(abs((int64_t)i))) + 1)) #define UINTLEN(i) (i<10 ? 1 : (i<100 ? 2 : (i<1000 ? 3 : CALCLEN(i)))) #define MXS_ARRAY_NELEMS(array) ((size_t)(sizeof(array)/sizeof(array[0]))) diff --git a/maxscale-system-test/CMakeLists.txt b/maxscale-system-test/CMakeLists.txt index d16438fac..d54c372f6 100644 --- a/maxscale-system-test/CMakeLists.txt +++ b/maxscale-system-test/CMakeLists.txt @@ -479,6 +479,10 @@ add_test_executable(mxs1045.cpp mxs1045 mxs1045 LABELS maxscale REPL_BACKEND) # https://jira.mariadb.org/browse/MXS-1123 add_test_executable(mxs1123.cpp mxs1123 mxs1123 LABELS maxscale REPL_BACKEND) +# MXS-1319: Maxscale selecting extra whitespace while loading users +# https://jira.mariadb.org/browse/MXS-1319 +add_test_executable(mxs1319.cpp mxs1319 replication LABELS MySQLAuth REPL_BACKEND) + # 'namedserverfilter' test add_test_executable(namedserverfilter.cpp namedserverfilter namedserverfilter LABELS namedserverfilter LIGHT REPL_BACKEND) diff --git a/maxscale-system-test/fw2/deny4 b/maxscale-system-test/fw2/deny4 index f000fa062..6a9af9f10 100644 --- a/maxscale-system-test/fw2/deny4 +++ b/maxscale-system-test/fw2/deny4 @@ -8,3 +8,5 @@ select * from test.t1 where 1 >= 1; select * from test.t1 where 1 <= 1; select * from test.t1 where 1 != 1; select * from test.t1 where 1 <> 1; +select function(*) from test.t1; +select insert(*) from test.t1; diff --git a/maxscale-system-test/fw2/deny5 b/maxscale-system-test/fw2/deny5 new file mode 100644 index 000000000..ab290eb4c --- /dev/null +++ b/maxscale-system-test/fw2/deny5 @@ -0,0 +1 @@ +select 1; diff --git a/maxscale-system-test/fw2/pass4 b/maxscale-system-test/fw2/pass4 index 5f597334b..6894c8432 100644 --- a/maxscale-system-test/fw2/pass4 +++ b/maxscale-system-test/fw2/pass4 @@ -3,3 +3,4 @@ create function my_function (arg int) returns int deterministic return arg * arg select "sum(1)"; select (1); select * from(select 1) as a; +insert into test.t1 values (1); diff --git a/maxscale-system-test/fw2/pass5 b/maxscale-system-test/fw2/pass5 new file mode 100644 index 000000000..3bbec0fac --- /dev/null +++ b/maxscale-system-test/fw2/pass5 @@ -0,0 +1 @@ +create or replace table t1 (id int); diff --git a/maxscale-system-test/fw2/rules4 b/maxscale-system-test/fw2/rules4 index f428c7c9a..c104917f8 100644 --- a/maxscale-system-test/fw2/rules4 +++ b/maxscale-system-test/fw2/rules4 @@ -1,4 +1,5 @@ rule test1 deny function sum avg on_queries select rule test2 deny function my_function on_queries select rule test3 deny function = >= <= != <> on_queries select -users %@% match any rules test1 test2 test3 +rule test4 deny function `function` `insert` +users %@% match any rules test1 test2 test3 test4 diff --git a/maxscale-system-test/fw2/rules5 b/maxscale-system-test/fw2/rules5 new file mode 100644 index 000000000..9b3902fa8 --- /dev/null +++ b/maxscale-system-test/fw2/rules5 @@ -0,0 +1,2 @@ +rule no_selects deny on_queries select +users %@% match any rules no_selects diff --git a/maxscale-system-test/fwf2.cpp b/maxscale-system-test/fwf2.cpp index fdda24663..bd282d4a9 100644 --- a/maxscale-system-test/fwf2.cpp +++ b/maxscale-system-test/fwf2.cpp @@ -65,7 +65,7 @@ int main(int argc, char *argv[]) FILE* file; sprintf(rules_dir, "%s/fw2/", test_dir); - int N = 4; + int N = 5; int i; for (i = 1; i < N + 1; i++) diff --git a/maxscale-system-test/mxs1319.cpp b/maxscale-system-test/mxs1319.cpp new file mode 100644 index 000000000..04d3aeda5 --- /dev/null +++ b/maxscale-system-test/mxs1319.cpp @@ -0,0 +1,23 @@ +/** + * Check that SQL_MODE='PAD_CHAR_TO_FULL_LENGTH' doesn't break authentication + */ + +#include "testconnections.h" + +int main(int argc, char *argv[]) +{ + TestConnections test(argc, argv); + + test.tprintf("Changing SQL_MODE to PAD_CHAR_TO_FULL_LENGTH and restarting MaxScale"); + test.repl->connect(); + test.repl->execute_query_all_nodes("SET GLOBAL SQL_MODE='PAD_CHAR_TO_FULL_LENGTH'"); + test.restart_maxscale(); + + test.tprintf("Connecting to MaxScale and executing a query"); + test.connect_maxscale(); + test.try_query(test.conn_rwsplit, "SELECT 1"); + test.close_maxscale_connections(); + + test.repl->execute_query_all_nodes("SET GLOBAL SQL_MODE=DEFAULT"); + return test.global_result; +} diff --git a/server/core/listener.cc b/server/core/listener.cc index 51d6509a9..7264fc7b8 100644 --- a/server/core/listener.cc +++ b/server/core/listener.cc @@ -169,10 +169,17 @@ void listener_free(SERV_LISTENER* listener) int listener_set_ssl_version(SSL_LISTENER *ssl_listener, char* version) { - if (strcasecmp(version, "TLSV10") == 0) + if (strcasecmp(version, "MAX") == 0) + { + ssl_listener->ssl_method_type = SERVICE_SSL_TLS_MAX; + } +#ifndef OPENSSL_1_1 + else if (strcasecmp(version, "TLSV10") == 0) { ssl_listener->ssl_method_type = SERVICE_TLS10; } +#else +#endif #ifdef OPENSSL_1_0 else if (strcasecmp(version, "TLSV11") == 0) { @@ -183,10 +190,6 @@ listener_set_ssl_version(SSL_LISTENER *ssl_listener, char* version) ssl_listener->ssl_method_type = SERVICE_TLS12; } #endif - else if (strcasecmp(version, "MAX") == 0) - { - ssl_listener->ssl_method_type = SERVICE_SSL_TLS_MAX; - } else { return -1; @@ -215,6 +218,20 @@ listener_set_certificates(SSL_LISTENER *ssl_listener, char* cert, char* key, cha ssl_listener->ssl_ca_cert = ca_cert ? MXS_STRDUP_A(ca_cert) : NULL; } +RSA* create_rsa(int bits) +{ +#ifdef OPENSSL_1_1 + BIGNUM* bn = BN_new(); + BN_set_word(bn, RSA_F4); + RSA* rsa = RSA_new(); + RSA_generate_key_ex(rsa, bits, NULL, NULL); + BN_free(bn); + return rsa; +#else + return RSA_generate_key(bits, RSA_F4, NULL, NULL); +#endif +} + /** * Initialize the listener's SSL context. This sets up the generated RSA * encryption keys, chooses the listener encryption level and configures the @@ -232,9 +249,11 @@ listener_init_SSL(SSL_LISTENER *ssl_listener) { switch (ssl_listener->ssl_method_type) { +#ifndef OPENSSL_1_1 case SERVICE_TLS10: ssl_listener->method = (SSL_METHOD*)TLSv1_method(); break; +#endif #ifdef OPENSSL_1_0 case SERVICE_TLS11: ssl_listener->method = (SSL_METHOD*)TLSv1_1_method(); @@ -273,34 +292,24 @@ listener_init_SSL(SSL_LISTENER *ssl_listener) SSL_CTX_set_options(ssl_listener->ctx, SSL_OP_NO_SSLv3); /** Generate the 512-bit and 1024-bit RSA keys */ - if (rsa_512 == NULL) + if (rsa_512 == NULL && (rsa_512 = create_rsa(512)) == NULL) { - rsa_512 = RSA_generate_key(512, RSA_F4, NULL, NULL); - if (rsa_512 == NULL) - { - MXS_ERROR("512-bit RSA key generation failed."); - return -1; - } + MXS_ERROR("512-bit RSA key generation failed."); + return -1; } - if (rsa_1024 == NULL) + if (rsa_1024 == NULL && (rsa_1024 = create_rsa(1024)) == NULL) { - rsa_1024 = RSA_generate_key(1024, RSA_F4, NULL, NULL); - if (rsa_1024 == NULL) - { - MXS_ERROR("1024-bit RSA key generation failed."); - return -1; - } + MXS_ERROR("1024-bit RSA key generation failed."); + return -1; } - if (rsa_512 != NULL && rsa_1024 != NULL) - { - SSL_CTX_set_tmp_rsa_callback(ssl_listener->ctx, tmp_rsa_callback); - } + ss_dassert(rsa_512 && rsa_1024); + SSL_CTX_set_tmp_rsa_callback(ssl_listener->ctx, tmp_rsa_callback); if (ssl_listener->ssl_cert && ssl_listener->ssl_key) { /** Load the server certificate */ - if (SSL_CTX_use_certificate_file(ssl_listener->ctx, ssl_listener->ssl_cert, SSL_FILETYPE_PEM) <= 0) + if (SSL_CTX_use_certificate_chain_file(ssl_listener->ctx, ssl_listener->ssl_cert) <= 0) { MXS_ERROR("Failed to set server SSL certificate."); return -1; @@ -363,7 +372,7 @@ tmp_rsa_callback(SSL *s, int is_export, int keylength) else { /* generate on the fly, should not happen in this example */ - rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL); + rsa_tmp = create_rsa(keylength); rsa_512 = rsa_tmp; /* Remember for later reuse */ } break; @@ -446,10 +455,11 @@ static bool create_listener_config(const SERV_LISTENER *listener, const char *fi switch (listener->ssl->ssl_method_type) { +#ifndef OPENSSL_1_1 case SERVICE_TLS10: version = "TLSV10"; break; - +#endif #ifdef OPENSSL_1_0 case SERVICE_TLS11: version = "TLSV11"; diff --git a/server/core/mysql_utils.cc b/server/core/mysql_utils.cc index 8b74ab714..32143996f 100644 --- a/server/core/mysql_utils.cc +++ b/server/core/mysql_utils.cc @@ -166,7 +166,22 @@ MYSQL *mxs_mysql_real_connect(MYSQL *con, SERVER *server, const char *user, cons mysql_ssl_set(con, listener->ssl_key, listener->ssl_cert, listener->ssl_ca_cert, NULL, NULL); } - return mysql_real_connect(con, server->name, user, passwd, NULL, server->port, NULL, 0); + MYSQL* mysql = mysql_real_connect(con, server->name, user, passwd, NULL, server->port, NULL, 0); + + if (mysql) + { + /** Copy the server charset */ + MY_CHARSET_INFO cs_info; + mysql_get_character_set_info(mysql, &cs_info); + server->charset = cs_info.number; + + if (mysql_query(mysql, "SET SQL_MODE=''")) + { + MXS_ERROR("Failed to change SQL_MODE: %s", mysql_error(mysql)); + } + } + + return mysql; } bool mxs_mysql_trim_quotes(char *s) diff --git a/server/core/server.cc b/server/core/server.cc index 194533cd9..ab2d6cde9 100644 --- a/server/core/server.cc +++ b/server/core/server.cc @@ -1213,10 +1213,11 @@ static bool create_server_config(const SERVER *server, const char *filename) switch (server->server_ssl->ssl_method_type) { +#ifndef OPENSSL_1_1 case SERVICE_TLS10: version = "TLSV10"; break; - +#endif #ifdef OPENSSL_1_0 case SERVICE_TLS11: version = "TLSV11"; diff --git a/server/core/ssl.cc b/server/core/ssl.cc index 59bb8bdd3..a2aa79367 100644 --- a/server/core/ssl.cc +++ b/server/core/ssl.cc @@ -196,20 +196,20 @@ const char* ssl_method_type_to_string(ssl_method_type_t method_type) { switch (method_type) { +#ifndef OPENSSL_1_1 case SERVICE_TLS10: - return "TLS10"; + return "TLSV10"; +#endif #ifdef OPENSSL_1_0 case SERVICE_TLS11: - return "TLS11"; + return "TLSV11"; case SERVICE_TLS12: - return "TLS12"; + return "TLSV12"; #endif case SERVICE_SSL_MAX: - return "SSL_MAX"; case SERVICE_TLS_MAX: - return "TLS_MAX"; case SERVICE_SSL_TLS_MAX: - return "SSL_TLS_MAX"; + return "MAX"; default: return "Unknown"; } diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.c b/server/modules/filter/dbfwfilter/dbfwfilter.c index bedfb3780..9730d361a 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.c +++ b/server/modules/filter/dbfwfilter/dbfwfilter.c @@ -1151,7 +1151,7 @@ bool create_rule(void* scanner, const char* name) if (ruledef && (ruledef->name = MXS_STRDUP(name))) { - ruledef->type = RT_UNDEFINED; + ruledef->type = RT_PERMISSION; ruledef->on_queries = FW_OP_UNDEFINED; ruledef->next = rstack->rule; ruledef->active = NULL; diff --git a/server/modules/filter/dbfwfilter/ruleparser.y b/server/modules/filter/dbfwfilter/ruleparser.y index f9b34ea9b..e5be55cf0 100644 --- a/server/modules/filter/dbfwfilter/ruleparser.y +++ b/server/modules/filter/dbfwfilter/ruleparser.y @@ -131,6 +131,7 @@ functionlist: functionvalue: FWTOK_CMP {if (!define_function_rule(scanner, $1)){YYERROR;}} | FWTOK_STR {if (!define_function_rule(scanner, $1)){YYERROR;}} + | FWTOK_BTSTR {if (!define_function_rule(scanner, $1)){YYERROR;}} ; optional: diff --git a/server/modules/protocol/examples/cdc_kafka_producer.py b/server/modules/protocol/examples/cdc_kafka_producer.py index f660ea781..ce87a6c29 100755 --- a/server/modules/protocol/examples/cdc_kafka_producer.py +++ b/server/modules/protocol/examples/cdc_kafka_producer.py @@ -30,6 +30,7 @@ parser.add_argument("-T", "--kafka-topic", dest="kafka_topic", opts = parser.parse_args(sys.argv[1:]) producer = KafkaProducer(bootstrap_servers=[opts.kafka_broker]) +sys.stdin = sys.stdin.detach() while True: try: diff --git a/server/modules/routing/avrorouter/avro_rbr.c b/server/modules/routing/avrorouter/avro_rbr.c index 77037694b..cc4ee24aa 100644 --- a/server/modules/routing/avrorouter/avro_rbr.c +++ b/server/modules/routing/avrorouter/avro_rbr.c @@ -164,7 +164,6 @@ bool handle_table_map_event(AVRO_INSTANCE *router, REP_HEADER *hdr, uint8_t *ptr } else { - ss_dassert(router->active_maps[old->id % MAX_MAPPED_TABLES] == old); router->active_maps[old->id % MAX_MAPPED_TABLES] = NULL; table_map_remap(ptr, ev_len, old); router->active_maps[old->id % MAX_MAPPED_TABLES] = old; diff --git a/server/modules/routing/binlogrouter/blr.h b/server/modules/routing/binlogrouter/blr.h index 4860889f1..babaa31bd 100644 --- a/server/modules/routing/binlogrouter/blr.h +++ b/server/modules/routing/binlogrouter/blr.h @@ -242,7 +242,7 @@ typedef enum #define BLR_MAX_BACKOFF 60 /* max size for error message returned to client */ -#define BINLOG_ERROR_MSG_LEN 385 +#define BINLOG_ERROR_MSG_LEN 700 /* network latency extra wait tme for heartbeat check */ #define BLR_NET_LATENCY_WAIT_TIME 1