capath(NULL),
crlfile(NULL),
dhfile(NULL),
- sslflags(NULL),
sslContextSessionId(NULL),
generateHostCertificates(false),
dynamicCertMemCacheSize(std::numeric_limits<size_t>::max()),
safe_free(capath);
safe_free(crlfile);
safe_free(dhfile);
- safe_free(sslflags);
safe_free(sslContextSessionId);
#endif
}
b->crlfile = xstrdup(crlfile);
if (dhfile)
b->dhfile = xstrdup(dhfile);
- if (sslflags)
- b->sslflags = xstrdup(sslflags);
+ b->sslflags = sslflags;
+ b->sslContextFlags = sslContextFlags;
if (sslContextSessionId)
b->sslContextSessionId = xstrdup(sslContextSessionId);
if (dhfile)
dhParams.reset(Ssl::readDHParams(dhfile));
- if (sslflags)
- sslContextFlags = Ssl::parse_flags(sslflags);
-
+ sslContextFlags = Security::ParseFlags(sslflags);
sslOptions = Security::ParseOptions(options);
staticSslContext.reset(sslCreateServerContext(*this));
#include "anyp/ProtocolVersion.h"
#include "anyp/TrafficMode.h"
#include "comm/Connection.h"
+#include "SBuf.h"
#if USE_OPENSSL
#include "ssl/gadgets.h"
char *capath;
char *crlfile;
char *dhfile;
- char *sslflags;
+ SBuf sslflags;
char *sslContextSessionId; ///< "session id context" for staticSslContext
bool generateHostCertificates; ///< dynamically make host cert for sslBump
size_t dynamicCertMemCacheSize; ///< max size of generated certificates memory cache
safe_free(s->dhfile);
s->dhfile = xstrdup(token + 9);
} else if (strncmp(token, "sslflags=", 9) == 0) {
- safe_free(s->sslflags);
- s->sslflags = xstrdup(token + 9);
+ s->sslflags = SBuf(token + 9);
} else if (strncmp(token, "sslcontext=", 11) == 0) {
safe_free(s->sslContextSessionId);
s->sslContextSessionId = xstrdup(token + 11);
if (s->dhfile)
storeAppendPrintf(e, " dhparams=%s", s->dhfile);
- if (s->sslflags)
- storeAppendPrintf(e, " sslflags=%s", s->sslflags);
+ if (!s->sslflags.isEmpty())
+ storeAppendPrintf(e, " sslflags=" SQUIDSBUFPH, SQUIDSBUFPRINT(s->sslflags));
if (s->sslContextSessionId)
storeAppendPrintf(e, " sslcontext=%s", s->sslContextSessionId);
#include "fatal.h"
#include "globals.h"
#include "Parsing.h"
+#include "parser/Tokenizer.h"
#include "security/PeerOptions.h"
#if USE_OPENSSL
} else if (strncmp(token, "crlfile=", 8) == 0) {
crlFile = SBuf(token + 8);
} else if (strncmp(token, "flags=", 6) == 0) {
+ if (parsedFlags != 0) {
+ debugs(0, DBG_PARSE_NOTE(1), "WARNING: Overwriting flags=" << sslFlags << " with " << SBuf(token + 6));
+ }
sslFlags = SBuf(token + 6);
+ parsedFlags = Security::ParseFlags(sslFlags);
} else if (strncmp(token, "domain=", 7) == 0) {
sslDomain = SBuf(token + 7);
}
#if USE_OPENSSL
// XXX: temporary performance regression. c_str() data copies and prevents this being a const method
t = sslCreateClientContext(certFile.c_str(), privateKeyFile.c_str(), sslVersion, sslCipher.c_str(),
- (setOptions ? parsedOptions : 0), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+ (setOptions ? parsedOptions : 0), parsedFlags, caFile.c_str(), caDir.c_str(), crlFile.c_str());
#endif
return op;
}
+long
+Security::ParseFlags(const SBuf &flags)
+{
+ if (flags.isEmpty())
+ return 0;
+
+ static struct {
+ SBuf label;
+ long mask;
+ } flagTokens[] = {
+ { SBuf("NO_DEFAULT_CA"), SSL_FLAG_NO_DEFAULT_CA },
+ { SBuf("DELAYED_AUTH"), SSL_FLAG_DELAYED_AUTH },
+ { SBuf("DONT_VERIFY_PEER"), SSL_FLAG_DONT_VERIFY_PEER },
+ { SBuf("DONT_VERIFY_DOMAIN"), SSL_FLAG_DONT_VERIFY_DOMAIN },
+ { SBuf("NO_SESSION_REUSE"), SSL_FLAG_NO_SESSION_REUSE },
+#if X509_V_FLAG_CRL_CHECK
+ { SBuf("VERIFY_CRL"), SSL_FLAG_VERIFY_CRL },
+ { SBuf("VERIFY_CRL_ALL"), SSL_FLAG_VERIFY_CRL_ALL },
+#endif
+ { SBuf(), 0 }
+ };
+
+ ::Parser::Tokenizer tok(flags);
+ static const CharacterSet delims("Flag-delimiter", ":,");
+
+ long fl = 0;
+ do {
+ long found = 0;
+ for (size_t i = 0; flagTokens[i].mask; ++i) {
+ if (tok.skip(flagTokens[i].label) == 0) {
+ found = flagTokens[i].mask;
+ break;
+ }
+ }
+ if (!found)
+ fatalf("Unknown SSL flag '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining()));
+ fl |= found;
+ } while (tok.skipOne(delims));
+
+ return fl;
+}
+
void
parse_securePeerOptions(Security::PeerOptions *opt)
{
SBuf crlFile; ///< path of file containing Certificate Revoke List
SBuf sslCipher;
- SBuf sslFlags;
+ SBuf sslFlags; ///< flags defining what TLS operations Squid performs
SBuf sslDomain;
long parsedOptions; ///< parsed value of sslOptions
+ long parsedFlags; ///< parsed value of sslFlags
int sslVersion;
*/
long ParseOptions(const char *options);
+/**
+ * Parses the TLS flags squid.conf parameter
+ */
+long ParseFlags(const SBuf &);
+
} // namespace Security
// parse the tls_outgoing_options directive
#include "security/Context.h"
+/* flags a SSL connection can be configured with */
+#define SSL_FLAG_NO_DEFAULT_CA (1<<0)
+#define SSL_FLAG_DELAYED_AUTH (1<<1)
+#define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
+#define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
+#define SSL_FLAG_NO_SESSION_REUSE (1<<4)
+#define SSL_FLAG_VERIFY_CRL (1<<5)
+#define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
+
/// Network/connection security abstraction layer
namespace Security
{
return ok;
}
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_NO_DEFAULT_CA (1<<0)
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_DELAYED_AUTH (1<<1)
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_NO_SESSION_REUSE (1<<4)
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_VERIFY_CRL (1<<5)
-/// \ingroup ServerProtocolSSLInternal
-#define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
-
-/// \ingroup ServerProtocolSSLInternal
-long
-Ssl::parse_flags(const char *flags)
-{
- long fl = 0;
- char *tmp;
- char *flag;
-
- if (!flags)
- return 0;
-
- tmp = xstrdup(flags);
-
- flag = strtok(tmp, ":,");
-
- while (flag) {
- if (strcmp(flag, "NO_DEFAULT_CA") == 0)
- fl |= SSL_FLAG_NO_DEFAULT_CA;
- else if (strcmp(flag, "DELAYED_AUTH") == 0)
- fl |= SSL_FLAG_DELAYED_AUTH;
- else if (strcmp(flag, "DONT_VERIFY_PEER") == 0)
- fl |= SSL_FLAG_DONT_VERIFY_PEER;
- else if (strcmp(flag, "DONT_VERIFY_DOMAIN") == 0)
- fl |= SSL_FLAG_DONT_VERIFY_DOMAIN;
- else if (strcmp(flag, "NO_SESSION_REUSE") == 0)
- fl |= SSL_FLAG_NO_SESSION_REUSE;
-
-#if X509_V_FLAG_CRL_CHECK
-
- else if (strcmp(flag, "VERIFY_CRL") == 0)
- fl |= SSL_FLAG_VERIFY_CRL;
- else if (strcmp(flag, "VERIFY_CRL_ALL") == 0)
- fl |= SSL_FLAG_VERIFY_CRL_ALL;
-
-#endif
-
- else
- fatalf("Unknown ssl flag '%s'", flag);
-
- flag = strtok(NULL, ":,");
- }
-
- safe_free(tmp);
- return fl;
-}
-
// "dup" function for SSL_get_ex_new_index("cert_err_check")
static int
ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
}
SSL_CTX *
-sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
+sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, long fl, const char *CAfile, const char *CApath, const char *CRLfile)
{
int ssl_error;
Ssl::ContextMethod method;
SSL_CTX * sslContext;
- long fl = Ssl::parse_flags(flags);
ssl_initialize();
SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port);
/// \ingroup ServerProtocolSSLAPI
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, long flags, const char *CAfile, const char *CApath, const char *CRLfile);
/// \ingroup ServerProtocolSSLAPI
int ssl_read_method(int, char *, int);
Security::ContextPointer Security::PeerOptions::createClientContext(bool) STUB_RETVAL(NULL)
void parse_securePeerOptions(Security::PeerOptions *) STUB
long Security::ParseOptions(const char *) STUB_RETVAL(0)
+long Security::ParseFlags(const SBuf &) STUB_RETVAL(0)