SNode.C
Loading...
Searching...
No Matches
servers.h
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#ifndef APPS_HTTP_MODEL_SERVERS_H
21#define APPS_HTTP_MODEL_SERVERS_H
22
23#define QUOTE_INCLUDE(a) STR_INCLUDE(a)
24#define STR_INCLUDE(a) #a
25
26// clang-format off
27#define WEBAPP_INCLUDE QUOTE_INCLUDE(express/STREAM/NET/WebApp.h)
28// clang-format on
29
30#include WEBAPP_INCLUDE // IWYU pragma: export
31
32#include "express/middleware/VerboseRequest.h"
33
34#ifndef DOXYGEN_SHOULD_SKIP_THIS
35
36#include "log/Logger.h"
37
38#if (STREAM_TYPE == TLS) // tls
39#include <cstddef>
40#include <openssl/ssl.h>
41#include <openssl/x509v3.h>
42#endif
43
44#endif /* DOXYGEN_SHOULD_SKIP_THIS */
45
46static express::Router getRouter() {
47 return express::middleware::VerboseRequest();
48}
49
50#if (STREAM_TYPE == LEGACY) // legacy
51
52namespace apps::http::legacy {
53
56
57 static WebApp getWebApp(const std::string& name) {
58 WebApp webApp = WebApp(name, getRouter());
59
60 return webApp;
61 }
62
63} // namespace apps::http::legacy
64
65#endif // (STREAM_TYPE == LEGACY) // legacy
66
67#if (STREAM_TYPE == TLS) // tls
68
69namespace apps::http::tls {
70
73
74 static WebApp getWebApp(const std::string& name) {
75 WebApp webApp(name, getRouter());
76
77 webApp.setOnConnect([webApp](SocketConnection* socketConnection) { // onConnect
78 VLOG(1) << "OnConnect " << webApp.getConfig().getInstanceName();
79
80 VLOG(1) << "\tLocal: " << socketConnection->getLocalAddress().toString();
81 VLOG(1) << "\tPeer: " << socketConnection->getRemoteAddress().toString();
82
83 /* Enable automatic hostname checks */
84 // X509_VERIFY_PARAM* param = SSL_get0_param(socketConnection->getSSL());
85
86 // X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
87 // if (!X509_VERIFY_PARAM_set1_host(param, "localhost", sizeof("localhost") - 1)) {
88 // // handle error
89 // socketConnection->close();
90 // }
91 });
92
93 webApp.setOnConnected([webApp](SocketConnection* socketConnection) { // onConnected
94 VLOG(1) << "OnConnected " << webApp.getConfig().getInstanceName();
95
96 X509* server_cert = SSL_get_peer_certificate(socketConnection->getSSL());
97 if (server_cert != nullptr) {
98 long verifyErr = SSL_get_verify_result(socketConnection->getSSL());
99
100 VLOG(1) << "\tPeer certificate verifyErr = " + std::to_string(verifyErr) + ": " +
101 std::string(X509_verify_cert_error_string(verifyErr));
102
103 char* str = X509_NAME_oneline(X509_get_subject_name(server_cert), nullptr, 0);
104 VLOG(1) << "\t Subject: " + std::string(str);
105 OPENSSL_free(str);
106
107 str = X509_NAME_oneline(X509_get_issuer_name(server_cert), nullptr, 0);
108 VLOG(1) << "\t Issuer: " + std::string(str);
109 OPENSSL_free(str);
110
111 // We could do all sorts of certificate verification stuff here before deallocating the certificate.
112
113 GENERAL_NAMES* subjectAltNames =
114 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr));
115#ifdef __GNUC__
116#pragma GCC diagnostic push
117#ifdef __has_warning
118#if __has_warning("-Wused-but-marked-unused")
119#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
120#endif
121#endif
122#endif
123 int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
124#ifdef __GNUC_
125#pragma GCC diagnostic pop
126#endif
127 VLOG(1) << "\t Subject alternative name count: " << altNameCount;
128 for (int32_t i = 0; i < altNameCount; ++i) {
129#ifdef __GNUC__
130#pragma GCC diagnostic push
131#ifdef __has_warning
132#if __has_warning("-Wused-but-marked-unused")
133#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
134#endif
135#endif
136#endif
137 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
138#ifdef __GNUC_
139#pragma GCC diagnostic pop
140#endif
141 if (generalName->type == GEN_URI) {
142 std::string subjectAltName =
143 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
144 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
145 VLOG(1) << "\t SAN (URI): '" + subjectAltName;
146 } else if (generalName->type == GEN_DNS) {
147 std::string subjectAltName =
148 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
149 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
150 VLOG(1) << "\t SAN (DNS): '" + subjectAltName;
151 } else {
152 VLOG(1) << "\t SAN (Type): '" + std::to_string(generalName->type);
153 }
154 }
155#ifdef __GNUC__
156#pragma GCC diagnostic push
157#ifdef __has_warning
158#if __has_warning("-Wused-but-marked-unused")
159#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
160#endif
161#endif
162#endif
163 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
164#ifdef __GNUC_
165#pragma GCC diagnostic pop
166#endif
167 X509_free(server_cert);
168 } else {
169 LOG(WARNING) << "\tPeer certificate: no certificate";
170 }
171 });
172
173 webApp.setOnDisconnect([webApp](SocketConnection* socketConnection) { // onDisconnect
174 VLOG(1) << "OnDisconnect " << webApp.getConfig().getInstanceName();
175
176 VLOG(1) << "\tLocal: " << socketConnection->getLocalAddress().toString();
177 VLOG(1) << "\tPeer: " << socketConnection->getRemoteAddress().toString();
178 });
179
180 return webApp;
181 }
182
183} // namespace apps::http::tls
184
185#endif // (STREAM_TYPE == TLS) // tls
186
187#endif // APPS_HTTP_MODEL_SERVERS_H
int main(int argc, char *argv[])
#define QUOTE_INCLUDE(a)
Definition clients.h:25
#define STR_INCLUDE(a)
Definition servers.h:26
static express::Router getRouter()
Definition servers.h:46
static WebApp getWebApp(const std::string &name)
Definition servers.h:57
static WebApp getWebApp(const std::string &name)
Definition servers.h:74