bool push_back_unique(C const &);
bool find(C const &)const;
bool findAndTune(C const &);
+ /// iterates entire list to return the last element holder
+ CbDataList *tail();
CbDataList *next;
C element;
bool empty() const { return this == NULL; }
return true;
}
+template <class C>
+CbDataList<C> *
+CbDataList<C>::tail()
+{
+ CbDataList<C> *last;
+ for (last = this; last->next; last = last->next);
+ return last;
+}
+
+
template <class C>
bool
CbDataList<C>::find (C const &toFind) const
-e "s%[@]DEFAULT_SSL_DB_DIR[@]%$(DEFAULT_SSL_DB_DIR)%g" \
-e "s%[@]DEFAULT_ICON_DIR[@]%$(DEFAULT_ICON_DIR)%g" \
-e "s%[@]DEFAULT_CONFIG_DIR[@]%$(DEFAULT_CONFIG_DIR)%g" \
+ -e "s%[@]DEFAULT_ERROR_DIR[@]%$(DEFAULT_ERROR_DIR)%g" \
-e "s%[@]DEFAULT_PREFIX[@]%$(DEFAULT_PREFIX)%g" \
-e "s%[@]DEFAULT_HOSTS[@]%$(DEFAULT_HOSTS)%g" \
-e "s%[@]SQUID[@]%SQUID\ $(VERSION)%g" \
for (Tail = &values; *Tail; Tail = &((*Tail)->next));
while ((t = strtokFile())) {
- Ssl::Errors *q = new Ssl::Errors(Ssl::ParseErrorString(t));
+ Ssl::Errors *q = Ssl::ParseErrorString(t);
*(Tail) = q;
- Tail = &q->next;
+ Tail = &q->tail()->next;
}
}
NAME: acl
TYPE: acl
LOC: Config.aclList
+IFDEF USE_SSL
+DEFAULT: ssl::certHasExpired ssl_error X509_V_ERR_CERT_HAS_EXPIRED
+DEFAULT: ssl::certNotYetValid ssl_error X509_V_ERR_CERT_NOT_YET_VALID
+DEFAULT: ssl::certDomainMismatch ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH
+DEFAULT: ssl::certUntrusted ssl_error X509_V_ERR_INVALID_CA X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY X509_V_ERR_CERT_UNTRUSTED
+DEFAULT: ssl::certSelfSigned ssl_error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
+ENDIF
DEFAULT: all src all
DEFAULT: manager url_regex -i ^cache_object:// +i ^https?://[^/]+/squid-internal-mgr/
DEFAULT: localhost src 127.0.0.1/32 ::1
# effect in rules that affect the reply data stream such as
# http_reply_access.
+IFDEF USE_SSL
+ acl aclname ssl_error errorname
+ # match against SSL certificate validation error [fast]
+ # For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt template file
+ # The user aditionaly can use as error name the following error name
+ # shortcuts:
+ # [ssl::]certHasExpired: certificate "not after" field is in the past
+ # [ssl::]certNotYetValid: certificate "not before" field is in the
+ # future
+ # [ssl::]certDomainMismatch: The certificate CN domain does not match
+ # connecting host name
+ # [ssl::]certUntrusted: The certificate is untrusted because of an
+ # error says that the certificate issuer is not trusted.
+ # [ssl::]certSelfSigned: The certificate is self signed
+ #
+ # The ssl::certHasExpired, ssl::certNotYetValid ssl::certDomainMismatch,
+ # ssl::certUntrusted and ssl::certSelfSigned also exists as predefined
+ # acl lists.
+ #
+ # NOTE: The ssl_error acl has effect only when used with
+ # sslproxy_cert_error, sslproxy_cert_sign and sslproxy_cert_adapt
+ # access lists.
+ENDIF
+
Examples:
acl macaddress arp 09:00:2b:23:45:67
acl myexample dst_as 1241
generate a X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT error in the
browser.
- When the acl(s) match, the corresponding signing algorithm is used to
- generate the certificate. Otherwise, the default signing algorithm used
+ This clause only supports fast acl types.
+
+ When the acl(s) match, the corresponding signing algorithm is used to
+ generate the certificate. Otherwise, the default signing algorithm used
+
+ BUG: The SQUID_X509_V_ERR_DOMAIN_MISMATCH and ssl:certDomainMismatch ssl
+ errors can not be used with ssl_error acl type.
DOC_END
NAME: sslproxy_cert_adapt
without an explicit parameter for intercepted or tproxied SSL
transactions.
+ This clause only supports fast acl types.
+
When the acl(s) match, the corresponding adaptation algorithm is
applied to the fake/generated certificate. Otherwise, the
default mimicking action takes place.
+
+ BUG: The SQUID_X509_V_ERR_DOMAIN_MISMATCH and ssl:certDomainMismatch ssl
+ errors can not be used with ssl_error acl type
DOC_END
NAME: sslpassword_program
#include <fstream>
#include <iostream>
#include <list>
+#include <stack>
#include "cf_gen_defines.cci"
static void gen_free(const EntryList &, std::ostream&);
static void gen_conf(const EntryList &, std::ostream&, bool verbose_output);
static void gen_default_if_none(const EntryList &, std::ostream&);
+static bool isDefined(const std::string &name);
static void
checkDepend(const std::string &directive, const char *name, const TypeList &types, const EntryList &entries)
char *ptr = NULL;
char buff[MAX_LINE];
std::ifstream fp;
+ std::stack<std::string> IFDEFS;
if (argc != 3)
usage(argv[0]);
if ((t = strchr(buff, '\n')))
*t = '\0';
+ if(strncmp(buff, "IFDEF ", 6) == 0) {
+ if ((ptr = strtok(buff + 6, WS)) == NULL) {
+ std::cerr << "Missing IFDEF parameter on line" << linenum << std::endl;
+ exit(1);
+ }
+ IFDEFS.push(ptr);
+ std::cerr << "Entering IFDEF " << ptr << std::endl;
+ continue;
+ } else if (strcmp(buff, "ENDIF") == 0) {
+ if (IFDEFS.size() == 0) {
+ std::cerr << "ENDIF without IFDEF before on line " << linenum << std::endl;
+ exit(1);
+ }
+ IFDEFS.pop();
+ }
+ else if (!IFDEFS.size() || isDefined(IFDEFS.top()))
switch (state) {
case sSTART:
{SSL_ERROR_NONE, NULL}
};
+struct SslErrorAlias {
+ const char *name;
+ const Ssl::ssl_error_t *errors;
+};
+
+static const Ssl::ssl_error_t hasExpired[] = {X509_V_ERR_CERT_HAS_EXPIRED, SSL_ERROR_NONE};
+static const Ssl::ssl_error_t notYetValid[] = {X509_V_ERR_CERT_NOT_YET_VALID, SSL_ERROR_NONE};
+static const Ssl::ssl_error_t domainMismatch[] = {SQUID_X509_V_ERR_DOMAIN_MISMATCH, SSL_ERROR_NONE};
+static const Ssl::ssl_error_t certUntrusted[] = {X509_V_ERR_INVALID_CA,
+ X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN,
+ X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE,
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
+ X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY,
+ X509_V_ERR_CERT_UNTRUSTED, SSL_ERROR_NONE};
+static const Ssl::ssl_error_t certSelfSigned[] = {X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, SSL_ERROR_NONE};
+
+// The list of error name shortcuts for use with ssl_error acls.
+// The keys without the "ssl::" scope prefix allow shorter error
+// names within the SSL options scope. This is easier than
+// carefully stripping the scope prefix in Ssl::ParseErrorString()
+static SslErrorAlias TheSslErrorShortcutsArray[] = {
+ {"ssl::certHasExpired", hasExpired},
+ {"certHasExpired", hasExpired},
+ {"ssl::certNotYetValid", notYetValid},
+ {"certNotYetValid", notYetValid},
+ {"ssl::certDomainMismatch", domainMismatch},
+ {"certDomainMismatch", domainMismatch},
+ {"ssl::certUntrusted", certUntrusted},
+ {"certUntrusted", certUntrusted},
+ {"ssl::certSelfSigned", certSelfSigned},
+ {"certSelfSigned", certSelfSigned},
+ {NULL, NULL}
+};
+
+//Use std::map to optimize search
+typedef std::map<std::string, const Ssl::ssl_error_t *> SslErrorShortcuts;
+SslErrorShortcuts TheSslErrorShortcuts;
+
static void loadSslErrorMap()
{
assert(TheSslErrors.empty());
}
}
+static void loadSslErrorShortcutsMap()
+{
+ assert(TheSslErrorShortcuts.empty());
+ for (int i = 0; TheSslErrorShortcutsArray[i].name; i++)
+ TheSslErrorShortcuts[TheSslErrorShortcutsArray[i].name] = TheSslErrorShortcutsArray[i].errors;
+}
+
Ssl::ssl_error_t Ssl::GetErrorCode(const char *name)
{
for (int i = 0; TheSslErrorArray[i].name != NULL; i++) {
return SSL_ERROR_NONE;
}
-Ssl::ssl_error_t
+Ssl::Errors *
Ssl::ParseErrorString(const char *name)
{
assert(name);
const Ssl::ssl_error_t ssl_error = GetErrorCode(name);
if (ssl_error != SSL_ERROR_NONE)
- return ssl_error;
+ return new Ssl::Errors(ssl_error);
if (xisdigit(*name)) {
const long int value = strtol(name, NULL, 0);
if (SQUID_SSL_ERROR_MIN <= value && value <= SQUID_SSL_ERROR_MAX)
- return value;
+ return new Ssl::Errors(value);
fatalf("Too small or too bug SSL error code '%s'", name);
}
+ if (TheSslErrorShortcuts.empty())
+ loadSslErrorShortcutsMap();
+
+ const SslErrorShortcuts::const_iterator it = TheSslErrorShortcuts.find(name);
+ if (it != TheSslErrorShortcuts.end()) {
+ // Should not be empty...
+ assert(it->second[0] != SSL_ERROR_NONE);
+ Ssl::Errors *errors = new Ssl::Errors(it->second[0]);
+ for (int i =1; it->second[i] != SSL_ERROR_NONE; i++) {
+ errors->push_back_unique(it->second[i]);
+ }
+ return errors;
+ }
+
fatalf("Unknown SSL error name '%s'", name);
- return SSL_ERROR_SSL; // not reached
+ return NULL; // not reached
}
const char *Ssl::GetErrorName(Ssl::ssl_error_t value)
{
/**
\ingroup ServerProtocolSSLAPI
- * The ssl_error_t representation of the error described by "name".
+ * The Ssl::Errors representation of the error described by "name".
+ * The result may be a single element of a list of errors, and needs to be
+ * released by the caller.
* This function also parses numeric arguments.
*/
-ssl_error_t ParseErrorString(const char *name);
+Ssl::Errors *ParseErrorString(const char *name);
/**
\ingroup ServerProtocolSSLAPI