#include "anyp/PortCfg.h"
#include "comm.h"
#include "fatal.h"
+#include "security/PeerOptions.h"
#if USE_OPENSSL
#include "ssl/support.h"
#endif
if (sslflags)
sslContextFlags = Ssl::parse_flags(sslflags);
- sslOptions = Ssl::parse_options(options);
+ sslOptions = Security::ParseOptions(options);
staticSslContext.reset(sslCreateServerContext(*this));
#include "squid.h"
#include "Debug.h"
+#include "fatal.h"
#include "globals.h"
#include "Parsing.h"
#include "security/PeerOptions.h"
// Pre-parse SSL client options to be applied when the client SSL objects created.
// Options must not used in the case of peek or stare bump mode.
// XXX: performance regression. c_str() can reallocate
- parsedOptions = Ssl::parse_options(sslOptions.c_str());
+ parsedOptions = Security::ParseOptions(sslOptions.c_str());
#endif
} else if (strncmp(token, "cipher=", 7) == 0) {
sslCipher = 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 ? sslOptions.c_str() : NULL), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+ (setOptions ? parsedOptions : 0), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+
#endif
return t;
}
+/// set of options we can parse and what they map to
+static struct ssl_option {
+ const char *name;
+ long value;
+
+} ssl_options[] = {
+
+#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+ {
+ "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+ },
+#endif
+#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+ {
+ "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+ },
+#endif
+#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+ {
+ "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+ },
+#endif
+#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+ {
+ "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+ },
+#endif
+#if SSL_OP_TLS_D5_BUG
+ {
+ "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
+ },
+#endif
+#if SSL_OP_TLS_BLOCK_PADDING_BUG
+ {
+ "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
+ },
+#endif
+#if SSL_OP_TLS_ROLLBACK_BUG
+ {
+ "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
+ },
+#endif
+#if SSL_OP_ALL
+ {
+ "ALL", (long)SSL_OP_ALL
+ },
+#endif
+#if SSL_OP_SINGLE_DH_USE
+ {
+ "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
+ },
+#endif
+#if SSL_OP_EPHEMERAL_RSA
+ {
+ "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
+ },
+#endif
+#if SSL_OP_PKCS1_CHECK_1
+ {
+ "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
+ },
+#endif
+#if SSL_OP_PKCS1_CHECK_2
+ {
+ "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
+ },
+#endif
+#if SSL_OP_NETSCAPE_CA_DN_BUG
+ {
+ "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
+ },
+#endif
+#if SSL_OP_NON_EXPORT_FIRST
+ {
+ "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
+ },
+#endif
+#if SSL_OP_CIPHER_SERVER_PREFERENCE
+ {
+ "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
+ },
+#endif
+#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+ {
+ "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+ },
+#endif
+#if SSL_OP_NO_SSLv3
+ {
+ "NO_SSLv3", SSL_OP_NO_SSLv3
+ },
+#endif
+#if SSL_OP_NO_TLSv1
+ {
+ "NO_TLSv1", SSL_OP_NO_TLSv1
+ },
+#endif
+#if SSL_OP_NO_TLSv1_1
+ {
+ "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
+ },
+#endif
+#if SSL_OP_NO_TLSv1_2
+ {
+ "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
+ },
+#endif
+#if SSL_OP_NO_COMPRESSION
+ {
+ "No_Compression", SSL_OP_NO_COMPRESSION
+ },
+#endif
+#if SSL_OP_NO_TICKET
+ {
+ "NO_TICKET", SSL_OP_NO_TICKET
+ },
+#endif
+ {
+ "", 0
+ },
+ {
+ NULL, 0
+ }
+};
+
+long
+Security::ParseOptions(const char *options)
+{
+ long op = 0;
+ char *tmp;
+ char *option;
+
+ if (options) {
+
+ tmp = xstrdup(options);
+ option = strtok(tmp, ":,");
+
+ while (option) {
+
+ enum {
+ MODE_ADD, MODE_REMOVE
+ } mode;
+
+ switch (*option) {
+
+ case '!':
+
+ case '-':
+ mode = MODE_REMOVE;
+ ++option;
+ break;
+
+ case '+':
+ mode = MODE_ADD;
+ ++option;
+ break;
+
+ default:
+ mode = MODE_ADD;
+ break;
+ }
+
+ struct ssl_option *opt = NULL;
+ for (struct ssl_option *opttmp = ssl_options; opttmp->name; ++opttmp) {
+ if (strcmp(opttmp->name, option) == 0) {
+ opt = opttmp;
+ break;
+ }
+ }
+
+ long value = 0;
+ if (opt)
+ value = opt->value;
+ else if (strncmp(option, "0x", 2) == 0) {
+ /* Special case.. hex specification */
+ value = strtol(option + 2, NULL, 16);
+ } else {
+ fatalf("Unknown SSL option '%s'", option);
+ value = 0; /* Keep GCC happy */
+ }
+
+ switch (mode) {
+
+ case MODE_ADD:
+ op |= value;
+ break;
+
+ case MODE_REMOVE:
+ op &= ~value;
+ break;
+ }
+
+ option = strtok(NULL, ":,");
+ }
+
+ safe_free(tmp);
+ }
+
+#if SSL_OP_NO_SSLv2
+ // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
+ op = op | SSL_OP_NO_SSLv2;
+#endif
+ return op;
+}
+
void
parse_securePeerOptions(Security::PeerOptions *opt)
{
/// configuration options for DIRECT server access
extern PeerOptions ProxyOutgoingConfig;
+/**
+ * Parses the TLS options squid.conf parameter
+ */
+long ParseOptions(const char *options);
+
} // namespace Security
// parse the tls_outgoing_options directive
return ok;
}
-/// \ingroup ServerProtocolSSLInternal
-static struct ssl_option {
- const char *name;
- long value;
-}
-
-ssl_options[] = {
-
-#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
- {
- "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
- },
-#endif
-#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
- {
- "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
- },
-#endif
-#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
- {
- "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
- },
-#endif
-#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
- {
- "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
- },
-#endif
-#if SSL_OP_TLS_D5_BUG
- {
- "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
- },
-#endif
-#if SSL_OP_TLS_BLOCK_PADDING_BUG
- {
- "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
- },
-#endif
-#if SSL_OP_TLS_ROLLBACK_BUG
- {
- "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
- },
-#endif
-#if SSL_OP_ALL
- {
- "ALL", (long)SSL_OP_ALL
- },
-#endif
-#if SSL_OP_SINGLE_DH_USE
- {
- "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
- },
-#endif
-#if SSL_OP_EPHEMERAL_RSA
- {
- "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
- },
-#endif
-#if SSL_OP_PKCS1_CHECK_1
- {
- "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
- },
-#endif
-#if SSL_OP_PKCS1_CHECK_2
- {
- "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
- },
-#endif
-#if SSL_OP_NETSCAPE_CA_DN_BUG
- {
- "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
- },
-#endif
-#if SSL_OP_NON_EXPORT_FIRST
- {
- "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
- },
-#endif
-#if SSL_OP_CIPHER_SERVER_PREFERENCE
- {
- "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
- },
-#endif
-#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
- {
- "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
- },
-#endif
-#if SSL_OP_NO_SSLv3
- {
- "NO_SSLv3", SSL_OP_NO_SSLv3
- },
-#endif
-#if SSL_OP_NO_TLSv1
- {
- "NO_TLSv1", SSL_OP_NO_TLSv1
- },
-#endif
-#if SSL_OP_NO_TLSv1_1
- {
- "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
- },
-#endif
-#if SSL_OP_NO_TLSv1_2
- {
- "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
- },
-#endif
-#if SSL_OP_NO_COMPRESSION
- {
- "No_Compression", SSL_OP_NO_COMPRESSION
- },
-#endif
-#if SSL_OP_NO_TICKET
- {
- "NO_TICKET", SSL_OP_NO_TICKET
- },
-#endif
- {
- "", 0
- },
- {
- NULL, 0
- }
-};
-
-/// \ingroup ServerProtocolSSLInternal
-long
-Ssl::parse_options(const char *options)
-{
- long op = 0;
- char *tmp;
- char *option;
-
- if (!options)
- goto no_options;
-
- tmp = xstrdup(options);
-
- option = strtok(tmp, ":,");
-
- while (option) {
-
- struct ssl_option *opt = NULL, *opttmp;
- long value = 0;
- enum {
- MODE_ADD, MODE_REMOVE
- } mode;
-
- switch (*option) {
-
- case '!':
-
- case '-':
- mode = MODE_REMOVE;
- ++option;
- break;
-
- case '+':
- mode = MODE_ADD;
- ++option;
- break;
-
- default:
- mode = MODE_ADD;
- break;
- }
-
- for (opttmp = ssl_options; opttmp->name; ++opttmp) {
- if (strcmp(opttmp->name, option) == 0) {
- opt = opttmp;
- break;
- }
- }
-
- if (opt)
- value = opt->value;
- else if (strncmp(option, "0x", 2) == 0) {
- /* Special case.. hex specification */
- value = strtol(option + 2, NULL, 16);
- } else {
- fatalf("Unknown SSL option '%s'", option);
- value = 0; /* Keep GCC happy */
- }
-
- switch (mode) {
-
- case MODE_ADD:
- op |= value;
- break;
-
- case MODE_REMOVE:
- op &= ~value;
- break;
- }
-
- option = strtok(NULL, ":,");
- }
-
- safe_free(tmp);
-
-no_options:
-#if SSL_OP_NO_SSLv2
- // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
- op = op | SSL_OP_NO_SSLv2;
-#endif
- return op;
-}
-
/// \ingroup ServerProtocolSSLInternal
#define SSL_FLAG_NO_DEFAULT_CA (1<<0)
/// \ingroup ServerProtocolSSLInternal
}
SSL_CTX *
-sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *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, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
{
int ssl_error;
Ssl::ContextMethod method;
ERR_error_string(ssl_error, NULL));
}
- SSL_CTX_set_options(sslContext, Ssl::parse_options(options));
+ SSL_CTX_set_options(sslContext, options);
if (*cipher) {
debugs(83, 5, "Using chiper suite " << cipher << ".");
SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port);
/// \ingroup ServerProtocolSSLAPI
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *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, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
/// \ingroup ServerProtocolSSLAPI
int ssl_read_method(int, char *, int);
*/
long parse_flags(const char *flags);
-/**
- \ingroup ServerProtocolSSLAPI
- * Parses the SSL options.
- */
-long parse_options(const char *options);
-
/**
\ingroup ServerProtocolSSLAPI
* Load a CRLs list stored in a file
void Security::PeerOptions::parse(char const*) STUB
Security::ContextPointer Security::PeerOptions::createContext(bool) STUB_RETVAL(NULL)
void parse_securePeerOptions(Security::PeerOptions *) STUB
+long Security::ParseOptions(const char *) STUB_RETVAL(0)
bool CertError::operator != (const CertError &ce) const STUB_RETVAL(false)
} // namespace Ssl
SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port) STUB_RETVAL(NULL)
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) STUB_RETVAL(NULL)
+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) STUB_RETVAL(NULL)
int ssl_read_method(int, char *, int) STUB_RETVAL(0)
int ssl_write_method(int, const char *, int) STUB_RETVAL(0)
void ssl_shutdown_method(SSL *ssl) STUB
//GETX509ATTRIBUTE GetX509Fingerprint;
const char *BumpModeStr[] = {""};
long parse_flags(const char *flags) STUB_RETVAL(0)
-long parse_options(const char *options) STUB_RETVAL(0)
STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags) STUB_RETVAL(NULL)
DH *readDHParams(const char *dhfile) STUB_RETVAL(NULL)
ContextMethod contextMethod(int version) STUB_RETVAL(ContextMethod())