diff options
Diffstat (limited to 'sql')
-rwxr-xr-x | sql/CMakeLists.txt | 2 | ||||
-rw-r--r-- | sql/Makefile.am | 3 | ||||
-rw-r--r-- | sql/item_create.cc | 23 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 153 | ||||
-rw-r--r-- | sql/item_strfunc.h | 12 | ||||
-rw-r--r-- | sql/mysqld.cc | 26 | ||||
-rw-r--r-- | sql/sha2.cc | 68 | ||||
-rw-r--r-- | sql/sql_acl.cc | 4 | ||||
-rw-r--r-- | sql/sql_connect.cc | 10 | ||||
-rw-r--r-- | sql/sys_vars.cc | 2 |
10 files changed, 276 insertions, 27 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 31110c5e201..396c8b1fd27 100755 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -41,7 +41,7 @@ ENDIF() SET (SQL_SOURCE ../sql-common/client.c derror.cc des_key_file.cc discover.cc ../libmysql/errmsg.c field.cc field_conv.cc - filesort.cc gstream.cc + filesort.cc gstream.cc sha2.cc ha_partition.cc handler.cc hash_filo.cc hash_filo.h sql_plugin_services.h hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc diff --git a/sql/Makefile.am b/sql/Makefile.am index 696f608c879..93595a964eb 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -167,7 +167,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ sql_plugin.cc sql_binlog.cc \ sql_builtin.cc sql_tablespace.cc partition_info.cc \ sql_servers.cc event_parse_data.cc sql_signal.cc \ - rpl_handler.cc mdl.cc transaction.cc sql_audit.cc + rpl_handler.cc mdl.cc transaction.cc sql_audit.cc \ + sha2.cc nodist_mysqld_SOURCES = mini_client_errors.c pack.c client.c my_time.c my_user.c diff --git a/sql/item_create.cc b/sql/item_create.cc index beb7b40dc18..5f30a10d1e0 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -1834,6 +1834,19 @@ protected: }; +class Create_func_sha2 : public Create_func_arg2 +{ +public: + virtual Item* create(THD *thd, Item *arg1, Item *arg2); + + static Create_func_sha2 s_singleton; + +protected: + Create_func_sha2() {} + virtual ~Create_func_sha2() {} +}; + + class Create_func_sign : public Create_func_arg1 { public: @@ -4363,6 +4376,15 @@ Create_func_sha::create(THD *thd, Item *arg1) } +Create_func_sha2 Create_func_sha2::s_singleton; + +Item* +Create_func_sha2::create(THD *thd, Item *arg1, Item *arg2) +{ + return new (thd->mem_root) Item_func_sha2(arg1, arg2); +} + + Create_func_sign Create_func_sign::s_singleton; Item* @@ -4973,6 +4995,7 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)}, { { C_STRING_WITH_LEN("SHA") }, BUILDER(Create_func_sha)}, { { C_STRING_WITH_LEN("SHA1") }, BUILDER(Create_func_sha)}, + { { C_STRING_WITH_LEN("SHA2") }, BUILDER(Create_func_sha2)}, { { C_STRING_WITH_LEN("SIGN") }, BUILDER(Create_func_sign)}, { { C_STRING_WITH_LEN("SIN") }, BUILDER(Create_func_sin)}, { { C_STRING_WITH_LEN("SLEEP") }, BUILDER(Create_func_sleep)}, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9ae15322265..32baae87c50 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -29,6 +29,8 @@ #pragma implementation // gcc: Class implementation #endif +/* May include caustic 3rd-party defs. Use early, so it can override nothing. */ +#include "sha2.h" #include "my_global.h" // HAVE_* @@ -94,9 +96,9 @@ String *Item_str_ascii_func::val_str(String *str) Used to generate a hexadecimal representation of a message digest. */ -static void array_to_hex(char *to, const char *str, uint len) +static void array_to_hex(char *to, const unsigned char *str, uint len) { - const char *str_end= str + len; + const unsigned char *str_end= str + len; for (; str != str_end; ++str) { *to++= _dig_vec_lower[((uchar) *str) >> 4]; @@ -175,7 +177,7 @@ String *Item_func_md5::val_str_ascii(String *str) null_value=1; return 0; } - array_to_hex((char *) str->ptr(), (const char*) digest, 16); + array_to_hex((char *) str->ptr(), digest, 16); str->length((uint) 32); return str; } @@ -216,7 +218,7 @@ String *Item_func_sha::val_str_ascii(String *str) if (!( str->alloc(SHA1_HASH_SIZE*2) || (mysql_sha1_result(&context,digest)))) { - array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE); + array_to_hex((char *) str->ptr(), digest, SHA1_HASH_SIZE); str->length((uint) SHA1_HASH_SIZE*2); null_value=0; return str; @@ -240,6 +242,144 @@ void Item_func_sha::fix_length_and_dec() fix_length_and_charset(SHA1_HASH_SIZE * 2, default_charset()); } +String *Item_func_sha2::val_str(String *str) +{ + DBUG_ASSERT(fixed == 1); +#ifdef HAVE_OPENSSL + unsigned char digest_buf[SHA512_DIGEST_LENGTH]; + String *input_string; + unsigned char *input_ptr; + size_t input_len; + uint digest_length= 0; + + str->set_charset(&my_charset_bin); + + input_string= args[0]->val_str(str); + if (input_string == NULL) + { + null_value= TRUE; + return (String *) NULL; + } + + null_value= args[0]->null_value; + if (null_value) + return (String *) NULL; + + input_ptr= (unsigned char *) input_string->ptr(); + input_len= input_string->length(); + + switch ((uint) args[1]->val_int()) { +#ifndef OPENSSL_NO_SHA512 + case 512: + digest_length= SHA512_DIGEST_LENGTH; + (void) SHA512(input_ptr, input_len, digest_buf); + break; + case 384: + digest_length= SHA384_DIGEST_LENGTH; + (void) SHA384(input_ptr, input_len, digest_buf); + break; +#endif +#ifndef OPENSSL_NO_SHA256 + case 224: + digest_length= SHA224_DIGEST_LENGTH; + (void) SHA224(input_ptr, input_len, digest_buf); + break; + case 256: + case 0: // SHA-256 is the default + digest_length= SHA256_DIGEST_LENGTH; + (void) SHA256(input_ptr, input_len, digest_buf); + break; +#endif + default: + if (!args[1]->const_item()) + push_warning_printf(current_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_PARAMETERS_TO_NATIVE_FCT, + ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2"); + null_value= TRUE; + return NULL; + } + + /* + Since we're subverting the usual String methods, we must make sure that + the destination has space for the bytes we're about to write. + */ + str->realloc((uint) digest_length*2 + 1); /* Each byte as two nybbles */ + + /* Convert the large number to a string-hex representation. */ + array_to_hex((char *) str->ptr(), digest_buf, digest_length); + + /* We poked raw bytes in. We must inform the the String of its length. */ + str->length((uint) digest_length*2); /* Each byte as two nybbles */ + + null_value= FALSE; + return str; + +#else + push_warning_printf(current_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + "sha2", "--with-ssl"); + null_value= TRUE; + return (String *) NULL; +#endif +} + + +void Item_func_sha2::fix_length_and_dec() +{ + maybe_null = 1; + max_length = 0; + +#if defined(HAVE_OPENSSL) + int sha_variant= args[1]->const_item() ? args[1]->val_int() : 512; + + switch (sha_variant) { +#ifndef OPENSSL_NO_SHA512 + case 512: + max_length= SHA512_DIGEST_LENGTH*2; + break; + case 384: + max_length= SHA384_DIGEST_LENGTH*2; + break; +#endif +#ifndef OPENSSL_NO_SHA256 + case 256: + case 0: // SHA-256 is the default + max_length= SHA256_DIGEST_LENGTH*2; + break; + case 224: + max_length= SHA224_DIGEST_LENGTH*2; + break; +#endif + default: + push_warning_printf(current_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_PARAMETERS_TO_NATIVE_FCT, + ER(ER_WRONG_PARAMETERS_TO_NATIVE_FCT), "sha2"); + } + + /* + The SHA2() function treats its parameter as being a case sensitive. + Thus we set binary collation on it so different instances of SHA2() + will be compared properly. + */ + + args[0]->collation.set( + get_charset_by_csname( + args[0]->collation.collation->csname, + MY_CS_BINSORT, + MYF(0)), + DERIVATION_COERCIBLE); +#else + push_warning_printf(current_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_FEATURE_DISABLED, + ER(ER_FEATURE_DISABLED), + "sha2", "--with-ssl"); +#endif +} /* Implementation of AES encryption routines */ @@ -510,7 +650,6 @@ String *Item_func_des_encrypt::val_str(String *str) return 0; // ENCRYPT(NULL) == NULL if ((res_length=res->length()) == 0) return &my_empty_string; - if (arg_count == 1) { /* Protect against someone doing FLUSH DES_KEY_FILE */ @@ -583,7 +722,7 @@ error: #else push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), - "des_encrypt","--with-openssl"); + "des_encrypt", "--with-ssl"); #endif /* HAVE_OPENSSL */ null_value=1; return 0; @@ -661,7 +800,7 @@ wrong_key: #else push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_WARN, ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED), - "des_decrypt","--with-openssl"); + "des_decrypt", "--with-ssl"); #endif /* HAVE_OPENSSL */ null_value=1; return 0; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e3008a5daab..7b7f8d3308a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -82,6 +82,18 @@ public: const char *func_name() const { return "sha"; } }; +class Item_func_sha2 :public Item_str_func +{ +public: + Item_func_sha2(Item *a, Item *b) :Item_str_func(a, b) + { + collation.set(&my_charset_bin); + } + String *val_str(String *); + void fix_length_and_dec(); + const char *func_name() const { return "sha2"; } +}; + class Item_func_aes_encrypt :public Item_str_func { public: diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2bc47849915..b35e2545a18 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -957,7 +957,9 @@ static void openssl_lock(int, openssl_lock_t *, const char *, int); static unsigned long openssl_id_function(); #endif char *des_key_file; +#ifndef EMBEDDED_LIBRARY struct st_VioSSLFd *ssl_acceptor_fd; +#endif #endif /* HAVE_OPENSSL */ /** @@ -1003,8 +1005,8 @@ static void clean_up_mutexes(void); static void wait_for_signal_thread_to_end(void); static void create_pid_file(); static void mysqld_exit(int exit_code) __attribute__((noreturn)); -static void end_ssl(); #endif +static void end_ssl(); #ifndef EMBEDDED_LIBRARY @@ -1524,9 +1526,7 @@ void clean_up(bool print_message) #endif delete binlog_filter; delete rpl_filter; -#ifndef EMBEDDED_LIBRARY end_ssl(); -#endif vio_end(); #ifdef USE_REGEX my_regex_end(); @@ -3916,11 +3916,10 @@ static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, #endif /* HAVE_OPENSSL */ -#ifndef EMBEDDED_LIBRARY - static void init_ssl() { #ifdef HAVE_OPENSSL +#ifndef EMBEDDED_LIBRARY if (opt_use_ssl) { enum enum_ssl_init_error error= SSL_INITERR_NOERROR; @@ -3942,6 +3941,9 @@ static void init_ssl() { have_ssl= SHOW_OPTION_DISABLED; } +#else + have_ssl= SHOW_OPTION_DISABLED; +#endif /* ! EMBEDDED_LIBRARY */ if (des_key_file) load_des_key_file(des_key_file); #endif /* HAVE_OPENSSL */ @@ -3951,16 +3953,16 @@ static void init_ssl() static void end_ssl() { #ifdef HAVE_OPENSSL +#ifndef EMBEDDED_LIBRARY if (ssl_acceptor_fd) { free_vio_ssl_acceptor_fd(ssl_acceptor_fd); ssl_acceptor_fd= 0; } +#endif /* ! EMBEDDED_LIBRARY */ #endif /* HAVE_OPENSSL */ } -#endif /* EMBEDDED_LIBRARY */ - static int init_server_components() { @@ -6434,7 +6436,7 @@ static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff) return 0; } -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) /* Functions relying on CTX */ static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff) { @@ -6690,7 +6692,7 @@ static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff) return 0; } -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ /* @@ -6781,6 +6783,7 @@ SHOW_VAR status_vars[]= { {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS}, {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS}, #ifdef HAVE_OPENSSL +#ifndef EMBEDDED_LIBRARY {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC}, {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC}, {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC}, @@ -6804,6 +6807,7 @@ SHOW_VAR status_vars[]= { {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_FUNC}, {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC}, {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC}, +#endif #endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, @@ -7103,8 +7107,10 @@ static int mysql_init_variables(void) #endif #ifdef HAVE_OPENSSL des_key_file = 0; +#ifndef EMBEDDED_LIBRARY ssl_acceptor_fd= 0; -#endif +#endif /* ! EMBEDDED_LIBRARY */ +#endif /* HAVE_OPENSSL */ #ifdef HAVE_SMEM shared_memory_base_name= default_shared_memory_base_name; #endif diff --git a/sql/sha2.cc b/sql/sha2.cc new file mode 100644 index 00000000000..1a9de86f2e0 --- /dev/null +++ b/sql/sha2.cc @@ -0,0 +1,68 @@ +/* Copyright (C) 2007 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +/** + @file + A compatibility layer to our built-in SSL implementation, to mimic the + oft-used external library, OpenSSL. +*/ + +#include <my_global.h> +#include <sha2.h> + +#ifdef HAVE_YASSL + +/* + If TaoCrypt::SHA512 or ::SHA384 are not defined (but ::SHA256 is), it's + probably that neither of config.h's SIZEOF_LONG or SIZEOF_LONG_LONG are + 64 bits long. At present, both OpenSSL and YaSSL require 64-bit integers + for SHA-512. (The SIZEOF_* definitions come from autoconf's config.h .) +*/ + +# define GEN_YASSL_SHA2_BRIDGE(size) \ +unsigned char* SHA##size(const unsigned char *input_ptr, size_t input_length, \ + char unsigned *output_ptr) { \ + TaoCrypt::SHA##size hasher; \ + \ + hasher.Update(input_ptr, input_length); \ + hasher.Final(output_ptr); \ + return(output_ptr); \ +} + + +/** + @fn SHA512 + @fn SHA384 + @fn SHA256 + @fn SHA224 + + Instantiate an hash object, fill in the cleartext value, compute the digest, + and extract the result from the object. + + (Generate the functions. See similar .h code for the prototypes.) +*/ +# ifndef OPENSSL_NO_SHA512 +GEN_YASSL_SHA2_BRIDGE(512); +GEN_YASSL_SHA2_BRIDGE(384); +# else +# warning Some SHA2 functionality is missing. See OPENSSL_NO_SHA512. +# endif +GEN_YASSL_SHA2_BRIDGE(256); +GEN_YASSL_SHA2_BRIDGE(224); + +# undef GEN_YASSL_SHA2_BRIDGE + +#endif /* HAVE_YASSL */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a5e5b4ec2a1..f8be3ff6d4a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -929,7 +929,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, if (acl_user) { /* OK. User found and password checked continue validation */ -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) Vio *vio=thd->net.vio; SSL *ssl= (SSL*) vio->ssl_arg; X509 *cert; @@ -946,7 +946,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, case SSL_TYPE_NONE: // SSL is not required user_access= acl_user->access; break; -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) case SSL_TYPE_ANY: // Any kind of SSL is ok if (vio_type(vio) == VIO_TYPE_SSL) user_access= acl_user->access; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index cfcf1754581..e2d0977def7 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -36,7 +36,7 @@ // reset_host_errors #include "sql_acl.h" // acl_getroot, NO_ACCESS, SUPER_ACL -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) /* Without SSL the handshake consists of one packet. This packet has both client capabilites and scrambled password. @@ -52,7 +52,7 @@ #define MIN_HANDSHAKE_SIZE 2 #else #define MIN_HANDSHAKE_SIZE 6 -#endif /* HAVE_OPENSSL */ +#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ /* Get structure for logging connection data for the current user @@ -654,6 +654,7 @@ bool init_new_connection_handler_thread() return 0; } +#ifndef EMBEDDED_LIBRARY /* Perform handshake, authorize client and update thd ACL variables. @@ -667,7 +668,6 @@ bool init_new_connection_handler_thread() > 0 error code (not sent to user) */ -#ifndef EMBEDDED_LIBRARY static int check_connection(THD *thd) { uint connect_errors= 0; @@ -749,7 +749,7 @@ static int check_connection(THD *thd) #ifdef HAVE_COMPRESS server_capabilites|= CLIENT_COMPRESS; #endif /* HAVE_COMPRESS */ -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) if (ssl_acceptor_fd) { server_capabilites |= CLIENT_SSL; /* Wow, SSL is available! */ @@ -827,7 +827,7 @@ static int check_connection(THD *thd) if (thd->client_capabilities & CLIENT_IGNORE_SPACE) thd->variables.sql_mode|= MODE_IGNORE_SPACE; -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities)); if (thd->client_capabilities & CLIENT_SSL) { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 3cb1e90b124..ea86bcc227f 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1923,7 +1923,7 @@ static Sys_var_set Sys_sql_mode( sql_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_sql_mode), ON_UPDATE(fix_sql_mode)); -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) #define SSL_OPT(X) CMD_LINE(REQUIRED_ARG,X) #else #define SSL_OPT(X) NO_CMD_LINE |