]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/CertificateData.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / acl / CertificateData.cc
1 /*
2 * Copyright (C) 1996-2014 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/CertificateData.h"
13 #include "acl/Checklist.h"
14 #include "cache_cf.h"
15 #include "Debug.h"
16 #include "wordlist.h"
17
18 ACLCertificateData::ACLCertificateData(Ssl::GETX509ATTRIBUTE *sslStrategy, const char *attrs, bool optionalAttr) : validAttributesStr(attrs), attributeIsOptional(optionalAttr), attribute (NULL), values (), sslAttributeCall (sslStrategy)
19 {
20 if (attrs) {
21 size_t current = 0;
22 size_t next = std::string::npos;
23 std::string valid(attrs);
24 do {
25 next = valid.find_first_of( "|", current);
26 validAttributes.push_back(valid.substr( current, (next == std::string::npos ? std::string::npos : next - current)));
27 current = next + 1;
28 } while (next != std::string::npos);
29 }
30 }
31
32 ACLCertificateData::ACLCertificateData(ACLCertificateData const &old) : attribute (NULL), values (old.values), sslAttributeCall (old.sslAttributeCall)
33 {
34 validAttributesStr = old.validAttributesStr;
35 validAttributes.assign (old.validAttributes.begin(), old.validAttributes.end());
36 attributeIsOptional = old.attributeIsOptional;
37 if (old.attribute)
38 attribute = xstrdup(old.attribute);
39 }
40
41 template<class T>
42 inline void
43 xRefFree(T &thing)
44 {
45 xfree (thing);
46 }
47
48 ACLCertificateData::~ACLCertificateData()
49 {
50 safe_free (attribute);
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
60 bool
61 ACLCertificateData::match(X509 *cert)
62 {
63 if (!cert)
64 return 0;
65
66 char const *value = sslAttributeCall(cert, attribute);
67 debugs(28, 6, (attribute ? attribute : "value") << "=" << value);
68 if (value == NULL)
69 return 0;
70
71 return values.match(value);
72 }
73
74 static void
75 aclDumpAttributeListWalkee(char * const & node_data, void *outlist)
76 {
77 /* outlist is really a SBufList * */
78 static_cast<SBufList *>(outlist)->push_back(SBuf(node_data));
79 }
80
81 SBufList
82 ACLCertificateData::dump() const
83 {
84 SBufList sl;
85 if (validAttributesStr)
86 sl.push_back(SBuf(attribute));
87 /* damn this is VERY inefficient for long ACL lists... filling
88 * a wordlist this way costs Sum(1,N) iterations. For instance
89 * a 1000-elements list will be filled in 499500 iterations.
90 */
91 /* XXX FIXME: don't break abstraction */
92 values.values->walk(aclDumpAttributeListWalkee, &sl);
93 return sl;
94 }
95
96 void
97 ACLCertificateData::parse()
98 {
99 if (validAttributesStr) {
100 char *newAttribute = strtokFile();
101
102 if (!newAttribute) {
103 if (attributeIsOptional)
104 return;
105
106 debugs(28, DBG_CRITICAL, "FATAL: required attribute argument missing");
107 self_destruct();
108 }
109
110 // Handle the cases where we have optional -x type attributes
111 if (attributeIsOptional && newAttribute[0] != '-')
112 // The read token is not an attribute/option, so add it to values list
113 values.insert(newAttribute);
114 else {
115 bool valid = false;
116 for (std::list<std::string>::const_iterator it = validAttributes.begin(); it != validAttributes.end(); ++it) {
117 if (*it == "*" || *it == newAttribute) {
118 valid = true;
119 break;
120 }
121 }
122
123 if (!valid) {
124 debugs(28, DBG_CRITICAL, "FATAL: Unknown option. Supported option(s) are: " << validAttributesStr);
125 self_destruct();
126 }
127
128 /* an acl must use consistent attributes in all config lines */
129 if (attribute) {
130 if (strcasecmp(newAttribute, attribute) != 0) {
131 debugs(28, DBG_CRITICAL, "FATAL: An acl must use consistent attributes in all config lines (" << newAttribute << "!=" << attribute << ").");
132 self_destruct();
133 }
134 } else
135 attribute = xstrdup(newAttribute);
136 }
137 }
138
139 values.parse();
140 }
141
142 bool
143 ACLCertificateData::empty() const
144 {
145 return values.empty();
146 }
147
148 ACLData<X509 *> *
149 ACLCertificateData::clone() const
150 {
151 /* Splay trees don't clone yet. */
152 return new ACLCertificateData(*this);
153 }