1 /* 2 Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 #ifndef KEYRING_INFO_INCLUDED 26 #define KEYRING_INFO_INCLUDED 27 28 #include <chrono> 29 #include <stdexcept> 30 #include <string> 31 32 namespace mysql_harness { 33 class Config; 34 } 35 36 /** 37 * @brief MasterKeyWriteError class represents error during writing 38 * master key using master-key-writer. More detail about the nature 39 * of the error can be accessed using what() member function. 40 */ 41 class MasterKeyWriteError : public std::runtime_error { 42 public: MasterKeyWriteError(const std::string & msg)43 explicit MasterKeyWriteError(const std::string &msg) 44 : std::runtime_error(msg) {} 45 }; 46 47 /** 48 * @brief MasterKeyReadError class represents error during reading 49 * master key using master-key-reader. More detail about the nature 50 * of the error can be accessed using what() member function. 51 */ 52 class MasterKeyReadError : public std::runtime_error { 53 public: MasterKeyReadError(const std::string & msg)54 explicit MasterKeyReadError(const std::string &msg) 55 : std::runtime_error(msg) {} 56 }; 57 58 /** 59 * @brief SetRouterIdEnvVariableError class represents error duing 60 * adding ROUTER_ID variable to environment. More detail about the 61 * nature of the error can be accessed using what() member function. 62 */ 63 class SetRouterIdEnvVariableError : public std::runtime_error { 64 public: SetRouterIdEnvVariableError(const std::string & msg)65 explicit SetRouterIdEnvVariableError(const std::string &msg) 66 : std::runtime_error(msg) {} 67 }; 68 69 /** 70 * @brief KeyringInfo class encapsulates loading and storing master key 71 * using master-key-reader and master-key-writer. 72 */ 73 class KeyringInfo { 74 private: 75 /** @brief The path to keyring file */ 76 std::string keyring_file_; 77 78 /** @brief The path to master key file, empty if master key file is not used 79 */ 80 std::string master_key_file_; 81 82 /** @brief The path to master-key-reader that is used to read master key */ 83 std::string master_key_reader_; 84 85 /** @brief The path to master-key-writer that is used to store master key */ 86 std::string master_key_writer_; 87 88 /** @brief The master key that is used to encode/decode keyring content */ 89 std::string master_key_; 90 91 /** @brief The maximum time to write master key using master-key-writer or 92 * read master key using master-key-fetcher. */ 93 std::chrono::milliseconds rw_timeout_ = std::chrono::milliseconds(30000); 94 95 /** @brief If true then log verbose error messages */ 96 bool verbose_ = true; 97 98 public: 99 /** 100 * Default constructor. 101 * 102 * @param verbose IF true then log verbose error messages 103 */ verbose_(verbose)104 KeyringInfo(bool verbose = true) noexcept : verbose_(verbose) {} 105 106 /** 107 * Constructs KeyringInfo and assigns keyring file and master key file 108 * 109 * @param keyring_file The path to keyring file 110 * @param master_key_file The path to master key file 111 */ KeyringInfo(const std::string & keyring_file,const std::string & master_key_file)112 KeyringInfo(const std::string &keyring_file, 113 const std::string &master_key_file) 114 : keyring_file_(keyring_file), master_key_file_(master_key_file) {} 115 set_keyring_file(const std::string & keyring_file)116 void set_keyring_file(const std::string &keyring_file) { 117 keyring_file_ = keyring_file; 118 } 119 get_keyring_file()120 const std::string &get_keyring_file() const noexcept { return keyring_file_; } 121 set_master_key_file(const std::string & master_key_file)122 void set_master_key_file(const std::string &master_key_file) { 123 master_key_file_ = master_key_file; 124 } 125 get_master_key_file()126 const std::string &get_master_key_file() const noexcept { 127 return master_key_file_; 128 } 129 set_master_key_reader(const std::string & master_key_reader)130 void set_master_key_reader(const std::string &master_key_reader) { 131 master_key_reader_ = master_key_reader; 132 } 133 get_master_key_reader()134 const std::string &get_master_key_reader() const noexcept { 135 return master_key_reader_; 136 } 137 set_master_key_writer(const std::string & master_key_writer)138 void set_master_key_writer(const std::string &master_key_writer) { 139 master_key_writer_ = master_key_writer; 140 } 141 get_master_key_writer()142 const std::string &get_master_key_writer() const noexcept { 143 return master_key_writer_; 144 } 145 set_master_key(const std::string & master_key)146 void set_master_key(const std::string &master_key) { 147 master_key_ = master_key; 148 } 149 get_master_key()150 const std::string &get_master_key() const noexcept { return master_key_; } 151 152 /** 153 * @brief Initializes KeyringInfo using data read from Config. It initializes 154 * keyring_file, master_key_file_, master_key_reader_ and master_key_writer. 155 * 156 * @param config The Config that is used to initialize KeyringInfo 157 */ 158 void init(mysql_harness::Config &config); 159 160 /** 161 * @brief Reads master key using master_key_reader_; 162 * 163 * @return true if successfully read master key, false otherwise. 164 */ 165 bool read_master_key() noexcept; 166 167 /** 168 * @brief Writes master key using master_key_writer_; 169 * 170 * @return true if write was successful, false otherwise. 171 */ 172 bool write_master_key() const noexcept; 173 174 /* 175 * @brief Generate master key and store it in KeyringInfo. Generated 176 * master key can be accessed using master_key_ attribute. 177 */ 178 void generate_master_key() noexcept; 179 180 /** 181 * @brief Adds ROUTER_ID variable to environment. 182 * 183 * @throw SetRouterIdEnvVariableError if adding ROUTER_ID to environment 184 * fails. 185 */ 186 void add_router_id_to_env(uint32_t router_id) const; 187 188 /** 189 * @brief Checks if master-key-reader/master-key-writer should be 190 * used to load/store master key. 191 * 192 * @return true if master-key-reader/master-key-writer should be used 193 * to load/store master key, false otherwise. 194 */ 195 bool use_master_key_external_facility() const noexcept; 196 197 /** 198 * @brief Checks if mysqlrouter.key and keyring files should be used to 199 * store master key. 200 * 201 * @return true if master key should be used to store master key, false 202 * otherwise. 203 */ 204 bool use_master_key_file() const noexcept; 205 206 /** 207 * @brief Checks if master key is correct: it cannot be empty, and cannot 208 * be longer than mysql_harness::kMaxKeyringKeyLength. 209 * 210 * @throw std::runtime_error if master key is empty or is longer than 211 * mysql_harness::kMaxKeyringKeyLength 212 */ 213 void validate_master_key() const; 214 215 /** 216 * @brief Returns path to keyring file based on data read from config or 217 * bootstrap directory. 218 * 219 * @return The path to keyring file 220 */ 221 std::string get_keyring_file(const mysql_harness::Config &config) const; 222 }; 223 224 #endif /* KEYRING_INFO_INCLUDED */ 225