You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +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;
 | 
						|
}
 |