ServerName.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 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 == NULL)
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 != NULL);
50 
51 }
52 
55 {
56  /* Splay trees don't clone yet. */
57  assert (!domains);
58  return new ACLServerNameData;
59 }
60 
64 template<class MatchType>
65 int
66 check_cert_domain( void *check_data, ASN1_STRING *cn_data)
67 {
68  char cn[1024];
69  ACLData<MatchType> * data = (ACLData<MatchType> *)check_data;
70 
71  if (cn_data->length > (int)sizeof(cn) - 1)
72  return 1; // ignore data that does not fit our buffer
73 
74  char *s = reinterpret_cast<char *>(cn_data->data);
75  char *d = cn;
76  for (int i = 0; i < cn_data->length; ++i, ++d, ++s) {
77  if (*s == '\0')
78  return 1; // always a domain mismatch. contains 0x00
79  *d = *s;
80  }
81  cn[cn_data->length] = '\0';
82  debugs(28, 4, "Verifying certificate name/subjectAltName " << cn);
83  if (data->match(cn))
84  return 0;
85  return 1;
86 }
87 
88 int
90 {
91  assert(checklist != NULL && checklist->request != NULL);
92 
93  const char *serverName = nullptr;
94  SBuf clientSniKeeper; // because c_str() is not constant
95  if (ConnStateData *conn = checklist->conn()) {
96  const char *clientRequestedServerName = nullptr;
97  clientSniKeeper = conn->tlsClientSni();
98  if (clientSniKeeper.isEmpty()) {
99  const char *host = checklist->request->url.host();
100  if (host && *host) // paranoid first condition: host() is never nil
101  clientRequestedServerName = host;
102  } else
103  clientRequestedServerName = clientSniKeeper.c_str();
104 
105  if (useConsensus) {
106  X509 *peer_cert = conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr;
107  // use the client requested name if it matches the server
108  // certificate or if the certificate is not available
109  if (!peer_cert || Ssl::checkX509ServerValidity(peer_cert, clientRequestedServerName))
110  serverName = clientRequestedServerName;
111  } else if (useClientRequested)
112  serverName = clientRequestedServerName;
113  else { // either no options or useServerProvided
114  if (X509 *peer_cert = (conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr))
115  return Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain<MatchType>);
116  if (!useServerProvided)
117  serverName = clientRequestedServerName;
118  }
119  }
120 
121  if (!serverName)
122  serverName = "none";
123 
124  return data->match(serverName);
125 }
126 
127 const Acl::Options &
129 {
130  static const Acl::BooleanOption ClientRequested;
131  static const Acl::BooleanOption ServerProvided;
132  static const Acl::BooleanOption Consensus;
133  static const Acl::Options MyOptions = {
134  {"--client-requested", &ClientRequested},
135  {"--server-provided", &ServerProvided},
136  {"--consensus", &Consensus}
137  };
138 
139  ClientRequested.linkWith(&useClientRequested);
140  ServerProvided.linkWith(&useServerProvided);
141  Consensus.linkWith(&useConsensus);
142  return MyOptions;
143 }
144 
145 bool
147 {
148  int optionCount = 0;
149 
150  if (useClientRequested)
151  optionCount++;
152  if (useServerProvided)
153  optionCount++;
154  if (useConsensus)
155  optionCount++;
156 
157  if (optionCount > 1) {
158  debugs(28, DBG_CRITICAL, "ERROR: Multiple options given for the server_name ACL");
159  return false;
160  }
161  return true;
162 }
163 
#define assert(EX)
Definition: assert.h:17
static int aclHostDomainCompare(char *const &a, char *const &b)
Definition: ServerName.cc:28
virtual bool match(M)=0
Definition: SBuf.h:86
int i
Definition: membanger.c:49
bool isEmpty() const
Definition: SBuf.h:420
virtual bool valid() const
Definition: ServerName.cc:146
#define DBG_CRITICAL
Definition: Debug.h:45
int conn
the current server connection FD
Definition: Transport.cc:26
virtual const Acl::Options & options()
Definition: ServerName.cc:128
Configured ACL parameter(s) (e.g., domain names in dstdomain ACL).
Definition: Data.h:17
int check_cert_domain(void *check_data, ASN1_STRING *cn_data)
Definition: ServerName.cc:66
void const char HLPCB void * data
Definition: stub_helper.cc:16
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
ConnStateData * conn() const
The client connection manager.
virtual bool match(const char *)
Definition: ServerName.cc:37
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
const char * c_str()
Definition: SBuf.cc:526
virtual int match(ACLData< MatchType > *&, ACLFilledChecklist *)
Definition: ServerName.cc:89
void host(const char *src)
Definition: Uri.cc:47
Value const * find(FindValue const &, int(*compare)(FindValue const &a, Value const &b)) const
Definition: splay.h:285
HttpRequest * request
bool checkX509ServerValidity(X509 *cert, const char *server)
Definition: support.cc:251
virtual ACLData< char const * > * clone() const
Definition: ServerName.cc:54
std::map< OptionName, const Option *, OptionNameCmp > Options
name:option map
Definition: Options.h:159
void linkWith(Recipient *recipient) const
who to tell when this option is enabled
Definition: Options.h:90
int a
Definition: membanger.c:50
a type-specific Option (e.g., a boolean –toggle or -m=SBuf)
Definition: Options.h:83
int matchX509CommonNames(X509 *peer_cert, void *check_data, int(*check_func)(void *check_data, ASN1_STRING *cn_data))
Definition: support.cc:192
Splay< char * > * domains
Definition: DomainData.h:29
int matchDomainName(const char *h, const char *d, uint8_t flags)
Definition: Uri.cc:693
#define NULL
Definition: types.h:166

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors