blob: 499d9a82b9a7ab1ef3a48bc0bef0d8fea6f5d5c4 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Marco Kawajiri0e373b52023-10-31 13:36:58 -07003#pragma once
4
5#include "logging.hpp"
6
7#include <format>
8#include <optional>
9#include <string>
10#include <string_view>
11
12inline std::optional<std::string_view>
13 mtlsMetaParseSslUser(std::string_view sslUser)
14{
15 // Parses a Meta internal TLS client certificate Subject CN in
16 // '<entityType>:<entity>[/<hostname>]' format and returns the resulting
17 // POSIX-compatible local user name on success, null otherwise.
18 //
19 // Only entityType = "user" is supported for now.
20 //
21 // Example client subject CN -> local user name:
22 // "user:a_username/hostname" -> "a_username"
23
24 // Parse entityType
25 size_t colonIndex = sslUser.find(':');
26 if (colonIndex == std::string_view::npos)
27 {
28 BMCWEB_LOG_WARNING("Invalid Meta TLS client cert Subject CN: '{}'",
29 sslUser);
30 return std::nullopt;
31 }
32
33 std::string_view entityType = sslUser.substr(0, colonIndex);
34 sslUser.remove_prefix(colonIndex + 1);
35 if (entityType != "user")
36 {
37 BMCWEB_LOG_WARNING(
38 "Invalid/unsupported entityType='{}' in Meta TLS client cert Subject CN: '{}'",
39 entityType, sslUser);
40 return std::nullopt;
41 }
42
43 // Parse entity
44 size_t slashIndex = sslUser.find('/');
45 std::string_view entity;
46 if (slashIndex == std::string_view::npos)
47 {
48 // No '/' character, Subject CN is just '<entityType>:<entity>'
49 entity = sslUser;
50 }
51 else
52 {
53 // Subject CN ends with /<hostname>
54 entity = sslUser.substr(0, slashIndex);
55 sslUser.remove_prefix(slashIndex + 1);
56
57 if (entity.find_first_not_of(
58 "abcdefghijklmnopqrstuvwxyz0123456789_-.") != std::string::npos)
59 {
60 BMCWEB_LOG_WARNING(
61 "Invalid entity='{}' in Meta TLS client cert Subject CN: '{}'",
62 entity, sslUser);
63 return std::nullopt;
64 }
65 }
66
67 if (entity.empty())
68 {
69 BMCWEB_LOG_DEBUG("Invalid Meta TLS client cert Subject CN: '{}'",
70 sslUser);
71 return std::nullopt;
72 }
73
74 return entity;
75}