SNode.C
Loading...
Searching...
No Matches
ConfigTlsServer.cpp
Go to the documentation of this file.
1/*
2 * SNode.C - A Slim Toolkit for Network Communication
3 * Copyright (C) Volker Christian <me@vchrist.at>
4 * 2020, 2021, 2022, 2023, 2024, 2025
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * MIT License
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 * THE SOFTWARE.
40 */
41
42#include "net/config/ConfigTlsServer.h"
43
44#include "net/config/ConfigSection.hpp"
45
46#ifndef DOXYGEN_SHOULD_SKIP_THIS
47
48#include <functional>
49#include <memory>
50
51#endif // DOXYGEN_SHOULD_SKIP_THIS
52
53namespace net::config {
54
56 : Super(instance) {
58 ->add_option("--sni-cert",
60 "Server Name Indication (SNI) Certificates:\n"
61 "sni = SNI of the virtual server\n"
62 "<key> = {\n"
63 " Cert -> value:PEM-FILE [\"\"]\n"
64 " CertKey -> value:PEM-FILE [\"\"]\n"
65 " CertKeyPassword -> value:TEXT [\"\"]\n"
66 " CaCert -> value:PEM-FILE [\"\"]\n"
67 " CaCertDir -> value:PEM-CONTAINER-DIR [\"\"]\n"
68 " CaCertUseDefaultDir -> value:BOOLEAN [false]\n"
69 " CipherList -> value:CIPHER [\"\"]\n"
70 " SslOptions -> value:UINT [0]\n"
71 "}") //
72 ->type_name("sni <key> value [<key> value] ... [%% sni <key> value [<key> value] ...]")
73 ->default_str("[\"\" \"\" \"\" \"\"]");
74 if (sniCertsOpt->get_configurable()) {
75 sniCertsOpt->group(section->get_formatter()->get_label("Persistent Options"));
76 }
77
78 sniCertsOpt->default_function([this]() -> std::string {
79 std::string defaultValue;
80
81 for (const auto& [domain, sniCertConf] : defaultSniCerts) {
82 defaultValue += (!defaultValue.empty() ? "\"%%\" \"" : "\"") + domain + "\" ";
83
84 for (const auto& [key, value] : sniCertConf) {
85 defaultValue += "\"" + key + "\" ";
86
87 if (key == "Cert") {
88 defaultValue += "\"" + std::get<std::string>(value) + "\" ";
89 } else if (key == "CertKey") {
90 defaultValue += "\"" + std::get<std::string>(value) + "\" ";
91 } else if (key == "CertKeyPassword") {
92 defaultValue += "\"" + std::get<std::string>(value) + "\" ";
93 } else if (key == "CaCert") {
94 defaultValue += "\"" + std::get<std::string>(value) + "\" ";
95 } else if (key == "CaCertDir") {
96 defaultValue += "\"" + std::get<std::string>(value) + "\" ";
97 } else if (key == "CaCertUseDefaultDir") {
98 defaultValue += std::get<bool>(value) ? "\"true\" " : "\"false\" ";
99 } else if (key == "CipherList") {
100 defaultValue += "\"" + std::get<std::string>(value) + "\" ";
101 } else if (key == "SslOptions") {
102 defaultValue += "\"" + std::to_string(std::get<ssl_option_t>(value)) + "\" ";
103 }
104 }
105 }
106
107 defaultValue.pop_back();
108
109 return "[" + defaultValue + " \"\"]";
110 });
111
113 "--force-sni{true}",
114 "Force using of the Server Name Indication",
115 "bool",
116 "false",
117 CLI::IsMember({"true", "false"}));
118
119 section->final_callback([this]() {
120 for (auto& [domain, sniMap] : configuredSniCerts) {
121 if (domain.empty()) {
122 sniCertsOpt //
123 ->clear();
124 sniMap.clear();
125 break;
126 }
127 for (auto& [key, value] : sniMap) {
128 if (key != "Cert" && //
129 key != "CertKey" && //
130 key != "CertKeyPassword" && //
131 key != "CaCert" && //
132 key != "CaCertDir" && //
133 key != "CaCertUseDefaultDir" && //
134 key != "CipherList" && //
135 key != "SslOptions") {
136 throw CLI::ConversionError("'" + key + "' of option '--" + section->get_parent()->get_name() + "." +
137 section->get_name() + ".sni-cert'",
138 "<key>");
139 }
140 }
141 }
142 });
143 }
144
146 forceSniOpt //
147 ->default_val(forceSni ? "true" : "false")
148 ->clear();
149
150 return *this;
151 }
152
154 return forceSniOpt->as<bool>();
155 }
156
158 const std::map<std::string, std::map<std::string, std::variant<std::string, bool, ssl_option_t>>>& sniCerts) {
159 defaultSniCerts.insert(sniCerts.begin(), sniCerts.end());
160 sniCertsOpt->capture_default_str();
161
162 return *this;
163 }
164
165 ConfigTlsServer& ConfigTlsServer::addSniCert(const std::string& domain,
166 const std::map<std::string, std::variant<std::string, bool, ssl_option_t>>& sniCert) {
167 defaultSniCerts[domain] = sniCert;
168 sniCertsOpt->capture_default_str();
169
170 return *this;
171 }
172
173 const std::map<std::string, std::map<std::string, std::variant<std::string, bool, ssl_option_t>>>& ConfigTlsServer::getSniCerts() {
175 }
176
177} // namespace net::config
CLI::Option * addFlag(const std::string &name, const std::string &description, const std::string &typeName, ValueTypeT defaultValue, const CLI::Validator &additionalValidator)
std::map< std::string, std::map< std::string, std::variant< std::string, bool, ssl_option_t > > > configuredSniCerts
ConfigTlsServer & addSniCerts(const std::map< std::string, std::map< std::string, std::variant< std::string, bool, ssl_option_t > > > &sniCerts)
ConfigTlsServer(ConfigInstance *instance)
ConfigTlsServer & setForceSni(bool forceSni=true)
std::map< std::string, std::map< std::string, std::variant< std::string, bool, ssl_option_t > > > defaultSniCerts
ConfigTlsServer & addSniCert(const std::string &domain, const std::map< std::string, std::variant< std::string, bool, ssl_option_t > > &sniCert)
const std::map< std::string, std::map< std::string, std::variant< std::string, bool, ssl_option_t > > > & getSniCerts()
ConfigTls(ConfigInstance *instance)
Definition ConfigTls.cpp:52