]> git.ipfire.org Git - thirdparty/squid.git/blob - src/acl/CertificateData.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / CertificateData.cc
1 /*
2 * Copyright (C) 1996-2015 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 struct CertificateDataAclDumpVisitor {
75 SBufList contents;
76 void operator() (char * const & node_data) {
77 contents.push_back(SBuf(node_data));
78 }
79 };
80
81 SBufList
82 ACLCertificateData::dump() const
83 {
84 SBufList sl;
85 if (validAttributesStr)
86 sl.push_back(SBuf(attribute));
87
88 CertificateDataAclDumpVisitor visitor;
89 values.values->visit(visitor);
90 sl.splice(sl.end(),visitor.contents);
91 return sl;
92 }
93
94 void
95 ACLCertificateData::parse()
96 {
97 if (validAttributesStr) {
98 char *newAttribute = strtokFile();
99
100 if (!newAttribute) {
101 if (attributeIsOptional)
102 return;
103
104 debugs(28, DBG_CRITICAL, "FATAL: required attribute argument missing");
105 self_destruct();
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) {
122 debugs(28, DBG_CRITICAL, "FATAL: Unknown option. Supported option(s) are: " << validAttributesStr);
123 self_destruct();
124 }
125
126 /* an acl must use consistent attributes in all config lines */
127 if (attribute) {
128 if (strcasecmp(newAttribute, attribute) != 0) {
129 debugs(28, DBG_CRITICAL, "FATAL: An acl must use consistent attributes in all config lines (" << newAttribute << "!=" << attribute << ").");
130 self_destruct();
131 }
132 } else
133 attribute = xstrdup(newAttribute);
134 }
135 }
136
137 values.parse();
138 }
139
140 bool
141 ACLCertificateData::empty() const
142 {
143 return values.empty();
144 }
145
146 ACLData<X509 *> *
147 ACLCertificateData::clone() const
148 {
149 /* Splay trees don't clone yet. */
150 return new ACLCertificateData(*this);
151 }
152