diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-07-01 18:15:00 +0000 |
commit | a2a2e32c02643a0cec111511220227703fda1cd5 (patch) | |
tree | 69cc2b631234c2a8e026b9cd4d72676c61c594df /libmariadb/plugins/auth | |
parent | Releasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff) | |
download | mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.tar.xz mariadb-a2a2e32c02643a0cec111511220227703fda1cd5.zip |
Merging upstream version 1:11.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libmariadb/plugins/auth')
-rw-r--r-- | libmariadb/plugins/auth/CMakeLists.txt | 5 | ||||
-rw-r--r-- | libmariadb/plugins/auth/auth_gssapi_client.c | 3 | ||||
-rw-r--r-- | libmariadb/plugins/auth/caching_sha2_pw.c | 3 | ||||
-rw-r--r-- | libmariadb/plugins/auth/dialog.c | 3 | ||||
-rw-r--r-- | libmariadb/plugins/auth/ed25519.c | 35 | ||||
-rw-r--r-- | libmariadb/plugins/auth/mariadb_cleartext.c | 3 | ||||
-rw-r--r-- | libmariadb/plugins/auth/my_auth.c | 124 | ||||
-rw-r--r-- | libmariadb/plugins/auth/old_password.c | 3 | ||||
-rw-r--r-- | libmariadb/plugins/auth/ref10/crypto_sign.h | 2 | ||||
-rw-r--r-- | libmariadb/plugins/auth/ref10/sign.c | 3 | ||||
-rw-r--r-- | libmariadb/plugins/auth/sha256_pw.c | 3 |
11 files changed, 154 insertions, 33 deletions
diff --git a/libmariadb/plugins/auth/CMakeLists.txt b/libmariadb/plugins/auth/CMakeLists.txt index 83e324b9..d04fc7f1 100644 --- a/libmariadb/plugins/auth/CMakeLists.txt +++ b/libmariadb/plugins/auth/CMakeLists.txt @@ -108,12 +108,12 @@ IF(NOT WIN32) ELSE() SET(GSSAPI_LIBS secur32) SET(GSSAPI_SOURCES ${AUTH_DIR}/auth_gssapi_client.c ${AUTH_DIR}/sspi_client.c ${AUTH_DIR}/sspi_errmsg.c) - SET(AUTH_GSSAPI_DEFAULT_CONFIG STATIC) + SET(AUTH_GSSAPI_DEFAULT_CONFIG DYNAMIC_AND_STATIC) ENDIF() IF(GSSAPI_SOURCES) REGISTER_PLUGIN(TARGET auth_gssapi_client TYPE MARIADB_CLIENT_PLUGIN_AUTH - CONFIGURATIONS DYNAMIC STATIC OFF + CONFIGURATIONS DYNAMIC STATIC OFF DYNAMIC_AND_STATIC DEFAULT ${AUTH_GSSAPI_DEFAULT_CONFIG} SOURCES ${GSSAPI_SOURCES} INCLUDES ${CC_SOURCE_DIR}/plugins/auth ${GSSAPI_INCS} @@ -131,6 +131,7 @@ REGISTER_PLUGIN(TARGET mysql_old_password TYPE MARIADB_CLIENT_PLUGIN_AUTH CONFIGURATIONS STATIC DYNAMIC OFF DEFAULT STATIC + DISABLED YES SOURCES ${AUTH_DIR}/old_password.c) # Cleartext diff --git a/libmariadb/plugins/auth/auth_gssapi_client.c b/libmariadb/plugins/auth/auth_gssapi_client.c index 6f6c6ceb..19cdf246 100644 --- a/libmariadb/plugins/auth/auth_gssapi_client.c +++ b/libmariadb/plugins/auth/auth_gssapi_client.c @@ -117,5 +117,6 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = NULL, NULL, NULL, - gssapi_auth_client + gssapi_auth_client, + NULL }; diff --git a/libmariadb/plugins/auth/caching_sha2_pw.c b/libmariadb/plugins/auth/caching_sha2_pw.c index b442e477..14abb0c8 100644 --- a/libmariadb/plugins/auth/caching_sha2_pw.c +++ b/libmariadb/plugins/auth/caching_sha2_pw.c @@ -145,7 +145,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = auth_caching_sha2_init, auth_caching_sha2_deinit, NULL, - auth_caching_sha2_client + auth_caching_sha2_client, + NULL }; #ifdef HAVE_WINCRYPT diff --git a/libmariadb/plugins/auth/dialog.c b/libmariadb/plugins/auth/dialog.c index 31d7b7d8..8513e9ac 100644 --- a/libmariadb/plugins/auth/dialog.c +++ b/libmariadb/plugins/auth/dialog.c @@ -58,7 +58,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = auth_dialog_init, NULL, NULL, - auth_dialog_open + auth_dialog_open, + NULL }; diff --git a/libmariadb/plugins/auth/ed25519.c b/libmariadb/plugins/auth/ed25519.c index 38b896f8..ff2f39a5 100644 --- a/libmariadb/plugins/auth/ed25519.c +++ b/libmariadb/plugins/auth/ed25519.c @@ -64,6 +64,7 @@ static int auth_ed25519_init(char *unused1, size_t unused2, int unused3, va_list); +static int auth_ed25519_hash(MYSQL *, unsigned char *out, size_t *outlen); #ifndef PLUGIN_DYNAMIC @@ -77,21 +78,25 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = "client_ed25519", "Sergei Golubchik, Georg Richter", "Ed25519 Authentication Plugin", - {0,1,0}, + {0,1,1}, "LGPL", NULL, auth_ed25519_init, auth_ed25519_deinit, NULL, - auth_ed25519_client + auth_ed25519_client, + auth_ed25519_hash }; static int auth_ed25519_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) { unsigned char *packet, - signature[CRYPTO_BYTES + NONCE_BYTES]; - int pkt_len; + signature[CRYPTO_BYTES + NONCE_BYTES], + pk[CRYPTO_PUBLICKEYBYTES]; + unsigned long long pkt_len; + size_t pwlen= strlen(mysql->passwd); + char *newpw; /* Step 1: Server sends nonce @@ -106,16 +111,36 @@ static int auth_ed25519_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) return CR_SERVER_HANDSHAKE_ERR; /* Sign nonce: the crypto_sign function is part of ref10 */ - ma_crypto_sign(signature, packet, NONCE_BYTES, (unsigned char*)mysql->passwd, strlen(mysql->passwd)); + ma_crypto_sign(signature, pk, packet, NONCE_BYTES, (unsigned char*)mysql->passwd, pwlen); /* send signature to server */ if (vio->write_packet(vio, signature, CRYPTO_BYTES)) return CR_ERROR; + /* save pk for the future auth_ed25519_hash() call */ + if ((newpw= realloc(mysql->passwd, pwlen + 1 + sizeof(pk)))) + { + memcpy(newpw + pwlen + 1, pk, sizeof(pk)); + mysql->passwd= newpw; + } + return CR_OK; } /* }}} */ +/* {{{ static int auth_ed25519_hash */ +static int auth_ed25519_hash(MYSQL *mysql, unsigned char *out, size_t *outlen) +{ + if (*outlen < CRYPTO_PUBLICKEYBYTES) + return 1; + *outlen= CRYPTO_PUBLICKEYBYTES; + + /* use the cached value */ + memcpy(out, mysql->passwd + strlen(mysql->passwd) + 1, CRYPTO_PUBLICKEYBYTES); + return 0; +} +/* }}} */ + /* {{{ static int auth_ed25519_init */ static int auth_ed25519_init(char *unused1 __attribute__((unused)), size_t unused2 __attribute__((unused)), diff --git a/libmariadb/plugins/auth/mariadb_cleartext.c b/libmariadb/plugins/auth/mariadb_cleartext.c index b63c1d3b..92e56547 100644 --- a/libmariadb/plugins/auth/mariadb_cleartext.c +++ b/libmariadb/plugins/auth/mariadb_cleartext.c @@ -70,7 +70,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = NULL, NULL, NULL, - clear_password_auth_client + clear_password_auth_client, + NULL }; diff --git a/libmariadb/plugins/auth/my_auth.c b/libmariadb/plugins/auth/my_auth.c index 72773079..faea968c 100644 --- a/libmariadb/plugins/auth/my_auth.c +++ b/libmariadb/plugins/auth/my_auth.c @@ -3,16 +3,29 @@ #include <errmsg.h> #include <string.h> #include <ma_common.h> +#include <ma_crypt.h> #include <mysql/client_plugin.h> typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t; static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t); static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql); +static int native_password_hash(MYSQL *mysql, unsigned char *out, size_t *outlen); static int dummy_fallback_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql __attribute__((unused))); extern void read_user_name(char *name); extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer); extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length); extern unsigned char *mysql_net_store_length(unsigned char *packet, ulonglong length); +extern const char *disabled_plugins; + +#define hashing(p) (p->interface_version >= 0x0101 && p->hash_password_bin) + +static int set_error_from_tls_self_signed_error(MYSQL *mysql) +{ + my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, + ER(CR_SSL_CONNECTION_ERROR), mysql->net.tls_self_signed_error); + reset_tls_self_signed_error(mysql); + return 1; +} typedef struct { int (*read_packet)(struct st_plugin_vio *vio, uchar **buf); @@ -44,13 +57,14 @@ auth_plugin_t mysql_native_password_client_plugin= native_password_plugin_name, "R.J.Silk, Sergei Golubchik", "Native MySQL authentication", - {1, 0, 0}, + {1, 0, 1}, "LGPL", NULL, NULL, NULL, NULL, - native_password_auth_client + native_password_auth_client, + native_password_hash }; @@ -97,6 +111,22 @@ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) return CR_OK; } +static int native_password_hash(MYSQL *mysql, unsigned char *out, size_t *out_length) +{ + unsigned char digest[MA_SHA1_HASH_SIZE]; + + if (*out_length < MA_SHA1_HASH_SIZE) + return 1; + *out_length= MA_SHA1_HASH_SIZE; + + /* would it be better to reuse instead of recalculating here? see ed25519 */ + ma_hash(MA_HASH_SHA1, (unsigned char*)mysql->passwd, strlen(mysql->passwd), + digest); + ma_hash(MA_HASH_SHA1, digest, sizeof(digest), out); + + return 0; +} + auth_plugin_t dummy_fallback_client_plugin= { MYSQL_CLIENT_AUTHENTICATION_PLUGIN, @@ -110,7 +140,8 @@ auth_plugin_t dummy_fallback_client_plugin= NULL, NULL, NULL, - dummy_fallback_auth_client + dummy_fallback_auth_client, + NULL }; @@ -223,7 +254,7 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, if (mysql->options.ssl_key || mysql->options.ssl_cert || mysql->options.ssl_ca || mysql->options.ssl_capath || mysql->options.ssl_cipher || mysql->options.use_ssl || - mysql->options.extension->tls_verify_server_cert) + !mysql->options.extension->tls_allow_invalid_server_cert) mysql->options.use_ssl= 1; if (mysql->options.use_ssl) mysql->client_flag|= CLIENT_SSL; @@ -243,15 +274,16 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, mysql->net.pvio->type == PVIO_TYPE_SHAREDMEM)) { mysql->server_capabilities &= ~(CLIENT_SSL); + mysql->options.extension->tls_allow_invalid_server_cert= 1; } /* if server doesn't support SSL and verification of server certificate was set to mandatory, we need to return an error */ if (mysql->options.use_ssl && !(mysql->server_capabilities & CLIENT_SSL)) { - if (mysql->options.extension->tls_verify_server_cert || - (mysql->options.extension && (mysql->options.extension->tls_fp || - mysql->options.extension->tls_fp_list))) + if (!mysql->options.extension->tls_allow_invalid_server_cert || + mysql->options.extension->tls_fp || + mysql->options.extension->tls_fp_list) { my_set_error(mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, ER(CR_SSL_CONNECTION_ERROR), @@ -307,9 +339,11 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, if (!(mysql->server_capabilities & CLIENT_MYSQL)) { uint server_extended_cap= mysql->extension->mariadb_server_capabilities; - uint client_extended_cap= (uint)(MARIADB_CLIENT_SUPPORTED_FLAGS >> 32); + ulonglong client_extended_flag = CLIENT_DEFAULT_EXTENDED_FLAGS; + if (mysql->options.extension && mysql->options.extension->bulk_unit_results) + client_extended_flag|= MARIADB_CLIENT_BULK_UNIT_RESULTS; mysql->extension->mariadb_client_flag= - server_extended_cap & client_extended_cap; + server_extended_cap & (long)(client_extended_flag >> 32); int4store(buff + 28, mysql->extension->mariadb_client_flag); } end= buff+32; @@ -350,6 +384,13 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, } if (ma_pvio_start_ssl(mysql->net.pvio)) goto error; + if (mysql->net.tls_self_signed_error && + (!mysql->passwd || !mysql->passwd[0] || !hashing(mpvio->plugin))) + { + /* cannot use auth to validate the cert */ + set_error_from_tls_self_signed_error(mysql); + goto error; + } } #endif /* HAVE_TLS */ @@ -658,13 +699,13 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, retry: mpvio.plugin= auth_plugin; - if (auth_plugin_name && - mysql->options.extension && - mysql->options.extension->restricted_auth) + if (auth_plugin_name) { - if (!strstr(mysql->options.extension->restricted_auth, auth_plugin_name)) + if ((mysql->options.extension && mysql->options.extension->restricted_auth) + ? !strstr(mysql->options.extension->restricted_auth, auth_plugin_name) + : strstr(disabled_plugins, auth_plugin_name) != NULL) { - my_set_error(mysql, CR_PLUGIN_NOT_ALLOWED, SQLSTATE_UNKNOWN, 0, data_plugin); + my_set_error(mysql, CR_PLUGIN_NOT_ALLOWED, SQLSTATE_UNKNOWN, 0, auth_plugin_name); return 1; } } @@ -727,15 +768,62 @@ retry: auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN))) auth_plugin= &dummy_fallback_client_plugin; + /* can we use this plugin with this tls server cert ? */ + if (mysql->net.tls_self_signed_error && !hashing(auth_plugin)) + return set_error_from_tls_self_signed_error(mysql); goto retry; - } /* net->read_pos[0] should always be 0 here if the server implements the protocol correctly */ - if (mysql->net.read_pos[0] == 0) - return ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length); - return 1; + if (mysql->net.read_pos[0] != 0) + return 1; + if (ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length)) + return -1; + + if (!mysql->net.tls_self_signed_error) + return 0; + + assert(mysql->options.use_ssl); + assert(!mysql->options.extension->tls_allow_invalid_server_cert); + assert(!mysql->options.ssl_ca); + assert(!mysql->options.ssl_capath); + assert(!mysql->options.extension->tls_fp); + assert(!mysql->options.extension->tls_fp_list); + assert(hashing(auth_plugin)); + assert(mysql->passwd[0]); + if (mysql->info && mysql->info[0] == '\1') + { + MA_HASH_CTX *ctx = NULL; + unsigned char buf[1024], digest[MA_SHA256_HASH_SIZE]; + char fp[128], hexdigest[sizeof(digest)*2+1], *hexsig= mysql->info + 1; + size_t buflen= sizeof(buf) - 1, fplen; + + mysql->info= NULL; /* no need to confuse the client with binary info */ + + if (!(fplen= ma_tls_get_finger_print(mysql->net.pvio->ctls, MA_HASH_SHA256, + fp, sizeof(fp)))) + return 1; /* error is already set */ + + if (auth_plugin->hash_password_bin(mysql, buf, &buflen) || + !(ctx= ma_hash_new(MA_HASH_SHA256))) + { + SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); + return 1; + } + + ma_hash_input(ctx, (unsigned char*)buf, buflen); + ma_hash_input(ctx, (unsigned char*)mysql->scramble_buff, SCRAMBLE_LENGTH); + ma_hash_input(ctx, (unsigned char*)fp, fplen); + ma_hash_result(ctx, digest); + ma_hash_free(ctx); + + mysql_hex_string(hexdigest, (char*)digest, sizeof(digest)); + if (strcmp(hexdigest, hexsig) == 0) + return 0; /* phew. self-signed certificate is validated! */ + } + + return set_error_from_tls_self_signed_error(mysql); } diff --git a/libmariadb/plugins/auth/old_password.c b/libmariadb/plugins/auth/old_password.c index 07756e92..3f7d533c 100644 --- a/libmariadb/plugins/auth/old_password.c +++ b/libmariadb/plugins/auth/old_password.c @@ -63,7 +63,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = NULL, NULL, NULL, - auth_old_password + auth_old_password, + NULL }; /** diff --git a/libmariadb/plugins/auth/ref10/crypto_sign.h b/libmariadb/plugins/auth/ref10/crypto_sign.h index 5f9b3437..3c676885 100644 --- a/libmariadb/plugins/auth/ref10/crypto_sign.h +++ b/libmariadb/plugins/auth/ref10/crypto_sign.h @@ -3,7 +3,7 @@ int crypto_sign_keypair( unsigned char *pw, unsigned long long pwlen ); int ma_crypto_sign( - unsigned char *sm, + unsigned char *sm, unsigned char *pk, const unsigned char *m, unsigned long long mlen, const unsigned char *pw, unsigned long long pwlen ); diff --git a/libmariadb/plugins/auth/ref10/sign.c b/libmariadb/plugins/auth/ref10/sign.c index b4153201..421a0aed 100644 --- a/libmariadb/plugins/auth/ref10/sign.c +++ b/libmariadb/plugins/auth/ref10/sign.c @@ -5,7 +5,7 @@ #include "sc.h" int ma_crypto_sign( - unsigned char *sm, + unsigned char *sm, unsigned char *pk, const unsigned char *m,unsigned long long mlen, const unsigned char *pw,unsigned long long pwlen ) @@ -26,6 +26,7 @@ int ma_crypto_sign( ge_scalarmult_base(&A,az); ge_p3_tobytes(sm + 32,&A); + memmove(pk, sm + 32, 32); sc_reduce(nonce); ge_scalarmult_base(&R,nonce); diff --git a/libmariadb/plugins/auth/sha256_pw.c b/libmariadb/plugins/auth/sha256_pw.c index 79febf1a..66fb1071 100644 --- a/libmariadb/plugins/auth/sha256_pw.c +++ b/libmariadb/plugins/auth/sha256_pw.c @@ -76,7 +76,8 @@ struct st_mysql_client_plugin_AUTHENTICATION _mysql_client_plugin_declaration_ = auth_sha256_init, NULL, NULL, - auth_sha256_client + auth_sha256_client, + NULL }; #ifdef HAVE_WINCRYPT |