diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2017-04-25 15:44:18 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-04-27 19:12:38 +0200 |
commit | 7bf409593e624deb00265e21e0d4579ce9fa7999 (patch) | |
tree | 7da6af1ff5a92126af5969a9504a82ddcf4cf263 /plugin/file_key_management | |
parent | db3910741347e7d741f4a854075c248e9081d722 (diff) | |
download | mariadb-git-7bf409593e624deb00265e21e0d4579ce9fa7999.tar.gz |
MDEV-11660 Make encryption plugins "pure"
Do not exporting mysqld entry points directly.
This is needed for mariabackup, to load encryption plugins on Windows.
All plugins are "pure" by default. To mark plugin "impure"
it should use RECOMPILE_FOR_EMBEDDED or STORAGE_ENGINE keyword.
Diffstat (limited to 'plugin/file_key_management')
-rw-r--r-- | plugin/file_key_management/file_key_management_plugin.cc | 18 | ||||
-rw-r--r-- | plugin/file_key_management/parser.cc | 106 | ||||
-rw-r--r-- | plugin/file_key_management/parser.h | 6 |
3 files changed, 76 insertions, 54 deletions
diff --git a/plugin/file_key_management/file_key_management_plugin.cc b/plugin/file_key_management/file_key_management_plugin.cc index 2c3e22c02d2..f6f7083d5f7 100644 --- a/plugin/file_key_management/file_key_management_plugin.cc +++ b/plugin/file_key_management/file_key_management_plugin.cc @@ -66,22 +66,14 @@ static struct st_mysql_sys_var* settings[] = { NULL }; -Dynamic_array<keyentry> keys(static_cast<uint>(0)); +std::map<unsigned int,keyentry> keys; static keyentry *get_key(unsigned int key_id) { - keyentry *a= keys.front(), *b= keys.back() + 1, *c; - while (b - a > 1) - { - c= a + (b - a)/2; - if (c->id == key_id) - return c; - else if (c->id < key_id) - a= c; - else - b= c; - } - return a->id == key_id ? a : 0; + keyentry &key= keys[key_id]; + if (key.id == 0) + return 0; + return &key; } /* the version is always the same, no automatic key rotation */ diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index facea9fad25..ac78186a488 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -143,13 +143,13 @@ void Parser::bytes_to_key(const unsigned char *salt, const char *input, } -bool Parser::parse(Dynamic_array<keyentry> *keys) +bool Parser::parse(std::map<uint,keyentry> *keys) { const char *secret= filekey; char buf[MAX_SECRET_SIZE + 1]; //If secret starts with FILE: interpret the secret as a filename. - if (is_prefix(filekey, FILE_PREFIX)) + if (strncmp(filekey, FILE_PREFIX,sizeof(FILE_PREFIX) -1) == 0) { if (read_filekey(filekey + sizeof(FILE_PREFIX) - 1, buf)) return 1; @@ -166,22 +166,26 @@ bool Parser::parse(Dynamic_array<keyentry> *keys) bool Parser::read_filekey(const char *filekey, char *secret) { - int f= my_open(filekey, O_RDONLY, MYF(MY_WME)); + int f= open(filekey, O_RDONLY|O_BINARY); if (f == -1) + { + my_error(EE_FILENOTFOUND,ME_ERROR_LOG, filekey, errno); return 1; - int len= my_read(f, (uchar*)secret, MAX_SECRET_SIZE, MYF(MY_WME)); - my_close(f, MYF(MY_WME)); + } + + int len= read(f, secret, MAX_SECRET_SIZE); if (len <= 0) + { + my_error(EE_READ,ME_ERROR_LOG, filekey, errno); + close(f); return 1; + } + close(f); while (secret[len - 1] == '\r' || secret[len - 1] == '\n') len--; secret[len]= '\0'; return 0; } -static int sort_keys(const keyentry *k1, const keyentry *k2) -{ - return k1->id < k2->id ? -1 : k1->id > k2->id; -} /** Get the keys from the key file <filename> and decrypt it with the @@ -191,7 +195,7 @@ static int sort_keys(const keyentry *k1, const keyentry *k2) @return 0 when ok, 1 for an error */ -bool Parser::parse_file(Dynamic_array<keyentry> *keys, const char *secret) +bool Parser::parse_file(std::map<uint,keyentry> *keys, const char *secret) { char *buffer= read_and_decrypt_file(secret); @@ -208,19 +212,16 @@ bool Parser::parse_file(Dynamic_array<keyentry> *keys, const char *secret) case 1: // comment break; case -1: // error - my_free(buffer); + free(buffer); return 1; case 0: - if (keys->push(key)) - return 1; + (*keys)[key.id] = key; break; } } - keys->sort(sort_keys); - my_free(buffer); - - if (keys->elements() == 0 || keys->at(0).id != 1) + free(buffer); + if (keys->size() == 0 || (*keys)[1].id == 0) { report_error("System key id 1 is missing", 0); return 1; @@ -247,16 +248,25 @@ int Parser::parse_line(char **line_ptr, keyentry *key) while (isspace(*p) && *p != '\n') p++; if (*p != '#' && *p != '\n') { - int error; - p+= 100; // the number will surely end here (on a non-digit or with an overflow) - longlong id= my_strtoll10(p - 100, &p, &error); - if (error) + if (!isdigit(*p)) { report_error("Syntax error", p - *line_ptr); return -1; } - if (id < 1 || id > UINT_MAX32) + longlong id = 0; + while (isdigit(*p)) + { + id = id * 10 + *p - '0'; + if (id > UINT_MAX32) + { + report_error("Invalid key id", p - *line_ptr); + return -1; + } + p++; + } + + if (id < 1) { report_error("Invalid key id", p - *line_ptr); return -1; @@ -269,7 +279,7 @@ int Parser::parse_line(char **line_ptr, keyentry *key) } p++; - key->id= id; + key->id= (unsigned int)id; key->length=0; while (isxdigit(p[0]) && isxdigit(p[1]) && key->length < sizeof(key->key)) { @@ -295,9 +305,13 @@ int Parser::parse_line(char **line_ptr, keyentry *key) 'secret'. Store the content of the decrypted file in 'buffer'. The buffer has to be freed in the calling function. */ +#ifdef _WIN32 +#define lseek _lseeki64 +#endif char* Parser::read_and_decrypt_file(const char *secret) { + int f; if (!filename || !filename[0]) { my_printf_error(EE_CANT_OPEN_STREAM, "file-key-management-filename is not set", @@ -305,15 +319,21 @@ char* Parser::read_and_decrypt_file(const char *secret) goto err0; } - int f; - if ((f= my_open(filename, O_RDONLY, MYF(MY_WME))) < 0) + f= open(filename, O_RDONLY|O_BINARY, 0); + if (f < 0) + { + my_error(EE_FILENOTFOUND, ME_ERROR_LOG, filename, errno); goto err0; + } my_off_t file_size; - file_size= my_seek(f, 0, SEEK_END, MYF(MY_WME)); + file_size= lseek(f, 0, SEEK_END); - if (file_size == MY_FILEPOS_ERROR) + if (file_size == MY_FILEPOS_ERROR || (my_off_t)lseek(f, 0, SEEK_SET) == MY_FILEPOS_ERROR) + { + my_error(EE_CANT_SEEK, MYF(0), filename, errno); goto err1; + } if (file_size > MAX_KEY_FILE_SIZE) { @@ -323,29 +343,39 @@ char* Parser::read_and_decrypt_file(const char *secret) //Read file into buffer uchar *buffer; - buffer= (uchar*)my_malloc(file_size + 1, MYF(MY_WME)); + buffer= (uchar*)malloc((size_t)file_size + 1); if (!buffer) + { + my_error(EE_OUTOFMEMORY, ME_ERROR_LOG| ME_FATAL, file_size); goto err1; + } - if (my_pread(f, buffer, file_size, 0, MYF(MY_WME)) != file_size) + if (read(f, buffer, (int)file_size) != (int)file_size) + { + my_printf_error(EE_READ, + "read from %s failed, errno %d", + MYF(ME_ERROR_LOG|ME_FATAL), filename, errno); goto err2; + } // Check for file encryption uchar *decrypted; - if (file_size > OpenSSL_prefix_len && is_prefix((char*)buffer, OpenSSL_prefix)) + if (file_size > OpenSSL_prefix_len && strncmp((char*)buffer, OpenSSL_prefix, OpenSSL_prefix_len) == 0) { uchar key[OpenSSL_key_len]; uchar iv[OpenSSL_iv_len]; - decrypted= (uchar*)my_malloc(file_size, MYF(MY_WME)); + decrypted= (uchar*)malloc((size_t)file_size); if (!decrypted) + { + my_error(EE_OUTOFMEMORY, ME_ERROR_LOG | ME_FATAL, file_size); goto err2; - + } bytes_to_key(buffer + OpenSSL_prefix_len, secret, key, iv); uint32 d_size; if (my_aes_crypt(MY_AES_CBC, ENCRYPTION_FLAG_DECRYPT, buffer + OpenSSL_prefix_len + OpenSSL_salt_len, - file_size - OpenSSL_prefix_len - OpenSSL_salt_len, + (unsigned int)file_size - OpenSSL_prefix_len - OpenSSL_salt_len, decrypted, &d_size, key, OpenSSL_key_len, iv, OpenSSL_iv_len)) @@ -354,7 +384,7 @@ char* Parser::read_and_decrypt_file(const char *secret) goto err3; } - my_free(buffer); + free(buffer); buffer= decrypted; file_size= d_size; } @@ -365,15 +395,15 @@ char* Parser::read_and_decrypt_file(const char *secret) } buffer[file_size]= '\0'; - my_close(f, MYF(MY_WME)); + close(f); return (char*) buffer; err3: - my_free(decrypted); + free(decrypted); err2: - my_free(buffer); + free(buffer); err1: - my_close(f, MYF(MY_WME)); + close(f); err0: return NULL; } diff --git a/plugin/file_key_management/parser.h b/plugin/file_key_management/parser.h index c8349db70a0..627b7fd84a6 100644 --- a/plugin/file_key_management/parser.h +++ b/plugin/file_key_management/parser.h @@ -22,7 +22,7 @@ Created 09/15/2014 #include <my_crypt.h> #include <ctype.h> -#include <sql_array.h> +#include <map> struct keyentry { unsigned int id; @@ -42,7 +42,7 @@ class Parser void bytes_to_key(const unsigned char *salt, const char *secret, unsigned char *key, unsigned char *iv); bool read_filekey(const char *filekey, char *secret); - bool parse_file(Dynamic_array<keyentry> *keys, const char *secret); + bool parse_file(std::map<unsigned int ,keyentry> *keys, const char *secret); void report_error(const char *reason, unsigned int position); int parse_line(char **line_ptr, keyentry *key); char* read_and_decrypt_file(const char *secret); @@ -50,5 +50,5 @@ class Parser public: Parser(const char* fn, const char *fk) : filename(fn), filekey(fk), line_number(0) { } - bool parse(Dynamic_array<keyentry> *keys); + bool parse(std::map<unsigned int ,keyentry> *keys); }; |