summaryrefslogtreecommitdiff
path: root/http
diff options
context:
space:
mode:
Diffstat (limited to 'http')
-rw-r--r--http/mutual_tls.hpp14
-rw-r--r--http/mutual_tls_meta.hpp73
2 files changed, 87 insertions, 0 deletions
diff --git a/http/mutual_tls.hpp b/http/mutual_tls.hpp
index 64bcd490d4..1620054e1c 100644
--- a/http/mutual_tls.hpp
+++ b/http/mutual_tls.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "logging.hpp"
+#include "mutual_tls_meta.hpp"
#include "persistent_data.hpp"
#include <openssl/crypto.h>
@@ -88,6 +89,19 @@ inline std::shared_ptr<persistent_data::UserSession>
return nullptr;
}
sslUser.resize(lastChar);
+
+ // Meta Inc. CommonName parsing
+ if (bmcwebMTLSCommonNameParsingMeta)
+ {
+ std::optional<std::string_view> sslUserMeta =
+ mtlsMetaParseSslUser(sslUser);
+ if (!sslUserMeta)
+ {
+ return nullptr;
+ }
+ sslUser = *sslUserMeta;
+ }
+
std::string unsupportedClientId;
return persistent_data::SessionStore::getInstance().generateUserSession(
sslUser, clientIp, unsupportedClientId,
diff --git a/http/mutual_tls_meta.hpp b/http/mutual_tls_meta.hpp
new file mode 100644
index 0000000000..5e55db8e28
--- /dev/null
+++ b/http/mutual_tls_meta.hpp
@@ -0,0 +1,73 @@
+#pragma once
+
+#include "logging.hpp"
+
+#include <format>
+#include <optional>
+#include <string>
+#include <string_view>
+
+inline std::optional<std::string_view>
+ mtlsMetaParseSslUser(std::string_view sslUser)
+{
+ // Parses a Meta internal TLS client certificate Subject CN in
+ // '<entityType>:<entity>[/<hostname>]' format and returns the resulting
+ // POSIX-compatible local user name on success, null otherwise.
+ //
+ // Only entityType = "user" is supported for now.
+ //
+ // Example client subject CN -> local user name:
+ // "user:a_username/hostname" -> "a_username"
+
+ // Parse entityType
+ size_t colonIndex = sslUser.find(':');
+ if (colonIndex == std::string_view::npos)
+ {
+ BMCWEB_LOG_WARNING("Invalid Meta TLS client cert Subject CN: '{}'",
+ sslUser);
+ return std::nullopt;
+ }
+
+ std::string_view entityType = sslUser.substr(0, colonIndex);
+ sslUser.remove_prefix(colonIndex + 1);
+ if (entityType != "user")
+ {
+ BMCWEB_LOG_WARNING(
+ "Invalid/unsupported entityType='{}' in Meta TLS client cert Subject CN: '{}'",
+ entityType, sslUser);
+ return std::nullopt;
+ }
+
+ // Parse entity
+ size_t slashIndex = sslUser.find('/');
+ std::string_view entity;
+ if (slashIndex == std::string_view::npos)
+ {
+ // No '/' character, Subject CN is just '<entityType>:<entity>'
+ entity = sslUser;
+ }
+ else
+ {
+ // Subject CN ends with /<hostname>
+ entity = sslUser.substr(0, slashIndex);
+ sslUser.remove_prefix(slashIndex + 1);
+
+ if (entity.find_first_not_of(
+ "abcdefghijklmnopqrstuvwxyz0123456789_-.") != std::string::npos)
+ {
+ BMCWEB_LOG_WARNING(
+ "Invalid entity='{}' in Meta TLS client cert Subject CN: '{}'",
+ entity, sslUser);
+ return std::nullopt;
+ }
+ }
+
+ if (entity.empty())
+ {
+ BMCWEB_LOG_DEBUG("Invalid Meta TLS client cert Subject CN: '{}'",
+ sslUser);
+ return std::nullopt;
+ }
+
+ return entity;
+}