ServerName.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2022 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/DomainData.h"
13 #include "acl/FilledChecklist.h"
14 #include "acl/RegexData.h"
15 #include "acl/ServerName.h"
16 #include "client_side.h"
17 #include "fde.h"
18 #include "http/Stream.h"
19 #include "HttpRequest.h"
20 #include "ipcache.h"
21 #include "SquidString.h"
22 #include "ssl/bio.h"
23 #include "ssl/ServerBump.h"
24 #include "ssl/support.h"
25 
26 // Compare function for tree search algorithms
27 static int
28 aclHostDomainCompare( char *const &a, char * const &b)
29 {
30  const char *h = static_cast<const char *>(a);
31  const char *d = static_cast<const char *>(b);
32  debugs(28, 7, "Match:" << h << " <> " << d);
33  return matchDomainName(h, d, mdnHonorWildcards);
34 }
35 
36 bool
37 ACLServerNameData::match(const char *host)
38 {
39  if (host == nullptr)
40  return 0;
41 
42  debugs(28, 3, "checking '" << host << "'");
43 
44  char *h = const_cast<char *>(host);
45  char const * const * result = domains->find(h, aclHostDomainCompare);
46 
47  debugs(28, 3, "'" << host << "' " << (result ? "found" : "NOT found"));
48 
49  return (result != nullptr);
50 
51 }
52 
56 template<class MatchType>
57 int
58 check_cert_domain( void *check_data, ASN1_STRING *cn_data)
59 {
60  char cn[1024];
61  ACLData<MatchType> * data = (ACLData<MatchType> *)check_data;
62 
63  if (cn_data->length > (int)sizeof(cn) - 1)
64  return 1; // ignore data that does not fit our buffer
65 
66  char *s = reinterpret_cast<char *>(cn_data->data);
67  char *d = cn;
68  for (int i = 0; i < cn_data->length; ++i, ++d, ++s) {
69  if (*s == '\0')
70  return 1; // always a domain mismatch. contains 0x00
71  *d = *s;
72  }
73  cn[cn_data->length] = '\0';
74  debugs(28, 4, "Verifying certificate name/subjectAltName " << cn);
75  if (data->match(cn))
76  return 0;
77  return 1;
78 }
79 
80 int
82 {
83  assert(checklist != nullptr && checklist->request != nullptr);
84 
85  const char *serverName = nullptr;
86  SBuf clientSniKeeper; // because c_str() is not constant
87  if (ConnStateData *conn = checklist->conn()) {
88  const char *clientRequestedServerName = nullptr;
89  clientSniKeeper = conn->tlsClientSni();
90  if (clientSniKeeper.isEmpty()) {
91  const char *host = checklist->request->url.host();
92  if (host && *host) // paranoid first condition: host() is never nil
93  clientRequestedServerName = host;
94  } else
95  clientRequestedServerName = clientSniKeeper.c_str();
96 
97  if (useConsensus) {
98  X509 *peer_cert = conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr;
99  // use the client requested name if it matches the server
100  // certificate or if the certificate is not available
101  if (!peer_cert || Ssl::checkX509ServerValidity(peer_cert, clientRequestedServerName))
102  serverName = clientRequestedServerName;
103  } else if (useClientRequested)
104  serverName = clientRequestedServerName;
105  else { // either no options or useServerProvided
106  if (X509 *peer_cert = (conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr))
107  return Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain<MatchType>);
108  if (!useServerProvided)
109  serverName = clientRequestedServerName;
110  }
111  }
112 
113  if (!serverName)
114  serverName = "none";
115 
116  return data->match(serverName);
117 }
118 
119 const Acl::Options &
121 {
122  static const Acl::BooleanOption ClientRequested("--client-requested");
123  static const Acl::BooleanOption ServerProvided("--server-provided");
124  static const Acl::BooleanOption Consensus("--consensus");
125  static const Acl::Options MyOptions = { &ClientRequested, &ServerProvided, &Consensus };
126  ClientRequested.linkWith(&useClientRequested);
127  ServerProvided.linkWith(&useServerProvided);
128  Consensus.linkWith(&useConsensus);
129  return MyOptions;
130 }
131 
132 bool
134 {
135  int optionCount = 0;
136 
137  if (useClientRequested)
138  optionCount++;
139  if (useServerProvided)
140  optionCount++;
141  if (useConsensus)
142  optionCount++;
143 
144  if (optionCount > 1) {
145  debugs(28, DBG_CRITICAL, "ERROR: Multiple options given for the server_name ACL");
146  return false;
147  }
148  return true;
149 }
150 
int check_cert_domain(void *check_data, ASN1_STRING *cn_data)
Definition: ServerName.cc:58
static int aclHostDomainCompare(char *const &a, char *const &b)
Definition: ServerName.cc:28
int conn
the current server connection FD
Definition: Transport.cc:26
int matchDomainName(const char *h, const char *d, MatchDomainNameFlags flags)
Definition: Uri.cc:736
@ mdnHonorWildcards
Definition: Uri.h:225
#define assert(EX)
Definition: assert.h:19
virtual bool match(M)=0
Splay< char * > * domains
Definition: DomainData.h:28
HttpRequest * request
ConnStateData * conn() const
The client connection manager.
virtual bool match(const char *)
Definition: ServerName.cc:37
Acl::BooleanOptionValue useConsensus
Ignore mismatching names.
Definition: ServerName.h:36
Acl::BooleanOptionValue useClientRequested
Ignore server-supplied names.
Definition: ServerName.h:34
Acl::BooleanOptionValue useServerProvided
Ignore client-supplied names.
Definition: ServerName.h:35
virtual int match(ACLData< MatchType > *&, ACLFilledChecklist *)
Definition: ServerName.cc:81
virtual const Acl::Options & options()
Definition: ServerName.cc:120
virtual bool valid() const
Definition: ServerName.cc:133
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
void host(const char *src)
Definition: Uri.cc:99
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
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
Definition: splay.h:285
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
#define DBG_CRITICAL
Definition: Stream.h:40
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