mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-04-18 21:44:02 +03:00
123 lines
3.4 KiB
C++
123 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) 2016 MariaDB Corporation Ab
|
|
*
|
|
* Use of this software is governed by the Business Source License included
|
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
*
|
|
* Change Date: 2025-05-25
|
|
*
|
|
* On the date above, in accordance with the Business Source License, use
|
|
* of this software will be governed by version 2 or later of the General
|
|
* Public License.
|
|
*/
|
|
|
|
#include <chrono>
|
|
#include <cstdio>
|
|
#include <getopt.h>
|
|
#include <unistd.h>
|
|
#include <openssl/err.h>
|
|
#include <openssl/evp.h>
|
|
#include <openssl/rand.h>
|
|
#include <openssl/opensslv.h>
|
|
|
|
#include "secrets.h"
|
|
#include "mcsconfig.h"
|
|
|
|
#ifdef OPENSSL_VERSION_PREREQ
|
|
#if OPENSSL_VERSION_PREREQ(3,0)
|
|
#define EVP_CIPHER_key_length EVP_CIPHER_get_key_length
|
|
#endif
|
|
#endif
|
|
|
|
using std::string;
|
|
using ByteVec = std::vector<uint8_t>;
|
|
|
|
struct option options[] = {
|
|
{"help", no_argument, nullptr, 'h'}, {"user", required_argument, nullptr, 'u'}, {nullptr, 0, nullptr, 0}};
|
|
|
|
const string default_user = "mysql";
|
|
|
|
ByteVec generate_encryption_key();
|
|
|
|
void print_usage(const char* executable, const char* default_directory)
|
|
{
|
|
const char msg[] =
|
|
R"(usage: %s [-h|--help] [directory]
|
|
This utility generates a random AES encryption key and init vector and writes
|
|
them to disk. The data is written to the file '%s', in the specified
|
|
directory. The key and init vector are used by the utility 'cspasswd' to
|
|
encrypt passwords used in Columnstore configuration files, as well as by Columnstore
|
|
itself to decrypt the passwords.
|
|
Re-creating the file invalidates all existing encrypted passwords in the
|
|
configuration files.
|
|
-h, --help Display this help
|
|
-u, --user Designate the owner of the generated file (default: '%s')
|
|
directory : The directory where to store the file in (default: '%s')
|
|
)";
|
|
printf(msg, executable, SECRETS_FILENAME, default_user.c_str(), default_directory);
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
const string default_directory = string(MCSDATADIR);
|
|
string username = default_user;
|
|
|
|
int c;
|
|
while ((c = getopt_long(argc, argv, "hu:", options, nullptr)) != -1)
|
|
{
|
|
switch (c)
|
|
{
|
|
case 'h': print_usage(argv[0], default_directory.c_str()); return EXIT_SUCCESS;
|
|
|
|
case 'u': username = optarg; break;
|
|
|
|
default: print_usage(argv[0], default_directory.c_str()); return EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
string filepath = default_directory;
|
|
if (optind < argc)
|
|
{
|
|
filepath = argv[optind];
|
|
}
|
|
filepath.append("/").append(SECRETS_FILENAME);
|
|
|
|
// Check that the file doesn't exist.
|
|
errno = 0;
|
|
auto filepathc = filepath.c_str();
|
|
if (access(filepathc, F_OK) == 0)
|
|
{
|
|
printf("Secrets file '%s' already exists. Delete it before generating a new encryption key.\n",
|
|
filepathc);
|
|
return EXIT_FAILURE;
|
|
}
|
|
else if (errno != ENOENT)
|
|
{
|
|
printf("stat() for secrets file '%s' failed unexpectedly. Error %i, %s.\n", filepathc, errno,
|
|
strerror(errno));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
int rval = EXIT_FAILURE;
|
|
auto new_key = generate_encryption_key();
|
|
if (!new_key.empty() && secrets_write_keys(new_key, filepath, username))
|
|
{
|
|
rval = EXIT_SUCCESS;
|
|
}
|
|
return rval;
|
|
}
|
|
|
|
ByteVec generate_encryption_key()
|
|
{
|
|
int keylen = EVP_CIPHER_key_length(secrets_cipher());
|
|
ByteVec key(keylen);
|
|
// Generate random bytes using OpenSSL.
|
|
if (RAND_bytes(key.data(), keylen) != 1)
|
|
{
|
|
auto errornum = ERR_get_error();
|
|
printf("OpenSSL RAND_bytes() failed. %s.\n", ERR_error_string(errornum, nullptr));
|
|
key.clear();
|
|
}
|
|
return key;
|
|
}
|