]>
Commit | Line | Data |
---|---|---|
3841dd46 | 1 | /* |
bbc27441 | 2 | * Copyright (C) 1996-2014 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" |
602d9612 | 15 | #include "Debug.h" |
836007fe | 16 | #include "wordlist.h" |
3841dd46 | 17 | |
00352183 AR |
18 | ACLCertificateData::ACLCertificateData(Ssl::GETX509ATTRIBUTE *sslStrategy, const char *attrs, bool optionalAttr) : validAttributesStr(attrs), attributeIsOptional(optionalAttr), attribute (NULL), values (), sslAttributeCall (sslStrategy) |
19 | { | |
20 | if (attrs) { | |
c9b5fbaf CT |
21 | size_t current = 0; |
22 | size_t next = std::string::npos; | |
00352183 AR |
23 | std::string valid(attrs); |
24 | do { | |
00352183 | 25 | next = valid.find_first_of( "|", current); |
c9b5fbaf CT |
26 | validAttributes.push_back(valid.substr( current, (next == std::string::npos ? std::string::npos : next - current))); |
27 | current = next + 1; | |
00352183 AR |
28 | } while (next != std::string::npos); |
29 | } | |
30 | } | |
3841dd46 | 31 | |
48071869 | 32 | ACLCertificateData::ACLCertificateData(ACLCertificateData const &old) : attribute (NULL), values (old.values), sslAttributeCall (old.sslAttributeCall) |
5dee515e | 33 | { |
00352183 AR |
34 | validAttributesStr = old.validAttributesStr; |
35 | validAttributes.assign (old.validAttributes.begin(), old.validAttributes.end()); | |
36 | attributeIsOptional = old.attributeIsOptional; | |
5dee515e | 37 | if (old.attribute) |
86c63190 | 38 | attribute = xstrdup(old.attribute); |
5dee515e | 39 | } |
40 | ||
3841dd46 | 41 | template<class T> |
42 | inline void | |
43 | xRefFree(T &thing) | |
44 | { | |
45 | xfree (thing); | |
46 | } | |
47 | ||
48 | ACLCertificateData::~ACLCertificateData() | |
49 | { | |
5dee515e | 50 | safe_free (attribute); |
3841dd46 | 51 | } |
52 | ||
53 | template<class T> | |
54 | inline int | |
55 | splaystrcmp (T&l, T&r) | |
56 | { | |
57 | return strcmp ((char *)l,(char *)r); | |
58 | } | |
59 | ||
3841dd46 | 60 | bool |
00352183 | 61 | ACLCertificateData::match(X509 *cert) |
3841dd46 | 62 | { |
00352183 | 63 | if (!cert) |
62e76326 | 64 | return 0; |
65 | ||
00352183 | 66 | char const *value = sslAttributeCall(cert, attribute); |
72b12f9e | 67 | debugs(28, 6, (attribute ? attribute : "value") << "=" << value); |
5dee515e | 68 | if (value == NULL) |
62e76326 | 69 | return 0; |
70 | ||
48071869 | 71 | return values.match(value); |
3841dd46 | 72 | } |
73 | ||
c2044052 FC |
74 | struct CertificateDataAclDumpVisitor { |
75 | SBufList contents; | |
76 | void operator() (char * const & node_data) { | |
77 | contents.push_back(SBuf(node_data)); | |
78 | } | |
79 | }; | |
3841dd46 | 80 | |
2cb8d372 FC |
81 | SBufList |
82 | ACLCertificateData::dump() const | |
3841dd46 | 83 | { |
2cb8d372 | 84 | SBufList sl; |
00352183 | 85 | if (validAttributesStr) |
2cb8d372 | 86 | sl.push_back(SBuf(attribute)); |
c2044052 FC |
87 | |
88 | CertificateDataAclDumpVisitor visitor; | |
89 | values.values->visit(visitor); | |
90 | sl.splice(sl.end(),visitor.contents); | |
2cb8d372 | 91 | return sl; |
3841dd46 | 92 | } |
93 | ||
94 | void | |
95 | ACLCertificateData::parse() | |
96 | { | |
00352183 AR |
97 | if (validAttributesStr) { |
98 | char *newAttribute = strtokFile(); | |
62e76326 | 99 | |
00352183 AR |
100 | if (!newAttribute) { |
101 | if (attributeIsOptional) | |
102 | return; | |
62e76326 | 103 | |
72b12f9e | 104 | debugs(28, DBG_CRITICAL, "FATAL: required attribute argument missing"); |
62e76326 | 105 | self_destruct(); |
00352183 AR |
106 | } |
107 | ||
108 | // Handle the cases where we have optional -x type attributes | |
109 | if (attributeIsOptional && newAttribute[0] != '-') | |
110 | // The read token is not an attribute/option, so add it to values list | |
111 | values.insert(newAttribute); | |
112 | else { | |
113 | bool valid = false; | |
114 | for (std::list<std::string>::const_iterator it = validAttributes.begin(); it != validAttributes.end(); ++it) { | |
115 | if (*it == "*" || *it == newAttribute) { | |
116 | valid = true; | |
117 | break; | |
118 | } | |
119 | } | |
120 | ||
121 | if (!valid) { | |
72b12f9e | 122 | debugs(28, DBG_CRITICAL, "FATAL: Unknown option. Supported option(s) are: " << validAttributesStr); |
00352183 AR |
123 | self_destruct(); |
124 | } | |
960e100b | 125 | |
00352183 AR |
126 | /* an acl must use consistent attributes in all config lines */ |
127 | if (attribute) { | |
128 | if (strcasecmp(newAttribute, attribute) != 0) { | |
72b12f9e | 129 | debugs(28, DBG_CRITICAL, "FATAL: An acl must use consistent attributes in all config lines (" << newAttribute << "!=" << attribute << ")."); |
00352183 AR |
130 | self_destruct(); |
131 | } | |
132 | } else | |
133 | attribute = xstrdup(newAttribute); | |
134 | } | |
135 | } | |
62e76326 | 136 | |
48071869 | 137 | values.parse(); |
3841dd46 | 138 | } |
139 | ||
65092baf | 140 | bool |
141 | ACLCertificateData::empty() const | |
142 | { | |
143 | return values.empty(); | |
144 | } | |
3841dd46 | 145 | |
00352183 | 146 | ACLData<X509 *> * |
3841dd46 | 147 | ACLCertificateData::clone() const |
148 | { | |
149 | /* Splay trees don't clone yet. */ | |
5dee515e | 150 | return new ACLCertificateData(*this); |
3841dd46 | 151 | } |
f53969cc | 152 |