diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_strfunc.cc | 8 | ||||
-rw-r--r-- | sql/mysqld.cc | 12 | ||||
-rw-r--r-- | sql/mysqld.h | 3 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 39 | ||||
-rw-r--r-- | sql/sql_plugin.h | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 65 | ||||
-rw-r--r-- | sql/sys_vars.cc | 35 | ||||
-rw-r--r-- | sql/sys_vars.h | 1 |
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 |