summaryrefslogtreecommitdiff
path: root/plugin
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-03-23 22:36:46 +0100
committerSergei Golubchik <serg@mariadb.org>2016-03-23 22:36:46 +0100
commitf67a2211ec48b1b1502a7095c50cd9195d8235f8 (patch)
tree93e5d158a4a2a1dca4be915f8cf9dc79b3b6d96c /plugin
parenta75d26946423d2142921411bf7bdc731eba4df1a (diff)
parent2783fc7d14bc8ad16acfeb509d3b19615023f47a (diff)
downloadmariadb-git-f67a2211ec48b1b1502a7095c50cd9195d8235f8.tar.gz
Merge branch '10.1' into 10.2
Diffstat (limited to 'plugin')
-rw-r--r--plugin/auth_gssapi/mysql-test/auth_gssapi/suite.pm2
-rw-r--r--plugin/aws_key_management/CMakeLists.txt154
-rw-r--r--plugin/aws_key_management/aws_key_management_plugin.cc587
-rw-r--r--plugin/cracklib_password_check/cracklib_password_check.c2
-rw-r--r--plugin/file_key_management/file_key_management_plugin.cc2
-rw-r--r--plugin/file_key_management/parser.cc2
-rw-r--r--plugin/handler_socket/docs-en/perl-client.en.txt6
-rw-r--r--plugin/handler_socket/handlersocket/database.cpp3
-rw-r--r--plugin/locale_info/locale_info.cc2
-rw-r--r--plugin/metadata_lock_info/metadata_lock_info.cc2
-rw-r--r--plugin/qc_info/qc_info.cc2
-rw-r--r--plugin/query_response_time/mysql-test/query_response_time/basic.result2
-rw-r--r--plugin/query_response_time/plugin.cc2
-rw-r--r--plugin/semisync/semisync_master.h6
-rw-r--r--plugin/semisync/semisync_master_plugin.cc2
-rw-r--r--plugin/semisync/semisync_slave_plugin.cc2
-rw-r--r--plugin/simple_password_check/simple_password_check.c2
-rw-r--r--plugin/sql_errlog/sql_errlog.c2
-rw-r--r--plugin/userstat/userstat.cc4
-rw-r--r--plugin/wsrep_info/plugin.cc4
20 files changed, 766 insertions, 24 deletions
diff --git a/plugin/auth_gssapi/mysql-test/auth_gssapi/suite.pm b/plugin/auth_gssapi/mysql-test/auth_gssapi/suite.pm
index 50137ca0211..aa225536a1e 100644
--- a/plugin/auth_gssapi/mysql-test/auth_gssapi/suite.pm
+++ b/plugin/auth_gssapi/mysql-test/auth_gssapi/suite.pm
@@ -19,7 +19,7 @@ else
{
if (!$ENV{'GSSAPI_FULLNAME'})
{
- my $s = `klist |grep 'Default principal: '`;
+ my $s = `klist 2>/dev/null |grep 'Default principal: '`;
if ($s)
{
chomp($s);
diff --git a/plugin/aws_key_management/CMakeLists.txt b/plugin/aws_key_management/CMakeLists.txt
new file mode 100644
index 00000000000..97bcfbb04db
--- /dev/null
+++ b/plugin/aws_key_management/CMakeLists.txt
@@ -0,0 +1,154 @@
+# We build parts of AWS C++ SDK as CMake external project
+# The restrictions of the SDK (https://github.com/awslabs/aws-sdk-cpp/blob/master/README.md)
+# are
+
+# - OS : Windows,Linux or OSX
+# - C++11 compiler : VS2013+, gcc 4.7+, clang 3.3+
+# - libcurl development package needs to be present on Unixes
+#
+# If we build SDK outselves, we'll need require GIT to be present on the build machine
+
+
+# Give message why the building this plugin is skipped (only if -DVERBOSE is defined)
+# or if plugin is explicitely requested to build. Then bail out.
+MACRO(SKIP_AWS_PLUGIN msg)
+ IF(VERBOSE OR "${PLUGIN_AWS_KEY_MANAGEMENT}" MATCHES "^(STATIC|DYNAMIC)$")
+ MESSAGE(STATUS "Skip aws_key_management - ${msg}")
+ ENDIF()
+ RETURN()
+ENDMACRO()
+
+MYSQL_ADD_PLUGIN(aws_key_management aws_key_management_plugin.cc DISABLED
+ COMPONENT aws-key-management)
+
+IF(NOT TARGET aws_key_management)
+ RETURN()
+ENDIF()
+
+# This plugin needs recent C++ compilers (AWS C++ SDK header files are using C++11 features)
+SET(CXX11_FLAGS)
+SET(OLD_COMPILER_MSG "AWS SDK requires c++11 -capable compiler (minimal supported versions are g++ 4.7, clang 3.3, VS2103)")
+
+IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ EXECUTE_PROCESS(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
+ IF (GCC_VERSION VERSION_LESS 4.8)
+ SKIP_AWS_PLUGIN("${OLD_COMPILER_MSG}")
+ ENDIF()
+ SET(CXX11_FLAGS "-std=c++11")
+ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ IF ((CMAKE_CXX_COMPILER_VERSION AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.3) OR
+ (CLANG_VERSION_STRING AND CLANG_VERSION_STRING VERSION_LESS 3.3))
+ SKIP_AWS_PLUGIN("${OLD_COMPILER_MSG}")
+ ENDIF()
+ SET(CXX11_FLAGS "-stdlib=libc++")
+ELSEIF(MSVC)
+ IF (MSVC_VERSION LESS 1800)
+ SKIP_AWS_PLUGIN("${OLD_COMPILER_MSG}")
+ ENDIF()
+ELSE()
+ SKIP_AWS_PLUGIN("Compiler not supported by AWS C++ SDK")
+ENDIF()
+
+IF (NOT(WIN32 OR APPLE OR (CMAKE_SYSTEM_NAME MATCHES "Linux")))
+ SKIP_AWS_PLUGIN("OS unsupported by AWS SDK")
+ENDIF()
+
+
+# Figure out where AWS installs SDK libraries
+# The below is defined in AWS SDK's CMakeLists.txt
+# (and their handling is weird, every OS has special install directory)
+IF(WIN32)
+ SET(SDK_INSTALL_BINARY_PREFIX "windows")
+ELSEIF(APPLE)
+ SET(SDK_INSTALL_BINARY_PREFIX "mac")
+ELSEIF(UNIX)
+ SET(SDK_INSTALL_BINARY_PREFIX "linux")
+ENDIF()
+IF(NOT APPLE)
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ SET(SDK_INSTALL_BINARY_PREFIX "${SDK_INSTALL_BINARY_PREFIX}/intel64")
+ ELSE()
+ SET(SDK_INSTALL_BINARY_PREFIX "${SDK_INSTALL_BINARY_PREFIX}/ia32")
+ ENDIF()
+ENDIF()
+IF(CMAKE_CONFIGURATION_TYPES)
+ SET(SDK_INSTALL_BINARY_PREFIX "${SDK_INSTALL_BINARY_PREFIX}/${CMAKE_CFG_INTDIR}")
+ENDIF()
+
+FIND_LIBRARY(AWS_CPP_SDK_CORE NAMES aws-cpp-sdk-core PATH_SUFFIXES "${SDK_INSTALL_BINARY_PREFIX}")
+FIND_LIBRARY(AWS_CPP_SDK_KMS NAMES aws-cpp-sdk-core PATH_SUFFIXES "${SDK_INSTALL_BINARY_PREFIX}")
+SET(CMAKE_REQUIRED_FLAGS ${CXX11_FLAGS})
+CHECK_INCLUDE_FILE_CXX(aws/kms/KMSClient.h HAVE_AWS_HEADERS)
+
+IF(AWS_CPP_SDK_CORE AND AWS_CPP_SDK_KMS AND HAVE_AWS_HEADERS)
+ # AWS C++ SDK installed
+ SET(AWS_SDK_LIBS ${AWS_CPP_SDK_CORE} ${AWS_CPP_SDK_KMS})
+ELSE()
+ # Build from source, using ExternalProject_Add
+ IF(CMAKE_VERSION VERSION_LESS "2.8.8")
+ SKIP_AWS_PLUGIN("CMake is too old")
+ ENDIF()
+ FIND_PACKAGE(Git)
+ IF(NOT GIT_FOUND)
+ SKIP_AWS_PLUGIN("no GIT")
+ ENDIF()
+ INCLUDE(ExternalProject)
+ IF(UNIX)
+ FIND_PACKAGE(CURL)
+ IF(NOT CURL_FOUND)
+ SKIP_AWS_PLUGIN("AWS C++ SDK requires libcurl development package")
+ ENDIF()
+ SET(PIC_FLAG -fPIC)
+ ENDIF()
+ IF(MSVC)
+ SET(EXTRA_SDK_CMAKE_FLAGS -DCMAKE_CXX_FLAGS_DEBUGOPT="" -DCMAKE_EXE_LINKER_FLAGS_DEBUGOPT="" -DCMAKE_CXX_FLAGS=/wd4592)
+ ENDIF()
+ IF(CMAKE_CXX_COMPILER)
+ SET(EXTRA_SDK_CMAKE_FLAGS ${EXTRA_SDK_CMAKE_FLAGS} -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
+ ENDIF()
+
+ # Relax AWS C++ SDK unreasonably high requirements for CMake version. Use replace utility (from MariaDB build)
+ # to patch their CMakeLists.txt
+ SET(AWS_SDK_PATCH_COMMAND )
+ ExternalProject_Add(
+ aws_sdk_cpp
+ GIT_REPOSITORY "https://github.com/awslabs/aws-sdk-cpp.git"
+ GIT_TAG "0.9.6" # single tag
+ UPDATE_COMMAND ""
+ PATCH_COMMAND replace 3.1.2 2.8 -- ${CMAKE_BINARY_DIR}/aws-sdk-cpp/CMakeLists.txt
+ SOURCE_DIR "${CMAKE_BINARY_DIR}/aws-sdk-cpp"
+ CMAKE_ARGS
+ -DBUILD_ONLY=aws-cpp-sdk-kms -DSTATIC_LINKING=1
+ "-DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG} ${PIC_FLAG}"
+ "-DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${PIC_FLAG}"
+ "-DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} ${PIC_FLAG}"
+ "-DCMAKE_CXX_FLAGS_MINSIZEREL=${CMAKE_CXX_FLAGS_MINSIZEREL} ${PIC_FLAG}"
+ ${EXTRA_SDK_CMAKE_FLAGS}
+ -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/aws_sdk_cpp
+ TEST_COMMAND ""
+ )
+
+ # We do not need to build the whole SDK , just 2 of its libs
+ set(AWS_SDK_LIBS aws-cpp-sdk-core aws-cpp-sdk-kms)
+ FOREACH(lib ${AWS_SDK_LIBS})
+ ADD_LIBRARY(${lib} STATIC IMPORTED GLOBAL)
+ ADD_DEPENDENCIES(${lib} aws_sdk_cpp)
+ SET(loc "${CMAKE_BINARY_DIR}/aws_sdk_cpp/lib/${SDK_INSTALL_BINARY_PREFIX}/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${loc})
+ IF(WIN32)
+ SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "bcrypt;winhttp;wininet;userenv")
+ ELSE()
+ SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${SSL_LIBRARIES};${CURL_LIBRARIES}")
+ ENDIF()
+ ENDFOREACH()
+
+ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+ # Need whole-archive , otherwise static libraries are not linked
+ SET(AWS_SDK_LIBS -Wl,--whole-archive ${AWS_SDK_LIBS} -Wl,--no-whole-archive)
+ ENDIF()
+ SET_TARGET_PROPERTIES(aws_sdk_cpp PROPERTIES EXCLUDE_FROM_ALL TRUE)
+ INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/aws_sdk_cpp/include)
+ENDIF()
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX11_FLAGS}")
+TARGET_LINK_LIBRARIES(aws_key_management ${AWS_SDK_LIBS})
diff --git a/plugin/aws_key_management/aws_key_management_plugin.cc b/plugin/aws_key_management/aws_key_management_plugin.cc
new file mode 100644
index 00000000000..3913d2c3145
--- /dev/null
+++ b/plugin/aws_key_management/aws_key_management_plugin.cc
@@ -0,0 +1,587 @@
+/*
+ Copyright (c) 2016 MariaDB Corporation
+
+ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+
+#include <my_global.h>
+#include <my_pthread.h>
+#include <my_sys.h>
+#include <my_dir.h>
+#include <mysql/plugin_encryption.h>
+#include <my_crypt.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <mysqld_error.h>
+#include <base64.h>
+#include <map>
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <iterator>
+#include <sstream>
+#include <fstream>
+
+#include <aws/core/client/AWSError.h>
+#include <aws/core/utils/logging/AWSLogging.h>
+#include <aws/core/utils/logging/ConsoleLogSystem.h>
+#include <aws/kms/KMSClient.h>
+#include <aws/kms/model/DecryptRequest.h>
+#include <aws/kms/model/DecryptResult.h>
+#include <aws/kms/model/GenerateDataKeyWithoutPlaintextRequest.h>
+#include <aws/kms/model/GenerateDataKeyWithoutPlaintextResult.h>
+#include <aws/core/utils/Outcome.h>
+
+using namespace std;
+using namespace Aws::KMS;
+using namespace Aws::KMS::Model;
+using namespace Aws::Utils::Logging;
+extern void sql_print_error(const char *format, ...);
+extern void sql_print_warning(const char *format, ...);
+extern void sql_print_information(const char *format, ...);
+
+
+/* Plaintext key info struct */
+struct KEY_INFO
+{
+ unsigned int key_id;
+ unsigned int key_version;
+ unsigned int length;
+ unsigned char data[MY_AES_MAX_KEY_LENGTH];
+ bool load_failed; /* if true, do not attempt to reload?*/
+public:
+ KEY_INFO() : key_id(0), key_version(0), length(0), load_failed(false){};
+};
+#define KEY_ID_AND_VERSION(key_id,version) ((longlong)key_id << 32 | version)
+
+/* Cache for the latest version, per key id */
+static std::map<uint, uint> latest_version_cache;
+
+/* Cache for plaintext keys */
+static std::map<ulonglong, KEY_INFO> key_info_cache;
+
+static const char *key_spec_names[]={ "AES_128", "AES_256", 0 };
+
+/* Plugin variables */
+static char* master_key_id;
+static unsigned long key_spec;
+static unsigned long log_level;
+static int rotate_key;
+
+/* AWS functionality*/
+static int aws_decrypt_key(const char *path, KEY_INFO *info);
+static int aws_generate_datakey(uint key_id, uint version);
+
+static int extract_id_and_version(const char *name, uint *id, uint *ver);
+static unsigned int get_latest_key_version(unsigned int key_id);
+static unsigned int get_latest_key_version_nolock(unsigned int key_id);
+static int load_key(KEY_INFO *info);
+
+/* Mutex to serialize access to caches */
+static mysql_mutex_t mtx;
+
+#ifdef HAVE_PSI_INTERFACE
+static uint mtx_key;
+static PSI_mutex_info mtx_info = {&mtx_key, "mtx", 0};
+#endif
+
+static Aws::KMS::KMSClient *client;
+
+/* Redirect AWS trace to error log */
+class MySQLLogSystem : public Aws::Utils::Logging::FormattedLogSystem
+{
+public:
+
+ using Base = FormattedLogSystem;
+ MySQLLogSystem(LogLevel logLevel) :
+ Base(logLevel)
+ {
+ }
+ virtual LogLevel GetLogLevel(void) const override
+ {
+ return (LogLevel)log_level;
+ }
+ virtual ~MySQLLogSystem()
+ {
+ }
+
+protected:
+ virtual void ProcessFormattedStatement(Aws::String&& statement) override
+ {
+#ifdef _WIN32
+ /*
+ On Windows, we can't use C runtime functions to write to stdout,
+ because we compile with static C runtime, so plugin has a stdout
+ different from server. Thus we're using WriteFile().
+ */
+ DWORD nSize= (DWORD)statement.size();
+ DWORD nWritten;
+ const char *s= statement.c_str();
+ HANDLE h= GetStdHandle(STD_OUTPUT_HANDLE);
+
+ WriteFile(h, s, nSize, &nWritten, NULL);
+#else
+ printf("%s", statement.c_str());
+#endif
+ }
+};
+
+
+/*
+ Plugin initialization.
+
+ Create KMS client and scan datadir to find out which keys and versions
+ are present.
+*/
+static int plugin_init(void *p)
+{
+ DBUG_ENTER("plugin_init");
+ client = new KMSClient();
+ if (!client)
+ {
+ sql_print_error("Can not initialize KMS client");
+ DBUG_RETURN(-1);
+ }
+ InitializeAWSLogging(Aws::MakeShared<MySQLLogSystem>("aws_key_management_plugin", (Aws::Utils::Logging::LogLevel) log_level));
+#ifdef HAVE_PSI_INTERFACE
+ mysql_mutex_register("aws_key_management", &mtx_info, 1);
+#endif
+ mysql_mutex_init(mtx_key, &mtx, NULL);
+
+ MY_DIR *dirp = my_dir(".", MYF(0));
+ if (!dirp)
+ {
+ sql_print_error("Can't scan current directory");
+ DBUG_RETURN(-1);
+ }
+ for (unsigned int i=0; i < dirp->number_of_files; i++)
+ {
+
+ KEY_INFO info;
+ if (extract_id_and_version(dirp->dir_entry[i].name, &info.key_id, &info.key_version) == 0)
+ {
+ key_info_cache[KEY_ID_AND_VERSION(info.key_id, info.key_version)]= info;
+ latest_version_cache[info.key_id]= max(info.key_version, latest_version_cache[info.key_id]);
+ }
+ }
+ my_dirend(dirp);
+ DBUG_RETURN(0);
+}
+
+
+static int plugin_deinit(void *p)
+{
+ DBUG_ENTER("plugin_deinit");
+ latest_version_cache.clear();
+ key_info_cache.clear();
+ mysql_mutex_destroy(&mtx);
+ delete client;
+ ShutdownAWSLogging();
+ DBUG_RETURN(0);
+}
+
+/* Generate filename to store the ciphered key */
+static void format_keyfile_name(char *buf, size_t size, uint key_id, uint version)
+{
+ snprintf(buf, size, "aws-kms-key.%u.%u", key_id, version);
+}
+
+/* Extract key id and version from file name */
+static int extract_id_and_version(const char *name, uint *id, uint *ver)
+{
+ int len;
+ int n= sscanf(name, "aws-kms-key.%u.%u%n", id, ver, &len);
+ if (n == 2 && *id > 0 && *ver > 0 && len == (int)strlen(name))
+ return 0;
+ return 1;
+}
+
+/*
+ Decrypt key stored in aws-kms-key.<id>.<version>
+ Cache the decrypted key.
+*/
+static int load_key(KEY_INFO *info)
+{
+ int ret;
+ char path[256];
+ DBUG_ENTER("load_key");
+ DBUG_PRINT("enter", ("id=%u,ver=%u", info->key_id, info->key_version));
+ format_keyfile_name(path, sizeof(path), info->key_id, info->key_version);
+ ret= aws_decrypt_key(path, info);
+ if (ret)
+ info->load_failed= true;
+
+ latest_version_cache[info->key_id]= max(latest_version_cache[info->key_id], info->key_version);
+ key_info_cache[KEY_ID_AND_VERSION(info->key_id, info->key_version)]= *info;
+
+ if (!ret)
+ {
+ sql_print_information("AWS KMS plugin: loaded key %u, version %u, key length %u bit",
+ info->key_id, info->key_version,(uint)info->length*8);
+ }
+ else
+ {
+ sql_print_warning("AWS KMS plugin: key %u, version %u could not be decrypted",
+ info->key_id, info->key_version);
+ }
+ DBUG_RETURN(ret);
+}
+
+
+/*
+ Get latest version for the key.
+
+ If key is not decrypted yet, this function also decrypt the key
+ and error will be returned if decryption fails.
+
+ The reason for that is that Innodb crashes
+ in case errors are returned by get_key(),
+
+ A new key will be created if it does not exist, provided there is
+ valid master_key_id.
+*/
+static unsigned int get_latest_key_version(unsigned int key_id)
+{
+ unsigned int ret;
+ DBUG_ENTER("get_latest_key_version");
+ mysql_mutex_lock(&mtx);
+ ret= get_latest_key_version_nolock(key_id);
+ mysql_mutex_unlock(&mtx);
+ DBUG_PRINT("info", ("key=%u,ret=%u", key_id, ret));
+ DBUG_RETURN(ret);
+}
+
+static unsigned int get_latest_key_version_nolock(unsigned int key_id)
+{
+ KEY_INFO info;
+ uint ver;
+ DBUG_ENTER("get_latest_key_version_nolock");
+ ver= latest_version_cache[key_id];
+ if (ver > 0)
+ {
+ info= key_info_cache[KEY_ID_AND_VERSION(key_id, ver)];
+ }
+ if (info.load_failed)
+ {
+ /* Decryption failed previously, don't retry */
+ DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID);
+ }
+ else if (ver > 0)
+ {
+ /* Key exists already, return it*/
+ if (info.length > 0)
+ DBUG_RETURN(ver);
+ }
+ else // (ver == 0)
+ {
+ /* Generate a new key, version 1 */
+ if (!master_key_id[0])
+ {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "Can't generate encryption key %u, because 'aws_key_management_master_key_id' parameter is not set",
+ MYF(0), key_id);
+ DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID);
+ }
+ if (aws_generate_datakey(key_id, 1) != 0)
+ DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID);
+ info.key_id= key_id;
+ info.key_version= 1;
+ info.length= 0;
+ }
+
+ if (load_key(&info))
+ DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID);
+ DBUG_RETURN(info.key_version);
+}
+
+
+/*
+ Decrypt a file with KMS
+*/
+static int aws_decrypt_key(const char *path, KEY_INFO *info)
+{
+ DBUG_ENTER("aws_decrypt_key");
+
+ /* Read file content into memory */
+ ifstream ifs(path, ios::binary | ios::ate);
+ if (!ifs.good())
+ {
+ sql_print_error("can't open file %s", path);
+ DBUG_RETURN(-1);
+ }
+ size_t pos = (size_t)ifs.tellg();
+ if (!pos || pos == SIZE_T_MAX)
+ {
+ sql_print_error("invalid key file %s", path);
+ DBUG_RETURN(-1);
+ }
+ std::vector<char> contents(pos);
+ ifs.seekg(0, ios::beg);
+ ifs.read(&contents[0], pos);
+
+ /* Decrypt data the with AWS */
+ DecryptRequest request;
+ Aws::Utils::ByteBuffer byteBuffer((unsigned char *)contents.data(), pos);
+ request.SetCiphertextBlob(byteBuffer);
+ DecryptOutcome outcome = client->Decrypt(request);
+ if (!outcome.IsSuccess())
+ {
+ sql_print_error("AWS KMS plugin: Decrypt failed for %s : %s", path,
+ outcome.GetError().GetMessage().c_str());
+ DBUG_RETURN(-1);
+ }
+ Aws::Utils::ByteBuffer plaintext = outcome.GetResult().GetPlaintext();
+ size_t len = plaintext.GetLength();
+
+ if (len > (int)sizeof(info->data))
+ {
+ sql_print_error("AWS KMS plugin: encoding key too large for %s", path);
+ DBUG_RETURN(ENCRYPTION_KEY_BUFFER_TOO_SMALL);
+ }
+ memcpy(info->data, plaintext.GetUnderlyingData(), len);
+ info->length= len;
+ DBUG_RETURN(0);
+}
+
+
+/* Generate a new datakey and store it a file */
+static int aws_generate_datakey(uint keyid, uint version)
+{
+
+ DBUG_ENTER("aws_generate_datakey");
+ GenerateDataKeyWithoutPlaintextRequest request;
+ request.SetKeyId(master_key_id);
+ request.SetKeySpec(DataKeySpecMapper::GetDataKeySpecForName(key_spec_names[key_spec]));
+
+ GenerateDataKeyWithoutPlaintextOutcome outcome;
+ outcome= client->GenerateDataKeyWithoutPlaintext(request);
+ if (!outcome.IsSuccess())
+ {
+ sql_print_error("AWS KMS plugin : GenerateDataKeyWithoutPlaintext failed : %s - %s",
+ outcome.GetError().GetExceptionName().c_str(),
+ outcome.GetError().GetMessage().c_str());
+ DBUG_RETURN(-1);
+ }
+
+ string out;
+ char filename[20];
+ Aws::Utils::ByteBuffer byteBuffer = outcome.GetResult().GetCiphertextBlob();
+
+ format_keyfile_name(filename, sizeof(filename), keyid, version);
+ int fd= my_open(filename, O_RDWR | O_CREAT, 0);
+ if (fd < 0)
+ {
+ sql_print_error("AWS KMS plugin: Can't create file %s", filename);
+ DBUG_RETURN(-1);
+ }
+ size_t len= byteBuffer.GetLength();
+ if (my_write(fd, byteBuffer.GetUnderlyingData(), len, 0) != len)
+ {
+ sql_print_error("AWS KMS plugin: can't write to %s", filename);
+ my_close(fd, 0);
+ my_delete(filename, 0);
+ DBUG_RETURN(-1);
+ }
+ my_close(fd, 0);
+ sql_print_information("AWS KMS plugin: generated encrypted datakey for key id=%u, version=%u",
+ keyid, version);
+ DBUG_RETURN(0);
+}
+
+/* Key rotation for a single key */
+static int rotate_single_key(uint key_id)
+{
+ uint ver;
+ ver= latest_version_cache[key_id];
+
+ if (!ver)
+ {
+ my_printf_error(ER_UNKNOWN_ERROR, "key %u does not exist", MYF(ME_JUST_WARNING), key_id);
+ return -1;
+ }
+ else if (aws_generate_datakey(key_id, ver + 1))
+ {
+ my_printf_error(ER_UNKNOWN_ERROR, "Could not generate datakey for key id= %u, ver= %u",
+ MYF(ME_JUST_WARNING), key_id, ver);
+ return -1;
+ }
+ else
+ {
+ KEY_INFO info;
+ info.key_id= key_id;
+ info.key_version = ver + 1;
+ if (load_key(&info))
+ {
+ my_printf_error(ER_UNKNOWN_ERROR, "Could not load datakey for key id= %u, ver= %u",
+ MYF(ME_JUST_WARNING), key_id, ver);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/* Key rotation for all key ids */
+static int rotate_all_keys()
+{
+ int ret= 0;
+ for (map<uint, uint>::iterator it= latest_version_cache.begin(); it != latest_version_cache.end(); it++)
+ {
+ ret= rotate_single_key(it->first);
+ if (ret)
+ break;
+ }
+ return ret;
+}
+
+static void update_rotate(MYSQL_THD, struct st_mysql_sys_var *, void *, const void *val)
+{
+ if (!master_key_id[0])
+ {
+ my_printf_error(ER_UNKNOWN_ERROR,
+ "aws_key_management_master_key_id must be set to generate new data keys", MYF(ME_JUST_WARNING));
+ return;
+ }
+ mysql_mutex_lock(&mtx);
+ rotate_key= *(int *)val;
+ switch (rotate_key)
+ {
+ case 0:
+ break;
+ case -1:
+ rotate_all_keys();
+ break;
+ default:
+ rotate_single_key(rotate_key);
+ break;
+ }
+ rotate_key= 0;
+ mysql_mutex_unlock(&mtx);
+}
+
+static unsigned int get_key(
+ unsigned int key_id,
+ unsigned int version,
+ unsigned char* dstbuf,
+ unsigned int* buflen)
+{
+ KEY_INFO info;
+
+ DBUG_ENTER("get_key");
+ mysql_mutex_lock(&mtx);
+ info= key_info_cache[KEY_ID_AND_VERSION(key_id, version)];
+ if (info.length == 0 && !info.load_failed)
+ {
+ info.key_id= key_id;
+ info.key_version= version;
+ load_key(&info);
+ }
+ mysql_mutex_unlock(&mtx);
+ if (info.load_failed)
+ DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID);
+ if (*buflen < info.length)
+ {
+ *buflen= info.length;
+ DBUG_RETURN(ENCRYPTION_KEY_BUFFER_TOO_SMALL);
+ }
+ *buflen= info.length;
+ memcpy(dstbuf, info.data, info.length);
+ DBUG_RETURN(0);
+}
+
+
+/* Plugin defs */
+struct st_mariadb_encryption aws_key_management_plugin= {
+ MariaDB_ENCRYPTION_INTERFACE_VERSION,
+ get_latest_key_version,
+ get_key,
+ // use default encrypt/decrypt functions
+ 0, 0, 0, 0, 0
+};
+
+
+static TYPELIB key_spec_typelib =
+{
+ array_elements(key_spec_names) - 1, "",
+ key_spec_names, NULL
+};
+
+const char *log_level_names[] =
+{
+ "Off",
+ "Fatal",
+ "Error",
+ "Warn",
+ "Info",
+ "Debug",
+ "Trace",
+ 0
+};
+
+static TYPELIB log_level_typelib =
+{
+ array_elements(log_level_names) - 1, "",
+ log_level_names, NULL
+};
+
+static MYSQL_SYSVAR_STR(master_key_id, master_key_id,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
+ "Key id for master encryption key. Used to create new datakeys. If not set, no new keys will be created",
+ NULL, NULL, "");
+
+static MYSQL_SYSVAR_ENUM(key_spec, key_spec,
+ PLUGIN_VAR_RQCMDARG,
+ "Encryption algorithm used to create new keys.",
+ NULL, NULL, 0, &key_spec_typelib);
+
+
+static MYSQL_SYSVAR_ENUM(log_level, log_level,
+ PLUGIN_VAR_RQCMDARG,
+ "Logging for AWS API",
+ NULL, NULL, 0, &log_level_typelib);
+
+
+static MYSQL_SYSVAR_INT(rotate_key, rotate_key,
+ PLUGIN_VAR_RQCMDARG,
+ "Set this variable to key id to perform rotation of the key. Specify -1 to rotate all keys",
+ NULL, update_rotate, 0, -1, INT_MAX, 1);
+
+static struct st_mysql_sys_var* settings[]= {
+ MYSQL_SYSVAR(master_key_id),
+ MYSQL_SYSVAR(key_spec),
+ MYSQL_SYSVAR(rotate_key),
+ MYSQL_SYSVAR(log_level),
+ NULL
+};
+
+/*
+ Plugin library descriptor
+*/
+maria_declare_plugin(aws_key_management)
+{
+ MariaDB_ENCRYPTION_PLUGIN,
+ &aws_key_management_plugin,
+ "aws_key_management",
+ "MariaDB Corporation",
+ "AWS key management plugin",
+ PLUGIN_LICENSE_GPL,
+ plugin_init,
+ plugin_deinit,
+ 0x0100,
+ NULL,
+ settings,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_EXPERIMENTAL
+}
+maria_declare_plugin_end;
diff --git a/plugin/cracklib_password_check/cracklib_password_check.c b/plugin/cracklib_password_check/cracklib_password_check.c
index c16075df74b..c593173942d 100644
--- a/plugin/cracklib_password_check/cracklib_password_check.c
+++ b/plugin/cracklib_password_check/cracklib_password_check.c
@@ -78,6 +78,6 @@ maria_declare_plugin(cracklib_password_check)
NULL,
sysvars,
"1.0",
- MariaDB_PLUGIN_MATURITY_ALPHA,
+ MariaDB_PLUGIN_MATURITY_GAMMA,
}
maria_declare_plugin_end;
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc
index 970fae9c189..e0afbd68cc9 100644
--- a/plugin/file_key_management/file_key_management_plugin.cc
+++ b/plugin/file_key_management/file_key_management_plugin.cc
@@ -186,6 +186,6 @@ maria_declare_plugin(file_key_management)
NULL, /* status variables */
settings,
"1.0",
- MariaDB_PLUGIN_MATURITY_ALPHA
+ MariaDB_PLUGIN_MATURITY_GAMMA
}
maria_declare_plugin_end;
diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc
index 28cd981df79..628412bc171 100644
--- a/plugin/file_key_management/parser.cc
+++ b/plugin/file_key_management/parser.cc
@@ -220,7 +220,7 @@ bool Parser::parse_file(Dynamic_array<keyentry> *keys, const char *secret)
keys->sort(sort_keys);
my_free(buffer);
- if (keys->at(0).id != 1)
+ if (keys->elements() == 0 || keys->at(0).id != 1)
{
report_error("System key id 1 is missing", 0);
return 1;
diff --git a/plugin/handler_socket/docs-en/perl-client.en.txt b/plugin/handler_socket/docs-en/perl-client.en.txt
index 448d33b5f12..cc9138518ee 100644
--- a/plugin/handler_socket/docs-en/perl-client.en.txt
+++ b/plugin/handler_socket/docs-en/perl-client.en.txt
@@ -42,7 +42,7 @@ to be retrieved are specified by the 5th argument for the
corresponding open_index call.
The execute_single method always returns an arrayref. The first
-element is the error code, which is 0 when no error is occured.
+element is the error code, which is 0 when no error is occurred.
The remaining are the field values. If more than one record is
returned, it is flatten to an 1-dimensional array. For example,
when 5 records that have 3 columns are returned, you can retrieve
@@ -125,9 +125,9 @@ methods.
die $hs->get_error() if $res->[0] != 0;
-----------------------------------------------------------------
-When an error is occured, the first element of the returned
+When an error is occurred, the first element of the returned
arrayref becomes a non-zero value. A negative value indicates
-that an I/O error is occured and the Net::HandlerSocket object
+that an I/O error is occurred and the Net::HandlerSocket object
should be disposed. A positive value means that the connection is
still active and the Net::HandlerSocket object can be reused
later.
diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp
index cfed9c42c0a..94eedbf6d04 100644
--- a/plugin/handler_socket/handlersocket/database.cpp
+++ b/plugin/handler_socket/handlersocket/database.cpp
@@ -304,6 +304,7 @@ dbcontext::init_thread(const void *stack_bottom, volatile int& shutdown_flag)
thd->db = 0;
thd->db = my_strdup("handlersocket", MYF(0));
}
+ thd->variables.option_bits |= OPTION_TABLE_LOCK;
my_pthread_setspecific_ptr(THR_THD, thd);
DBG_THR(fprintf(stderr, "HNDSOCK x0 %p\n", thd));
}
@@ -341,7 +342,7 @@ void
dbcontext::term_thread()
{
DBG_THR(fprintf(stderr, "HNDSOCK thread end %p\n", thd));
- unlock_tables_if();
+ close_tables_if();
my_pthread_setspecific_ptr(THR_THD, 0);
{
pthread_mutex_lock(&LOCK_thread_count);
diff --git a/plugin/locale_info/locale_info.cc b/plugin/locale_info/locale_info.cc
index dd14dcbb769..3d775c0be7c 100644
--- a/plugin/locale_info/locale_info.cc
+++ b/plugin/locale_info/locale_info.cc
@@ -117,6 +117,6 @@ maria_declare_plugin(locales)
NULL, /* Status variables */
NULL, /* System variables */
"1.0", /* String version representation */
- MariaDB_PLUGIN_MATURITY_GAMMA /* Maturity (see include/mysql/plugin.h)*/
+ MariaDB_PLUGIN_MATURITY_STABLE /* Maturity (see include/mysql/plugin.h)*/
}
maria_declare_plugin_end;
diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc
index fcfdb59da30..83db2c7ca5c 100644
--- a/plugin/metadata_lock_info/metadata_lock_info.cc
+++ b/plugin/metadata_lock_info/metadata_lock_info.cc
@@ -164,7 +164,7 @@ maria_declare_plugin(metadata_lock_info)
NULL,
NULL,
NULL,
- MariaDB_PLUGIN_MATURITY_GAMMA,
+ MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
#else
diff --git a/plugin/qc_info/qc_info.cc b/plugin/qc_info/qc_info.cc
index 998076dadf7..4ccfdc8f8c2 100644
--- a/plugin/qc_info/qc_info.cc
+++ b/plugin/qc_info/qc_info.cc
@@ -282,7 +282,7 @@ maria_declare_plugin(query_cache_info)
NULL, /* status variables */
NULL, /* system variables */
"1.1", /* version as a string */
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/plugin/query_response_time/mysql-test/query_response_time/basic.result b/plugin/query_response_time/mysql-test/query_response_time/basic.result
index 15746424b1d..86fba87e056 100644
--- a/plugin/query_response_time/mysql-test/query_response_time/basic.result
+++ b/plugin/query_response_time/mysql-test/query_response_time/basic.result
@@ -17,7 +17,7 @@ PLUGIN_TYPE INFORMATION SCHEMA
PLUGIN_AUTHOR Percona and Sergey Vojtovich
PLUGIN_DESCRIPTION Query Response Time Distribution INFORMATION_SCHEMA Plugin
PLUGIN_LICENSE GPL
-PLUGIN_MATURITY Gamma
+PLUGIN_MATURITY Stable
PLUGIN_NAME QUERY_RESPONSE_TIME_AUDIT
PLUGIN_VERSION 1.0
PLUGIN_TYPE AUDIT
diff --git a/plugin/query_response_time/plugin.cc b/plugin/query_response_time/plugin.cc
index c34e4cb6e02..37d52c3ce85 100644
--- a/plugin/query_response_time/plugin.cc
+++ b/plugin/query_response_time/plugin.cc
@@ -144,7 +144,7 @@ maria_declare_plugin(query_response_time)
NULL,
query_response_time_info_vars,
"1.0",
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
},
{
MYSQL_AUDIT_PLUGIN,
diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h
index d9dc4ce024b..c2862476ec8 100644
--- a/plugin/semisync/semisync_master.h
+++ b/plugin/semisync/semisync_master.h
@@ -102,7 +102,7 @@ public:
it are in use. A new Block is allocated and is put into the rear of the
Block link table if no Block is free.
- @return Return a TranxNode *, or NULL if an error occured.
+ @return Return a TranxNode *, or NULL if an error occurred.
*/
TranxNode *allocate_node()
{
@@ -134,7 +134,7 @@ public:
/**
All nodes are freed.
- @return Return 0, or 1 if an error occured.
+ @return Return 0, or 1 if an error occurred.
*/
int free_all_nodes()
{
@@ -150,7 +150,7 @@ public:
@param node All nodes before 'node' will be freed
- @return Return 0, or 1 if an error occured.
+ @return Return 0, or 1 if an error occurred.
*/
int free_nodes_before(TranxNode* node)
{
diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc
index 7bb0eea44ee..309910312c4 100644
--- a/plugin/semisync/semisync_master_plugin.cc
+++ b/plugin/semisync/semisync_master_plugin.cc
@@ -489,7 +489,7 @@ maria_declare_plugin(semisync_master)
semi_sync_master_status_vars, /* status variables */
semi_sync_master_system_vars, /* system variables */
"1.0",
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc
index 572ead214de..3a6c7625d93 100644
--- a/plugin/semisync/semisync_slave_plugin.cc
+++ b/plugin/semisync/semisync_slave_plugin.cc
@@ -227,7 +227,7 @@ maria_declare_plugin(semisync_slave)
semi_sync_slave_status_vars, /* status variables */
semi_sync_slave_system_vars, /* system variables */
"1.0",
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/plugin/simple_password_check/simple_password_check.c b/plugin/simple_password_check/simple_password_check.c
index f6d3e5b7a69..7ad8bfc811a 100644
--- a/plugin/simple_password_check/simple_password_check.c
+++ b/plugin/simple_password_check/simple_password_check.c
@@ -104,6 +104,6 @@ maria_declare_plugin(simple_password_check)
NULL,
sysvars,
"1.0",
- MariaDB_PLUGIN_MATURITY_ALPHA,
+ MariaDB_PLUGIN_MATURITY_GAMMA
}
maria_declare_plugin_end;
diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c
index 1c7e141c022..6ec4659d407 100644
--- a/plugin/sql_errlog/sql_errlog.c
+++ b/plugin/sql_errlog/sql_errlog.c
@@ -158,6 +158,6 @@ maria_declare_plugin(sql_errlog)
NULL,
vars,
"1.0",
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
diff --git a/plugin/userstat/userstat.cc b/plugin/userstat/userstat.cc
index 6ffee44f43c..69832f817c1 100644
--- a/plugin/userstat/userstat.cc
+++ b/plugin/userstat/userstat.cc
@@ -31,7 +31,7 @@ maria_declare_plugin(userstat)
NULL,
NULL,
"2.0",
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
},
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
@@ -46,7 +46,7 @@ maria_declare_plugin(userstat)
NULL,
NULL,
"2.0",
- MariaDB_PLUGIN_MATURITY_GAMMA
+ MariaDB_PLUGIN_MATURITY_STABLE
},
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
diff --git a/plugin/wsrep_info/plugin.cc b/plugin/wsrep_info/plugin.cc
index f3de177c85f..b8aaee5a132 100644
--- a/plugin/wsrep_info/plugin.cc
+++ b/plugin/wsrep_info/plugin.cc
@@ -245,7 +245,7 @@ maria_declare_plugin(wsrep_info)
NULL, /* Status variables */
NULL, /* System variables */
"1.0", /* Version (string) */
- MariaDB_PLUGIN_MATURITY_ALPHA /* Maturity */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* Maturity */
},
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
@@ -260,7 +260,7 @@ maria_declare_plugin(wsrep_info)
NULL, /* Status variables */
NULL, /* System variables */
"1.0", /* Version (string) */
- MariaDB_PLUGIN_MATURITY_ALPHA /* Maturity */
+ MariaDB_PLUGIN_MATURITY_GAMMA /* Maturity */
}
maria_declare_plugin_end;