summaryrefslogtreecommitdiffstats
path: root/libmariadb/plugins/auth
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-07-01 18:15:00 +0000
commita2a2e32c02643a0cec111511220227703fda1cd5 (patch)
tree69cc2b631234c2a8e026b9cd4d72676c61c594df /libmariadb/plugins/auth
parentReleasing progress-linux version 1:10.11.8-1~progress7.99u1. (diff)
downloadmariadb-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.txt5
-rw-r--r--libmariadb/plugins/auth/auth_gssapi_client.c3
-rw-r--r--libmariadb/plugins/auth/caching_sha2_pw.c3
-rw-r--r--libmariadb/plugins/auth/dialog.c3
-rw-r--r--libmariadb/plugins/auth/ed25519.c35
-rw-r--r--libmariadb/plugins/auth/mariadb_cleartext.c3
-rw-r--r--libmariadb/plugins/auth/my_auth.c124
-rw-r--r--libmariadb/plugins/auth/old_password.c3
-rw-r--r--libmariadb/plugins/auth/ref10/crypto_sign.h2
-rw-r--r--libmariadb/plugins/auth/ref10/sign.c3
-rw-r--r--libmariadb/plugins/auth/sha256_pw.c3
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