ServerName.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* DEBUG: section 28 Access Control */
10
11#include "squid.h"
12#include "acl/FilledChecklist.h"
13#include "acl/ServerName.h"
14#include "client_side.h"
15#include "http/Stream.h"
16#include "HttpRequest.h"
17#include "ssl/bio.h"
18#include "ssl/ServerBump.h"
19#include "ssl/support.h"
20
21// Compare function for tree search algorithms
22static int
23aclHostDomainCompare( char *const &a, char * const &b)
24{
25 const char *h = static_cast<const char *>(a);
26 const char *d = static_cast<const char *>(b);
27 debugs(28, 7, "Match:" << h << " <> " << d);
29}
30
31bool
32ACLServerNameData::match(const char *host)
33{
34 if (host == nullptr)
35 return 0;
36
37 debugs(28, 3, "checking '" << host << "'");
38
39 char *h = const_cast<char *>(host);
40 char const * const * result = domains->find(h, aclHostDomainCompare);
41
42 debugs(28, 3, "'" << host << "' " << (result ? "found" : "NOT found"));
43
44 return (result != nullptr);
45
46}
47
51template<class MatchType>
52int
53check_cert_domain( void *check_data, ASN1_STRING *cn_data)
54{
55 char cn[1024];
56 ACLData<MatchType> * data = (ACLData<MatchType> *)check_data;
57
58 if (cn_data->length > (int)sizeof(cn) - 1)
59 return 1; // ignore data that does not fit our buffer
60
61 char *s = reinterpret_cast<char *>(cn_data->data);
62 char *d = cn;
63 for (int i = 0; i < cn_data->length; ++i, ++d, ++s) {
64 if (*s == '\0')
65 return 1; // always a domain mismatch. contains 0x00
66 *d = *s;
67 }
68 cn[cn_data->length] = '\0';
69 debugs(28, 4, "Verifying certificate name/subjectAltName " << cn);
70 if (data->match(cn))
71 return 0;
72 return 1;
73}
74
75int
77{
78 const auto checklist = Filled(ch);
79
80 assert(checklist != nullptr && checklist->request != nullptr);
81
82 const char *serverName = nullptr;
83 SBuf clientSniKeeper; // because c_str() is not constant
84 if (ConnStateData *conn = checklist->conn()) {
85 const char *clientRequestedServerName = nullptr;
86 clientSniKeeper = conn->tlsClientSni();
87 if (clientSniKeeper.isEmpty()) {
88 const char *host = checklist->request->url.host();
89 if (host && *host) // paranoid first condition: host() is never nil
90 clientRequestedServerName = host;
91 } else
92 clientRequestedServerName = clientSniKeeper.c_str();
93
94 if (useConsensus) {
95 X509 *peer_cert = conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr;
96 // use the client requested name if it matches the server
97 // certificate or if the certificate is not available
98 if (!peer_cert || Ssl::checkX509ServerValidity(peer_cert, clientRequestedServerName))
99 serverName = clientRequestedServerName;
100 } else if (useClientRequested)
101 serverName = clientRequestedServerName;
102 else { // either no options or useServerProvided
103 if (X509 *peer_cert = (conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr))
104 return Ssl::matchX509CommonNames(peer_cert, data.get(), check_cert_domain<const char*>);
106 serverName = clientRequestedServerName;
107 }
108 }
109
110 if (!serverName)
111 serverName = "none";
112
113 return data->match(serverName);
114}
115
116const Acl::Options &
118{
119 static const Acl::BooleanOption ClientRequested("--client-requested");
120 static const Acl::BooleanOption ServerProvided("--server-provided");
121 static const Acl::BooleanOption Consensus("--consensus");
122 static const Acl::Options MyOptions = { &ClientRequested, &ServerProvided, &Consensus };
123 ClientRequested.linkWith(&useClientRequested);
124 ServerProvided.linkWith(&useServerProvided);
125 Consensus.linkWith(&useConsensus);
126 return MyOptions;
127}
128
129bool
131{
132 int optionCount = 0;
133
134 if (useClientRequested)
135 optionCount++;
136 if (useServerProvided)
137 optionCount++;
138 if (useConsensus)
139 optionCount++;
140
141 if (optionCount > 1) {
142 debugs(28, DBG_CRITICAL, "ERROR: Multiple options given for the server_name ACL");
143 return false;
144 }
145 return true;
146}
147
ACLFilledChecklist * Filled(ACLChecklist *checklist)
convenience and safety wrapper for dynamic_cast<ACLFilledChecklist*>
int check_cert_domain(void *check_data, ASN1_STRING *cn_data)
Definition: ServerName.cc:53
static int aclHostDomainCompare(char *const &a, char *const &b)
Definition: ServerName.cc:23
int conn
the current server connection FD
Definition: Transport.cc:26
int matchDomainName(const char *h, const char *d, MatchDomainNameFlags flags)
Definition: Uri.cc:820
@ mdnHonorWildcards
Definition: Uri.h:230
#define assert(EX)
Definition: assert.h:17
Configured ACL parameter(s) (e.g., domain names in dstdomain ACL).
Definition: Data.h:18
virtual bool match(M)=0
Splay< char * > * domains
Definition: DomainData.h:28
bool match(const char *) override
Definition: ServerName.cc:32
const Acl::Options & options() override
Definition: ServerName.cc:117
Acl::BooleanOptionValue useConsensus
Ignore mismatching names.
Definition: ServerName.h:38
bool valid() const override
Definition: ServerName.cc:130
Acl::BooleanOptionValue useClientRequested
Ignore server-supplied names.
Definition: ServerName.h:36
Acl::BooleanOptionValue useServerProvided
Ignore client-supplied names.
Definition: ServerName.h:37
int match(ACLChecklist *) override
Matches the actual data in checklist against this ACL.
Definition: ServerName.cc:76
a type-specific Option (e.g., a boolean –toggle or -m=SBuf)
Definition: Options.h:130
void linkWith(Recipient *recipient) const
who to tell when this option is enabled
Definition: Options.h:137
Definition: SBuf.h:94
const char * c_str()
Definition: SBuf.cc:516
bool isEmpty() const
Definition: SBuf.h:431
Value const * find(FindValue const &, int(*compare)(FindValue const &a, Value const &b)) const
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define DBG_CRITICAL
Definition: Stream.h:37
bool checkX509ServerValidity(X509 *cert, const char *server)
Definition: support.cc:254
int matchX509CommonNames(X509 *peer_cert, void *check_data, int(*check_func)(void *check_data, ASN1_STRING *cn_data))
Definition: support.cc:195
std::vector< const Option * > Options
Definition: Options.h:214

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors