summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rwxr-xr-xsql/CMakeLists.txt2
-rw-r--r--sql/Makefile.am3
-rw-r--r--sql/item_create.cc23
-rw-r--r--sql/item_strfunc.cc153
-rw-r--r--sql/item_strfunc.h12
-rw-r--r--sql/mysqld.cc26
-rw-r--r--sql/sha2.cc68
-rw-r--r--sql/sql_acl.cc4
-rw-r--r--sql/sql_connect.cc10
-rw-r--r--sql/sys_vars.cc2
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