diff options
Diffstat (limited to 'plugin/aws_key_management/aws_key_management_plugin.cc')
-rw-r--r-- | plugin/aws_key_management/aws_key_management_plugin.cc | 168 |
1 files changed, 84 insertions, 84 deletions
diff --git a/plugin/aws_key_management/aws_key_management_plugin.cc b/plugin/aws_key_management/aws_key_management_plugin.cc index 83966b97c17..d7a948369f5 100644 --- a/plugin/aws_key_management/aws_key_management_plugin.cc +++ b/plugin/aws_key_management/aws_key_management_plugin.cc @@ -16,15 +16,14 @@ #include <my_global.h> -#include <my_pthread.h> -#include <my_sys.h> -#include <my_dir.h> +#include <typelib.h> #include <mysql/plugin_encryption.h> #include <my_crypt.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <mysqld_error.h> +#include <my_sys.h> #include <map> #include <algorithm> #include <string> @@ -33,6 +32,10 @@ #include <sstream> #include <fstream> +#ifndef _WIN32 +#include <dirent.h> +#endif + #include <aws/core/Aws.h> #include <aws/core/client/AWSError.h> #include <aws/core/utils/logging/AWSLogging.h> @@ -48,9 +51,6 @@ 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 */ @@ -90,14 +90,8 @@ 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); +static std::mutex mtx; -/* 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; @@ -140,6 +134,33 @@ protected: } }; +/* Get list of files in current directory */ +static vector<string> traverse_current_directory() +{ + vector<string> v; +#ifdef _WIN32 + WIN32_FIND_DATA find_data; + HANDLE h= FindFirstFile("*.*", &find_data); + if (h == INVALID_HANDLE_VALUE) + return v; + do + { + v.push_back(find_data.cFileName); + } + while (FindNextFile(h, &find_data)); + FindClose(h); +#else + DIR *dir = opendir("."); + if (!dir) + return v; + struct dirent *e; + while ((e= readdir(dir))) + v.push_back(e->d_name); + closedir(dir); +#endif + return v; +} + Aws::SDKOptions sdkOptions; /* @@ -150,7 +171,6 @@ Aws::SDKOptions sdkOptions; */ static int plugin_init(void *p) { - DBUG_ENTER("plugin_init"); #ifdef HAVE_YASSL sdkOptions.cryptoOptions.initAndCleanupOpenSSL = true; @@ -175,47 +195,34 @@ static int plugin_init(void *p) client = new KMSClient(clientConfiguration); if (!client) { - sql_print_error("Can not initialize KMS client"); - DBUG_RETURN(-1); + my_printf_error(ER_UNKNOWN_ERROR, "Can not initialize KMS client", ME_ERROR_LOG | ME_WARNING); + return -1; } -#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++) + vector<string> files= traverse_current_directory(); + for (size_t i=0; i < files.size(); i++) { KEY_INFO info; - if (extract_id_and_version(dirp->dir_entry[i].name, &info.key_id, &info.key_version) == 0) + if (extract_id_and_version(files[i].c_str(), &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); + 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(); Aws::ShutdownAPI(sdkOptions); - DBUG_RETURN(0); + return 0; } /* Generate filename to store the ciphered key */ @@ -242,8 +249,7 @@ 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) @@ -254,15 +260,15 @@ static int load_key(KEY_INFO *info) if (!ret) { - sql_print_information("AWS KMS plugin: loaded key %u, version %u, key length %u bit", + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: loaded key %u, version %u, key length %u bit", ME_ERROR_LOG | ME_NOTE, 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", + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: key %u, version %u could not be decrypted", ME_ERROR_LOG | ME_WARNING, info->key_id, info->key_version); } - DBUG_RETURN(ret); + return ret; } @@ -281,19 +287,17 @@ static int load_key(KEY_INFO *info) static unsigned int get_latest_key_version(unsigned int key_id) { unsigned int ret; - DBUG_ENTER("get_latest_key_version"); - mysql_mutex_lock(&mtx); + mtx.lock(); 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); + mtx.unlock(); + 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) { @@ -302,13 +306,13 @@ static unsigned int get_latest_key_version_nolock(unsigned int key_id) if (info.load_failed) { /* Decryption failed previously, don't retry */ - DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID); + return(ENCRYPTION_KEY_VERSION_INVALID); } else if (ver > 0) { /* Key exists already, return it*/ if (info.length > 0) - DBUG_RETURN(ver); + return(ver); } else // (ver == 0) { @@ -318,18 +322,18 @@ static unsigned int get_latest_key_version_nolock(unsigned int key_id) 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); + return(ENCRYPTION_KEY_VERSION_INVALID); } if (aws_generate_datakey(key_id, 1) != 0) - DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID); + 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); + return(ENCRYPTION_KEY_VERSION_INVALID); + return(info.key_version); } @@ -338,20 +342,19 @@ static unsigned int get_latest_key_version_nolock(unsigned int key_id) */ 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); + my_printf_error(ER_UNKNOWN_ERROR, "can't open file %s", ME_ERROR_LOG, path); + 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); + my_printf_error(ER_UNKNOWN_ERROR, "invalid key file %s", ME_ERROR_LOG, path); + return(-1); } std::vector<char> contents(pos); ifs.seekg(0, ios::beg); @@ -364,29 +367,27 @@ static int aws_decrypt_key(const char *path, KEY_INFO *info) DecryptOutcome outcome = client->Decrypt(request); if (!outcome.IsSuccess()) { - sql_print_error("AWS KMS plugin: Decrypt failed for %s : %s", path, + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: Decrypt failed for %s : %s", ME_ERROR_LOG, path, outcome.GetError().GetMessage().c_str()); - DBUG_RETURN(-1); + 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); + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: encoding key too large for %s", ME_ERROR_LOG, path); + return(ENCRYPTION_KEY_BUFFER_TOO_SMALL); } memcpy(info->data, plaintext.GetUnderlyingData(), len); info->length= len; - DBUG_RETURN(0); + 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])); @@ -395,10 +396,10 @@ static int aws_generate_datakey(uint keyid, uint version) outcome= client->GenerateDataKeyWithoutPlaintext(request); if (!outcome.IsSuccess()) { - sql_print_error("AWS KMS plugin : GenerateDataKeyWithoutPlaintext failed : %s - %s", + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin : GenerateDataKeyWithoutPlaintext failed : %s - %s", ME_ERROR_LOG, outcome.GetError().GetExceptionName().c_str(), outcome.GetError().GetMessage().c_str()); - DBUG_RETURN(-1); + return(-1); } string out; @@ -406,24 +407,24 @@ static int aws_generate_datakey(uint keyid, uint version) 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); + int fd= open(filename, O_WRONLY |O_CREAT|O_BINARY, IF_WIN(_S_IREAD, S_IRUSR| S_IRGRP| S_IROTH)); if (fd < 0) { - sql_print_error("AWS KMS plugin: Can't create file %s", filename); - DBUG_RETURN(-1); + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: Can't create file %s", ME_ERROR_LOG, filename); + return(-1); } size_t len= byteBuffer.GetLength(); - if (my_write(fd, byteBuffer.GetUnderlyingData(), len, 0) != len) + if (write(fd, byteBuffer.GetUnderlyingData(), len) != 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_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: can't write to %s", ME_ERROR_LOG, filename); + close(fd); + unlink(filename); + return(-1); } - my_close(fd, 0); - sql_print_information("AWS KMS plugin: generated encrypted datakey for key id=%u, version=%u", + close(fd); + my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: generated encrypted datakey for key id=%u, version=%u", ME_ERROR_LOG | ME_NOTE, keyid, version); - DBUG_RETURN(0); + return(0); } /* Key rotation for a single key */ @@ -479,7 +480,7 @@ static void update_rotate(MYSQL_THD, struct st_mysql_sys_var *, void *, const vo "aws_key_management_master_key_id must be set to generate new data keys", MYF(ME_JUST_WARNING)); return; } - mysql_mutex_lock(&mtx); + mtx.lock(); rotate_key= *(int *)val; switch (rotate_key) { @@ -493,7 +494,7 @@ static void update_rotate(MYSQL_THD, struct st_mysql_sys_var *, void *, const vo break; } rotate_key= 0; - mysql_mutex_unlock(&mtx); + mtx.unlock(); } static unsigned int get_key( @@ -504,8 +505,7 @@ static unsigned int get_key( { KEY_INFO info; - DBUG_ENTER("get_key"); - mysql_mutex_lock(&mtx); + mtx.lock(); info= key_info_cache[KEY_ID_AND_VERSION(key_id, version)]; if (info.length == 0 && !info.load_failed) { @@ -513,17 +513,17 @@ static unsigned int get_key( info.key_version= version; load_key(&info); } - mysql_mutex_unlock(&mtx); + mtx.unlock(); if (info.load_failed) - DBUG_RETURN(ENCRYPTION_KEY_VERSION_INVALID); + return(ENCRYPTION_KEY_VERSION_INVALID); if (*buflen < info.length) { *buflen= info.length; - DBUG_RETURN(ENCRYPTION_KEY_BUFFER_TOO_SMALL); + return(ENCRYPTION_KEY_BUFFER_TOO_SMALL); } *buflen= info.length; memcpy(dstbuf, info.data, info.length); - DBUG_RETURN(0); + return(0); } |