]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/CertificateData.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / acl / CertificateData.cc
CommitLineData
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
19ACLCertificateData::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 33ACLCertificateData::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 42template<class T>
43inline void
44xRefFree(T &thing)
45{
46 xfree (thing);
47}
48
49ACLCertificateData::~ACLCertificateData()
50{
5dee515e 51 safe_free (attribute);
3841dd46 52}
53
54template<class T>
55inline int
56splaystrcmp (T&l, T&r)
57{
58 return strcmp ((char *)l,(char *)r);
59}
60
3841dd46 61bool
00352183 62ACLCertificateData::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
75SBufList
76ACLCertificateData::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
92void
93ACLCertificateData::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 162bool
163ACLCertificateData::empty() const
164{
165 return values.empty();
166}
3841dd46 167
00352183 168ACLData<X509 *> *
3841dd46 169ACLCertificateData::clone() const
170{
171 /* Splay trees don't clone yet. */
5dee515e 172 return new ACLCertificateData(*this);
3841dd46 173}
f53969cc 174