]> git.ipfire.org Git - thirdparty/squid.git/blame - src/acl/CertificateData.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / acl / CertificateData.cc
CommitLineData
3841dd46 1/*
f70aedc4 2 * Copyright (C) 1996-2021 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
68acf08e 82 sl.splice(sl.end(),values.dump());
2cb8d372 83 return sl;
3841dd46 84}
85
86void
87ACLCertificateData::parse()
88{
00352183 89 if (validAttributesStr) {
16c5ad96 90 char *newAttribute = ConfigParser::strtokFile();
62e76326 91
00352183 92 if (!newAttribute) {
2787bc17
AJ
93 if (!attributeIsOptional) {
94 debugs(28, DBG_CRITICAL, "FATAL: required attribute argument missing");
95 self_destruct();
96 }
97 return;
00352183
AR
98 }
99
100 // Handle the cases where we have optional -x type attributes
101 if (attributeIsOptional && newAttribute[0] != '-')
102 // The read token is not an attribute/option, so add it to values list
103 values.insert(newAttribute);
104 else {
105 bool valid = false;
106 for (std::list<std::string>::const_iterator it = validAttributes.begin(); it != validAttributes.end(); ++it) {
107 if (*it == "*" || *it == newAttribute) {
108 valid = true;
109 break;
110 }
111 }
112
113 if (!valid) {
72b12f9e 114 debugs(28, DBG_CRITICAL, "FATAL: Unknown option. Supported option(s) are: " << validAttributesStr);
00352183 115 self_destruct();
2787bc17 116 return;
00352183 117 }
960e100b 118
00352183
AR
119 /* an acl must use consistent attributes in all config lines */
120 if (attribute) {
121 if (strcasecmp(newAttribute, attribute) != 0) {
72b12f9e 122 debugs(28, DBG_CRITICAL, "FATAL: An acl must use consistent attributes in all config lines (" << newAttribute << "!=" << attribute << ").");
00352183 123 self_destruct();
2787bc17 124 return;
00352183 125 }
2927ae41
CT
126 } else {
127 if (strcasecmp(newAttribute, "DN") != 0) {
128 int nid = OBJ_txt2nid(newAttribute);
129 if (nid == 0) {
32e29d96
SM
130 const size_t span = strspn(newAttribute, "0123456789.");
131 if(newAttribute[span] == '\0') { // looks like a numerical OID
132 // create a new object based on this attribute
133
134 // NOTE: Not a [bad] leak: If the same attribute
135 // has been added before, the OBJ_txt2nid call
136 // would return a valid nid value.
137 // TODO: call OBJ_cleanup() on reconfigure?
138 nid = OBJ_create(newAttribute, newAttribute, newAttribute);
139 debugs(28, 7, "New SSL certificate attribute created with name: " << newAttribute << " and nid: " << nid);
140 }
2927ae41
CT
141 }
142 if (nid == 0) {
143 debugs(28, DBG_CRITICAL, "FATAL: Not valid SSL certificate attribute name or numerical OID: " << newAttribute);
144 self_destruct();
2787bc17 145 return;
2927ae41
CT
146 }
147 }
00352183 148 attribute = xstrdup(newAttribute);
2927ae41 149 }
00352183
AR
150 }
151 }
62e76326 152
48071869 153 values.parse();
3841dd46 154}
155
65092baf 156bool
157ACLCertificateData::empty() const
158{
159 return values.empty();
160}
3841dd46 161
00352183 162ACLData<X509 *> *
3841dd46 163ACLCertificateData::clone() const
164{
165 /* Splay trees don't clone yet. */
5dee515e 166 return new ACLCertificateData(*this);
3841dd46 167}
f53969cc 168