CertificateData.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2025 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 "ConfigParser.h"
16 #include "debug/Stream.h"
17 #include "wordlist.h"
18 
19 ACLCertificateData::ACLCertificateData(Ssl::GETX509ATTRIBUTE * const sslStrategy, const char * const attrs, const bool optionalAttr):
20  validAttributesStr(attrs),
21  attributeIsOptional(optionalAttr),
22  sslAttributeCall(sslStrategy)
23 {
24  if (attrs) {
25  size_t current = 0;
26  size_t next = std::string::npos;
27  std::string valid(attrs);
28  do {
29  next = valid.find_first_of( "|", current);
30  validAttributes.push_back(valid.substr( current, (next == std::string::npos ? std::string::npos : next - current)));
31  current = next + 1;
32  } while (next != std::string::npos);
33  }
34 }
35 
36 template<class T>
37 inline void
38 xRefFree(T &thing)
39 {
40  xfree (thing);
41 }
42 
43 template<class T>
44 inline int
45 splaystrcmp (T&l, T&r)
46 {
47  return strcmp ((char *)l,(char *)r);
48 }
49 
50 bool
52 {
53  if (!cert)
54  return 0;
55 
56  const auto value = sslAttributeCall(cert, attribute.c_str());
57  debugs(28, 6, (attribute.isEmpty() ? attribute.c_str() : "value") << "=" << value);
58  if (value == nullptr)
59  return 0;
60 
61  return values.match(value);
62 }
63 
66 {
67  SBufList sl;
69  sl.push_back(attribute);
70 
71  sl.splice(sl.end(),values.dump());
72  return sl;
73 }
74 
75 void
77 {
78  if (validAttributesStr) {
79  char *newAttribute = ConfigParser::strtokFile();
80 
81  if (!newAttribute) {
82  if (!attributeIsOptional) {
83  debugs(28, DBG_CRITICAL, "FATAL: required attribute argument missing");
84  self_destruct();
85  }
86  return;
87  }
88 
89  // Handle the cases where we have optional -x type attributes
90  if (attributeIsOptional && newAttribute[0] != '-')
91  // The read token is not an attribute/option, so add it to values list
92  values.insert(newAttribute);
93  else {
94  bool valid = false;
95  for (std::list<std::string>::const_iterator it = validAttributes.begin(); it != validAttributes.end(); ++it) {
96  if (*it == "*" || *it == newAttribute) {
97  valid = true;
98  break;
99  }
100  }
101 
102  if (!valid) {
103  debugs(28, DBG_CRITICAL, "FATAL: Unknown option. Supported option(s) are: " << validAttributesStr);
104  self_destruct();
105  return;
106  }
107 
108  // If attribute has been set already, then we do not need to call OBJ_create()
109  // below because either we did that for the same attribute when we set it, or
110  // Acl::SetKey() below will reject this new/different attribute spelling.
111  if (attribute.isEmpty()) {
112  if (strcasecmp(newAttribute, "DN") != 0) {
113  int nid = OBJ_txt2nid(newAttribute);
114  if (nid == 0) {
115  const size_t span = strspn(newAttribute, "0123456789.");
116  if(newAttribute[span] == '\0') { // looks like a numerical OID
117  // create a new object based on this attribute
118 
119  // NOTE: Not a [bad] leak: If the same attribute
120  // has been added before, the OBJ_txt2nid call
121  // would return a valid nid value.
122  // TODO: call OBJ_cleanup() on reconfigure?
123  nid = OBJ_create(newAttribute, newAttribute, newAttribute);
124  debugs(28, 7, "New SSL certificate attribute created with name: " << newAttribute << " and nid: " << nid);
125  }
126  }
127  if (nid == 0) {
128  debugs(28, DBG_CRITICAL, "FATAL: Not valid SSL certificate attribute name or numerical OID: " << newAttribute);
129  self_destruct();
130  return;
131  }
132  }
133  }
134 
135  Acl::SetKey(attribute, "SSL certificate attribute", newAttribute);
136  }
137  }
138 
139  values.parse();
140 }
141 
142 bool
144 {
145  return values.empty();
146 }
147 
#define DBG_CRITICAL
Definition: Stream.h:37
void parse() override
static char * strtokFile()
Definition: ConfigParser.cc:65
int splaystrcmp(T &l, T &r)
bool isEmpty() const
Definition: SBuf.h:435
void xRefFree(T &thing)
std::list< SBuf > SBufList
Definition: forward.h:22
bool match(X509 *) override
void SetKey(SBuf &keyStorage, const char *keyParameterName, const char *newKey)
Definition: Acl.cc:100
bool empty() const override
bool attributeIsOptional
True if the attribute is optional (-xxx options)
void self_destruct(void)
Definition: cache_cf.cc:276
Ssl::GETX509ATTRIBUTE * sslAttributeCall
The callback used to retrieve the data from X509 cert.
ACLCertificateData(Ssl::GETX509ATTRIBUTE *, const char *attributes, bool optionalAttr=false)
bool match(char const *) override
Definition: StringData.cc:39
void parse() override
Definition: StringData.cc:58
std::list< std::string > validAttributes
Parsed list of valid attribute names.
SBufList dump() const override
SBufList dump() const override
Definition: StringData.cc:50
const char * c_str()
Definition: SBuf.cc:516
#define xfree
const char * GETX509ATTRIBUTE(X509 *, const char *)
Definition: support.h:111
const char * validAttributesStr
void insert(const char *)
Insert a string data value.
Definition: StringData.cc:18
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
ACLStringData values
bool empty() const override
Definition: StringData.cc:65

 

Introduction

Documentation

Support

Miscellaneous