]>
Commit | Line | Data |
---|---|---|
69f69080 | 1 | /* |
ef57eb7b | 2 | * Copyright (C) 1996-2016 The Squid Software Foundation and contributors |
69f69080 CT |
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/Checklist.h" | |
69f69080 CT |
13 | #include "acl/DomainData.h" |
14 | #include "acl/RegexData.h" | |
8823b1c9 | 15 | #include "acl/ServerName.h" |
69f69080 CT |
16 | #include "client_side.h" |
17 | #include "fde.h" | |
d3dddfb5 | 18 | #include "http/Stream.h" |
69f69080 CT |
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 | #include "URL.h" | |
26 | ||
27 | // Compare function for tree search algorithms | |
28 | static int | |
29 | aclHostDomainCompare( char *const &a, char * const &b) | |
30 | { | |
31 | const char *h = static_cast<const char *>(a); | |
32 | const char *d = static_cast<const char *>(b); | |
33 | debugs(28, 7, "Match:" << h << " <> " << d); | |
abbd7825 | 34 | return matchDomainName(h, d, mdnHonorWildcards); |
69f69080 CT |
35 | } |
36 | ||
37 | bool | |
38 | ACLServerNameData::match(const char *host) | |
39 | { | |
40 | if (host == NULL) | |
41 | return 0; | |
42 | ||
43 | debugs(28, 3, "checking '" << host << "'"); | |
44 | ||
45 | char *h = const_cast<char *>(host); | |
46 | char const * const * result = domains->find(h, aclHostDomainCompare); | |
47 | ||
48 | debugs(28, 3, "'" << host << "' " << (result ? "found" : "NOT found")); | |
49 | ||
50 | return (result != NULL); | |
51 | ||
52 | } | |
53 | ||
54 | ACLData<char const *> * | |
55 | ACLServerNameData::clone() const | |
56 | { | |
57 | /* Splay trees don't clone yet. */ | |
58 | assert (!domains); | |
59 | return new ACLServerNameData; | |
60 | } | |
61 | ||
62 | /// A helper function to be used with Ssl::matchX509CommonNames(). | |
63 | /// \retval 0 when the name (cn or an alternate name) matches acl data | |
64 | /// \retval 1 when the name does not match | |
65 | template<class MatchType> | |
66 | int | |
67 | check_cert_domain( void *check_data, ASN1_STRING *cn_data) | |
68 | { | |
69 | char cn[1024]; | |
70 | ACLData<MatchType> * data = (ACLData<MatchType> *)check_data; | |
71 | ||
72 | if (cn_data->length > (int)sizeof(cn) - 1) | |
73 | return 1; // ignore data that does not fit our buffer | |
8823b1c9 | 74 | |
0f7f4cfc AJ |
75 | char *s = reinterpret_cast<char *>(cn_data->data); |
76 | char *d = cn; | |
77 | for (int i = 0; i < cn_data->length; ++i, ++d, ++s) { | |
78 | if (*s == '\0') | |
79 | return 1; // always a domain mismatch. contains 0x00 | |
80 | *d = *s; | |
81 | } | |
69f69080 CT |
82 | cn[cn_data->length] = '\0'; |
83 | debugs(28, 4, "Verifying certificate name/subjectAltName " << cn); | |
84 | if (data->match(cn)) | |
85 | return 0; | |
86 | return 1; | |
87 | } | |
88 | ||
89 | int | |
90 | ACLServerNameStrategy::match (ACLData<MatchType> * &data, ACLFilledChecklist *checklist, ACLFlags &flags) | |
91 | { | |
92 | assert(checklist != NULL && checklist->request != NULL); | |
93 | ||
94 | if (checklist->conn() && checklist->conn()->serverBump()) { | |
95 | if (X509 *peer_cert = checklist->conn()->serverBump()->serverCert.get()) { | |
96 | if (Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain<MatchType>)) | |
97 | return 1; | |
98 | } | |
99 | } | |
100 | ||
101 | const char *serverName = NULL; | |
102 | if (checklist->conn() && !checklist->conn()->sslCommonName().isEmpty()) { | |
103 | SBuf scn = checklist->conn()->sslCommonName(); | |
104 | serverName = scn.c_str(); | |
105 | } | |
106 | ||
107 | if (serverName == NULL) | |
5c51bffb | 108 | serverName = checklist->request->url.host(); |
69f69080 CT |
109 | |
110 | if (serverName && data->match(serverName)) { | |
111 | return 1; | |
112 | } | |
113 | ||
114 | return data->match("none"); | |
115 | } | |
116 | ||
117 | ACLServerNameStrategy * | |
118 | ACLServerNameStrategy::Instance() | |
119 | { | |
120 | return &Instance_; | |
121 | } | |
122 | ||
123 | ACLServerNameStrategy ACLServerNameStrategy::Instance_; | |
124 |