]>
Commit | Line | Data |
---|---|---|
3841dd46 | 1 | /* |
4ac4a490 | 2 | * Copyright (C) 1996-2017 The Squid Software Foundation and contributors |
3841dd46 | 3 | * |
bbc27441 AJ |
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. | |
3841dd46 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 28 Access Control */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
3ad63615 AR |
12 | #include "acl/CertificateData.h" |
13 | #include "acl/Checklist.h" | |
fc54b8d2 | 14 | #include "cache_cf.h" |
16c5ad96 | 15 | #include "ConfigParser.h" |
602d9612 | 16 | #include "Debug.h" |
836007fe | 17 | #include "wordlist.h" |
3841dd46 | 18 | |
00352183 AR |
19 | ACLCertificateData::ACLCertificateData(Ssl::GETX509ATTRIBUTE *sslStrategy, const char *attrs, bool optionalAttr) : validAttributesStr(attrs), attributeIsOptional(optionalAttr), attribute (NULL), values (), sslAttributeCall (sslStrategy) |
20 | { | |
21 | if (attrs) { | |
c9b5fbaf CT |
22 | size_t current = 0; |
23 | size_t next = std::string::npos; | |
00352183 AR |
24 | std::string valid(attrs); |
25 | do { | |
00352183 | 26 | next = valid.find_first_of( "|", current); |
c9b5fbaf CT |
27 | validAttributes.push_back(valid.substr( current, (next == std::string::npos ? std::string::npos : next - current))); |
28 | current = next + 1; | |
00352183 AR |
29 | } while (next != std::string::npos); |
30 | } | |
31 | } | |
3841dd46 | 32 | |
48071869 | 33 | ACLCertificateData::ACLCertificateData(ACLCertificateData const &old) : attribute (NULL), values (old.values), sslAttributeCall (old.sslAttributeCall) |
5dee515e | 34 | { |
00352183 AR |
35 | validAttributesStr = old.validAttributesStr; |
36 | validAttributes.assign (old.validAttributes.begin(), old.validAttributes.end()); | |
37 | attributeIsOptional = old.attributeIsOptional; | |
5dee515e | 38 | if (old.attribute) |
86c63190 | 39 | attribute = xstrdup(old.attribute); |
5dee515e | 40 | } |
41 | ||
3841dd46 | 42 | template<class T> |
43 | inline void | |
44 | xRefFree(T &thing) | |
45 | { | |
46 | xfree (thing); | |
47 | } | |
48 | ||
49 | ACLCertificateData::~ACLCertificateData() | |
50 | { | |
5dee515e | 51 | safe_free (attribute); |
3841dd46 | 52 | } |
53 | ||
54 | template<class T> | |
55 | inline int | |
56 | splaystrcmp (T&l, T&r) | |
57 | { | |
58 | return strcmp ((char *)l,(char *)r); | |
59 | } | |
60 | ||
3841dd46 | 61 | bool |
00352183 | 62 | ACLCertificateData::match(X509 *cert) |
3841dd46 | 63 | { |
00352183 | 64 | if (!cert) |
62e76326 | 65 | return 0; |
66 | ||
00352183 | 67 | char const *value = sslAttributeCall(cert, attribute); |
72b12f9e | 68 | debugs(28, 6, (attribute ? attribute : "value") << "=" << value); |
5dee515e | 69 | if (value == NULL) |
62e76326 | 70 | return 0; |
71 | ||
48071869 | 72 | return values.match(value); |
3841dd46 | 73 | } |
74 | ||
2cb8d372 FC |
75 | SBufList |
76 | ACLCertificateData::dump() const | |
3841dd46 | 77 | { |
2cb8d372 | 78 | SBufList sl; |
00352183 | 79 | if (validAttributesStr) |
2cb8d372 | 80 | sl.push_back(SBuf(attribute)); |
c2044052 | 81 | |
524f5ff6 | 82 | #if __cplusplus >= 201103L |
68acf08e | 83 | sl.splice(sl.end(),values.dump()); |
524f5ff6 AJ |
84 | #else |
85 | // temp is needed until c++11 move constructor | |
86 | SBufList tmp = values.dump(); | |
87 | sl.splice(sl.end(),tmp); | |
88 | #endif | |
2cb8d372 | 89 | return sl; |
3841dd46 | 90 | } |
91 | ||
92 | void | |
93 | ACLCertificateData::parse() | |
94 | { | |
00352183 | 95 | if (validAttributesStr) { |
16c5ad96 | 96 | char *newAttribute = ConfigParser::strtokFile(); |
62e76326 | 97 | |
00352183 | 98 | if (!newAttribute) { |
2787bc17 AJ |
99 | if (!attributeIsOptional) { |
100 | debugs(28, DBG_CRITICAL, "FATAL: required attribute argument missing"); | |
101 | self_destruct(); | |
102 | } | |
103 | return; | |
00352183 AR |
104 | } |
105 | ||
106 | // Handle the cases where we have optional -x type attributes | |
107 | if (attributeIsOptional && newAttribute[0] != '-') | |
108 | // The read token is not an attribute/option, so add it to values list | |
109 | values.insert(newAttribute); | |
110 | else { | |
111 | bool valid = false; | |
112 | for (std::list<std::string>::const_iterator it = validAttributes.begin(); it != validAttributes.end(); ++it) { | |
113 | if (*it == "*" || *it == newAttribute) { | |
114 | valid = true; | |
115 | break; | |
116 | } | |
117 | } | |
118 | ||
119 | if (!valid) { | |
72b12f9e | 120 | debugs(28, DBG_CRITICAL, "FATAL: Unknown option. Supported option(s) are: " << validAttributesStr); |
00352183 | 121 | self_destruct(); |
2787bc17 | 122 | return; |
00352183 | 123 | } |
960e100b | 124 | |
00352183 AR |
125 | /* an acl must use consistent attributes in all config lines */ |
126 | if (attribute) { | |
127 | if (strcasecmp(newAttribute, attribute) != 0) { | |
72b12f9e | 128 | debugs(28, DBG_CRITICAL, "FATAL: An acl must use consistent attributes in all config lines (" << newAttribute << "!=" << attribute << ")."); |
00352183 | 129 | self_destruct(); |
2787bc17 | 130 | return; |
00352183 | 131 | } |
2927ae41 CT |
132 | } else { |
133 | if (strcasecmp(newAttribute, "DN") != 0) { | |
134 | int nid = OBJ_txt2nid(newAttribute); | |
135 | if (nid == 0) { | |
32e29d96 SM |
136 | const size_t span = strspn(newAttribute, "0123456789."); |
137 | if(newAttribute[span] == '\0') { // looks like a numerical OID | |
138 | // create a new object based on this attribute | |
139 | ||
140 | // NOTE: Not a [bad] leak: If the same attribute | |
141 | // has been added before, the OBJ_txt2nid call | |
142 | // would return a valid nid value. | |
143 | // TODO: call OBJ_cleanup() on reconfigure? | |
144 | nid = OBJ_create(newAttribute, newAttribute, newAttribute); | |
145 | debugs(28, 7, "New SSL certificate attribute created with name: " << newAttribute << " and nid: " << nid); | |
146 | } | |
2927ae41 CT |
147 | } |
148 | if (nid == 0) { | |
149 | debugs(28, DBG_CRITICAL, "FATAL: Not valid SSL certificate attribute name or numerical OID: " << newAttribute); | |
150 | self_destruct(); | |
2787bc17 | 151 | return; |
2927ae41 CT |
152 | } |
153 | } | |
00352183 | 154 | attribute = xstrdup(newAttribute); |
2927ae41 | 155 | } |
00352183 AR |
156 | } |
157 | } | |
62e76326 | 158 | |
48071869 | 159 | values.parse(); |
3841dd46 | 160 | } |
161 | ||
65092baf | 162 | bool |
163 | ACLCertificateData::empty() const | |
164 | { | |
165 | return values.empty(); | |
166 | } | |
3841dd46 | 167 | |
00352183 | 168 | ACLData<X509 *> * |
3841dd46 | 169 | ACLCertificateData::clone() const |
170 | { | |
171 | /* Splay trees don't clone yet. */ | |
5dee515e | 172 | return new ACLCertificateData(*this); |
3841dd46 | 173 | } |
f53969cc | 174 |