1 /*
2  * Copyright (c) 2019, 2020, 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, version 2.0, 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 #include "plugin/x/src/server/builder/ssl_context_builder.h"
26 
27 #include <memory>
28 #include <string>
29 #include <utility>
30 
31 #include "plugin/x/src/config/config.h"
32 #include "plugin/x/src/module_mysqlx.h"
33 #include "plugin/x/src/ssl_context.h"
34 #include "plugin/x/src/variables/system_variables.h"
35 #include "plugin/x/src/xpl_log.h"
36 
37 namespace xpl {
38 
39 Ssl_context_builder::Ssl_config_local
get_mysqld_ssl_config() const40 Ssl_context_builder::get_mysqld_ssl_config() const {
41   Ssl_config_local result;
42   result.m_ssl_tls_version =
43       Plugin_system_variables::get_system_variable("tls_version");
44 
45   result.m_ssl_key = Plugin_system_variables::get_system_variable("ssl_key");
46   result.m_ssl_ca = Plugin_system_variables::get_system_variable("ssl_ca");
47   result.m_ssl_capath =
48       Plugin_system_variables::get_system_variable("ssl_capath");
49   result.m_ssl_cert = Plugin_system_variables::get_system_variable("ssl_cert");
50   result.m_ssl_cipher =
51       Plugin_system_variables::get_system_variable("ssl_cipher");
52   result.m_ssl_crl = Plugin_system_variables::get_system_variable("ssl_crl");
53   result.m_ssl_crlpath =
54       Plugin_system_variables::get_system_variable("ssl_crlpath");
55   result.m_have_ssl =
56       Plugin_system_variables::get_system_variable("have_ssl") == "YES";
57 
58   return result;
59 }
60 
choose_ssl_config(const bool mysqld_have_ssl,const xpl::Ssl_config & mysqld_ssl,const xpl::Ssl_config & mysqlx_ssl) const61 xpl::Ssl_config Ssl_context_builder::choose_ssl_config(
62     const bool mysqld_have_ssl, const xpl::Ssl_config &mysqld_ssl,
63     const xpl::Ssl_config &mysqlx_ssl) const {
64   if (mysqlx_ssl.is_configured()) {
65     log_info(ER_XPLUGIN_USING_SSL_CONF_FROM_MYSQLX);
66     return mysqlx_ssl;
67   }
68 
69   if (mysqld_have_ssl) {
70     log_info(ER_XPLUGIN_USING_SSL_CONF_FROM_SERVER);
71     return mysqld_ssl;
72   }
73 
74   log_info(ER_XPLUGIN_FAILED_TO_USE_SSL_CONF);
75 
76   return xpl::Ssl_config();
77 }
78 
setup_ssl_context(iface::Ssl_context * ssl_context) const79 void Ssl_context_builder::setup_ssl_context(
80     iface::Ssl_context *ssl_context) const {
81   auto ssl_config_from_mysqld_local = get_mysqld_ssl_config();
82   auto &ssl_config_from_plugin = xpl::Plugin_system_variables::m_ssl_config;
83   xpl::Ssl_config ssl_config_from_mysqld;
84 
85   ssl_config_from_mysqld.m_ssl_key = &ssl_config_from_mysqld_local.m_ssl_key[0];
86   ssl_config_from_mysqld.m_ssl_ca = &ssl_config_from_mysqld_local.m_ssl_ca[0];
87   ssl_config_from_mysqld.m_ssl_capath =
88       &ssl_config_from_mysqld_local.m_ssl_capath[0];
89   ssl_config_from_mysqld.m_ssl_cert =
90       &ssl_config_from_mysqld_local.m_ssl_cert[0];
91   ssl_config_from_mysqld.m_ssl_cipher =
92       &ssl_config_from_mysqld_local.m_ssl_cipher[0];
93   ssl_config_from_mysqld.m_ssl_crl = &ssl_config_from_mysqld_local.m_ssl_crl[0];
94   ssl_config_from_mysqld.m_ssl_crlpath =
95       &ssl_config_from_mysqld_local.m_ssl_crlpath[0];
96 
97   auto choosen_ssl_config =
98       choose_ssl_config(ssl_config_from_mysqld_local.m_have_ssl,
99                         ssl_config_from_mysqld, ssl_config_from_plugin);
100   const char *crl = choosen_ssl_config.m_ssl_crl;
101   const char *crlpath = choosen_ssl_config.m_ssl_crlpath;
102 
103   const bool ssl_setup_result = ssl_context->setup(
104       ssl_config_from_mysqld_local.m_ssl_tls_version.c_str(),
105       choosen_ssl_config.m_ssl_key, choosen_ssl_config.m_ssl_ca,
106       choosen_ssl_config.m_ssl_capath, choosen_ssl_config.m_ssl_cert,
107       choosen_ssl_config.m_ssl_cipher, crl, crlpath);
108 
109   if (ssl_setup_result) {
110     log_info(ER_XPLUGIN_USING_SSL_FOR_TLS_CONNECTION, "OpenSSL");
111   } else {
112     log_info(ER_XPLUGIN_REFERENCE_TO_SECURE_CONN_WITH_XPLUGIN);
113   }
114 }
115 
get_result_context() const116 std::unique_ptr<iface::Ssl_context> Ssl_context_builder::get_result_context()
117     const {
118   std::unique_ptr<iface::Ssl_context> result = std::make_unique<Ssl_context>();
119 
120   setup_ssl_context(result.get());
121 
122   return result;
123 }
124 
125 }  // namespace xpl
126