summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_strfunc.cc8
-rw-r--r--sql/mysqld.cc12
-rw-r--r--sql/mysqld.h3
-rw-r--r--sql/sql_plugin.cc39
-rw-r--r--sql/sql_plugin.h4
-rw-r--r--sql/sql_select.cc65
-rw-r--r--sql/sys_vars.cc35
-rw-r--r--sql/sys_vars.h1
8 files changed, 136 insertions, 31 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 25d5613669d..50e29aa4b7c 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -383,8 +383,8 @@ String *Item_func_aes_encrypt::val_str(String *str)
if (!str_value.alloc(aes_length)) // Ensure that memory is free
{
// finally encrypt directly to allocated buffer.
- if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(),
- key->ptr(), key->length()) == aes_length)
+ if (my_aes_encrypt((const uchar*) sptr->ptr(), sptr->length(), (uchar*) str_value.ptr(),
+ key->ptr(), key->length()) == aes_length)
{
// We got the expected result length
str_value.length((uint) aes_length);
@@ -420,8 +420,8 @@ String *Item_func_aes_decrypt::val_str(String *str)
{
// finally decrypt directly to allocated buffer.
int length;
- length=my_aes_decrypt(sptr->ptr(), sptr->length(),
- (char*) str_value.ptr(),
+ length=my_aes_decrypt((const uchar*)sptr->ptr(), sptr->length(),
+ (uchar*) str_value.ptr(),
key->ptr(), key->length());
if (length >= 0) // if we got correct data data
{
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 885d37d1cd7..da02b952f3c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -105,6 +105,7 @@
#include "sp_rcontext.h"
#include "sp_cache.h"
#include "sql_reload.h" // reload_acl_and_cache
+#include <my_aes.h>
#ifdef HAVE_POLL_H
#include <poll.h>
@@ -627,6 +628,9 @@ char server_version[SERVER_VERSION_LENGTH];
char *mysqld_unix_port, *opt_mysql_tmpdir;
ulong thread_handling;
+my_bool encrypt_tmp_disk_tables;
+ulong encryption_algorithm;
+
/** name of reference on left expression in rewritten IN subquery */
const char *in_left_expr_name= "<left expr>";
/** name of additional condition */
@@ -4797,6 +4801,14 @@ static int init_server_components()
my_rnd_init(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
setup_fpu();
init_thr_lock();
+ if (my_aes_init_dynamic_encrypt((enum_my_aes_encryption_algorithm)
+ encryption_algorithm))
+ {
+ fprintf(stderr, "Can't initialize encryption algorithm to \"%s\".\nCheck that the program is linked with the right library (openssl?)\n",
+ encryption_algorithm_names[encryption_algorithm]);
+ unireg_abort(1);
+ }
+
#ifndef EMBEDDED_LIBRARY
if (init_thr_timer(thread_scheduler->max_threads + extra_max_connections))
{
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 6a1ad65bd67..71d586cc4c1 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -249,6 +249,9 @@ extern ulong connection_errors_internal;
extern ulong connection_errors_max_connection;
extern ulong connection_errors_peer_addr;
extern ulong log_warnings;
+extern my_bool encrypt_tmp_disk_tables;
+extern ulong encryption_algorithm;
+extern const char *encryption_algorithm_names[];
/*
THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 30f840301ba..8fce66ae19f 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1233,9 +1233,24 @@ static void reap_plugins(void)
mysql_mutex_unlock(&LOCK_plugin);
+ /*
+ First free all normal plugins, last the key management plugin.
+ This is becasue the storage engines may need the key management plugin
+ during deinitialization.
+ */
+ list= reap;
+ while ((plugin= *(--list)))
+ {
+ if (plugin->plugin->type != MYSQL_KEY_MANAGEMENT_PLUGIN)
+ plugin_deinitialize(plugin, true);
+ }
+
list= reap;
while ((plugin= *(--list)))
- plugin_deinitialize(plugin, true);
+ {
+ if (plugin->state != PLUGIN_IS_UNINITIALIZED)
+ plugin_deinitialize(plugin, true);
+ }
mysql_mutex_lock(&LOCK_plugin);
@@ -1481,7 +1496,7 @@ static void init_plugin_psi_keys(void)
*/
int plugin_init(int *argc, char **argv, int flags)
{
- uint i;
+ uint i,j;
bool is_myisam;
struct st_maria_plugin **builtins;
struct st_maria_plugin *plugin;
@@ -1631,16 +1646,22 @@ int plugin_init(int *argc, char **argv, int flags)
reap= (st_plugin_int **) my_alloca((plugin_array.elements+1) * sizeof(void*));
*(reap++)= NULL;
- for (i= 0; i < plugin_array.elements; i++)
+ /* first MYSQL_KEY_MANAGEMENT_PLUGIN, then the rest */
+ for (j= 0 ; j <= 1; j++)
{
- plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
- if (plugin_ptr->plugin_dl && plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
+ for (i= 0; i < plugin_array.elements; i++)
{
- if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv,
- (flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
+ plugin_ptr= *dynamic_element(&plugin_array, i, struct st_plugin_int **);
+ if (((j == 0 && plugin->type == MYSQL_KEY_MANAGEMENT_PLUGIN) || j > 0) &&
+ plugin_ptr->plugin_dl &&
+ plugin_ptr->state == PLUGIN_IS_UNINITIALIZED)
{
- plugin_ptr->state= PLUGIN_IS_DYING;
- *(reap++)= plugin_ptr;
+ if (plugin_initialize(&tmp_root, plugin_ptr, argc, argv,
+ (flags & PLUGIN_INIT_SKIP_INITIALIZATION)))
+ {
+ plugin_ptr->state= PLUGIN_IS_DYING;
+ *(reap++)= plugin_ptr;
+ }
}
}
}
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index 9cfdba1edcd..2bfdcb29dfc 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -78,8 +78,6 @@ typedef struct st_mysql_show_var SHOW_VAR;
#define PLUGIN_IS_DYING 16
#define PLUGIN_IS_DISABLED 32
-/* A handle for the dynamic library containing a plugin or plugins. */
-
struct st_ptr_backup {
void **ptr;
void *value;
@@ -88,6 +86,8 @@ struct st_ptr_backup {
void restore() { *ptr= value; }
};
+/* A handle for the dynamic library containing a plugin or plugins. */
+
struct st_plugin_dl
{
LEX_STRING dl;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 87e2206cfb5..9d85c2646be 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -16886,6 +16886,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
MARIA_UNIQUEDEF uniquedef;
TABLE_SHARE *share= table->s;
MARIA_CREATE_INFO create_info;
+ my_bool encrypt= encrypt_tmp_disk_tables;
DBUG_ENTER("create_internal_tmp_table");
if (share->keys)
@@ -16988,24 +16989,56 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
delete the row. The cases when this can happen is when there is
a group by and no sum functions or if distinct is used.
*/
- if ((error= maria_create(share->table_name.str,
- table->no_rows ? NO_RECORD :
- (share->reclength < 64 &&
- !share->blob_fields ? STATIC_RECORD :
- table->used_for_duplicate_elimination ||
- table->keep_row_order ?
- DYNAMIC_RECORD : BLOCK_RECORD),
- share->keys, &keydef,
- (uint) (*recinfo-start_recinfo),
- start_recinfo,
- share->uniques, &uniquedef,
- &create_info,
- HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE)))
{
- table->file->print_error(error,MYF(0)); /* purecov: inspected */
- table->db_stat=0;
- goto err;
+ enum data_file_type file_type= table->no_rows ? NO_RECORD :
+ (share->reclength < 64 && !share->blob_fields ? STATIC_RECORD :
+ table->used_for_duplicate_elimination || table->keep_row_order ?
+ DYNAMIC_RECORD : BLOCK_RECORD);
+ uint create_flags= HA_CREATE_TMP_TABLE | HA_CREATE_INTERNAL_TABLE;
+
+ if (file_type != NO_RECORD && MY_TEST(encrypt))
+ {
+ /* encryption is only supported for BLOCK_RECORD */
+ file_type= BLOCK_RECORD;
+ create_flags|= HA_CREATE_ENCRYPTED;
+ if (table->keep_row_order)
+ {
+ create_flags|= HA_INSERT_ORDER;
+ }
+
+ if (table->used_for_duplicate_elimination)
+ {
+ /*
+ sql-layer expect the last column to be stored/restored also
+ when it's null.
+
+ This is probably a bug (that sql-layer doesn't annotate
+ the column as not-null) but both heap, aria-static, aria-dynamic and
+ myisam has this property. aria-block_record does not since it
+ does not store null-columns at all.
+ Emulate behaviour by making column not-nullable when creating the
+ table.
+ */
+ uint cols= (*recinfo-start_recinfo);
+ start_recinfo[cols-1].null_bit= 0;
+ }
+ }
+
+ if ((error= maria_create(share->table_name.str,
+ file_type,
+ share->keys, &keydef,
+ (uint) (*recinfo-start_recinfo),
+ start_recinfo,
+ share->uniques, &uniquedef,
+ &create_info,
+ create_flags)))
+ {
+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
+ table->db_stat=0;
+ goto err;
+ }
}
+
table->in_use->inc_status_created_tmp_disk_tables();
table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
share->db_record_offset= 1;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 1a4628d0d72..e7092354606 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -62,6 +62,7 @@
#include "sql_repl.h"
#include "opt_range.h"
#include "rpl_parallel.h"
+#include "my_crypt_key_management.h"
/*
The rule for this file: everything should be 'static'. When a sys_var
@@ -1124,6 +1125,26 @@ static Sys_var_mybool Sys_log_bin(
"log_bin", "Whether the binary log is enabled",
READ_ONLY GLOBAL_VAR(opt_bin_log), NO_CMD_LINE, DEFAULT(FALSE));
+
+#ifndef DBUG_OFF
+static Sys_var_mybool Sys_debug_use_static_keys(
+ "debug_use_static_encryption_keys",
+ "Enable use of nonrandom encryption keys. Only to be used in "
+ "internal testing",
+ READ_ONLY GLOBAL_VAR(debug_use_static_encryption_keys),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+static PolyLock_rwlock PLock_sys_debug_encryption_key_version(
+ &LOCK_dbug_encryption_key_version);
+
+static Sys_var_uint Sys_debug_encryption_key_version(
+ "debug_encryption_key_version",
+ "Encryption key version. Only to be used in internal testing.",
+ GLOBAL_VAR(opt_debug_encryption_key_version),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0,UINT_MAX), DEFAULT(0),
+ BLOCK_SIZE(1), &PLock_sys_debug_encryption_key_version);
+#endif
+
static Sys_var_mybool Sys_trust_function_creators(
"log_bin_trust_function_creators",
"If set to FALSE (the default), then when --log-bin is used, creation "
@@ -5133,6 +5154,20 @@ static Sys_var_harows Sys_expensive_subquery_limit(
SESSION_VAR(expensive_subquery_limit), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(100), BLOCK_SIZE(1));
+static Sys_var_mybool Sys_encrypt_tmp_disk_tables(
+ "encrypt_tmp_disk_tables",
+ "Encrypt tmp disk tables (created as part of query execution)",
+ GLOBAL_VAR(encrypt_tmp_disk_tables),
+ CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+
+const char *encryption_algorithm_names[]=
+{ "none", "aes_ecb", "aes_cbc", "aes_ctr", 0 };
+static Sys_var_enum Sys_encryption_algorithm(
+ "encryption_algorithm",
+ "Which encryption algorithm to use for table encryption. aes_cbc is the recommended one.",
+ READ_ONLY GLOBAL_VAR(encryption_algorithm),CMD_LINE(REQUIRED_ARG),
+ encryption_algorithm_names, DEFAULT(0));
+
static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var)
{
longlong previous_val= thd->variables.pseudo_slave_mode;
diff --git a/sql/sys_vars.h b/sql/sys_vars.h
index 61af931c189..2b83e9747b7 100644
--- a/sql/sys_vars.h
+++ b/sql/sys_vars.h
@@ -94,6 +94,7 @@ enum charset_enum {IN_SYSTEM_CHARSET, IN_FS_CHARSET};
static const char *bool_values[3]= {"OFF", "ON", 0};
TYPELIB bool_typelib={ array_elements(bool_values)-1, "", bool_values, 0 };
+extern const char *encrypt_algorithm_names[];
/**
A small wrapper class to pass getopt arguments as a pair