/*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
if (acl_access *acl = ::Config.ssl_client.cert_error) {
ACLFilledChecklist *check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
check->al = al;
+ check->syncAle(request.getRaw(), nullptr);
// check->fd(fd); XXX: need client FD here
SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check);
}
try {
debugs(83, 5, "Sending SSL certificate for validation to ssl_crtvd.");
AsyncCall::Pointer call = asyncCall(83,5, "Security::PeerConnector::sslCrtvdHandleReply", Ssl::CertValidationHelper::CbDialer(this, &Security::PeerConnector::sslCrtvdHandleReply, nullptr));
- Ssl::CertValidationHelper::GetInstance()->sslSubmit(validationRequest, call);
+ Ssl::CertValidationHelper::Submit(validationRequest, call);
return false;
} catch (const std::exception &e) {
debugs(83, DBG_IMPORTANT, "ERROR: Failed to compose ssl_crtvd " <<
if (acl_access *acl = ::Config.ssl_client.cert_error) {
check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
check->al = al;
+ check->syncAle(request.getRaw(), nullptr);
}
Security::CertErrors *errs = nullptr;
bool allowed = false;
if (check) {
check->sslErrors = new Security::CertErrors(Security::CertError(i->error_no, i->cert, i->error_depth));
- if (check->fastCheck() == ACCESS_ALLOWED)
+ if (check->fastCheck().allowed())
allowed = true;
}
// else the Config.ssl_client.cert_error access list is not defined
void
Security::PeerConnector::NegotiateSsl(int, void *data)
{
- PeerConnector *pc = static_cast<Security::PeerConnector *>(data);
+ const auto pc = static_cast<PeerConnector::Pointer*>(data);
+ if (pc->valid())
+ (*pc)->negotiateSsl();
+ delete pc;
+}
+
+/// Comm::SetSelect() callback. Direct calls tickle/resume negotiations.
+void
+Security::PeerConnector::negotiateSsl()
+{
// Use job calls to add done() checks and other job logic/protections.
- CallJobHere(83, 7, pc, Security::PeerConnector, negotiate);
+ CallJobHere(83, 7, this, Security::PeerConnector, negotiate);
}
void
switch (ret) {
case GNUTLS_E_WARNING_ALERT_RECEIVED: {
- auto alert = gnutls_alert_get(session.get());
- debugs(83, DBG_IMPORTANT, "TLS ALERT: " << gnutls_alert_get_name(alert));
- }
- // drop through to next case
+ auto alert = gnutls_alert_get(session.get());
+ debugs(83, DBG_IMPORTANT, "TLS ALERT: " << gnutls_alert_get_name(alert));
+ }
+ // drop through to next case
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
srvBio->holdRead(false);
// schedule a negotiateSSl to allow openSSL parse received data
- Security::PeerConnector::NegotiateSsl(fd, this);
+ negotiateSsl();
return;
} else if (srvBio->gotHelloFailed()) {
srvBio->holdRead(false);
debugs(83, DBG_IMPORTANT, "Error parsing SSL Server Hello Message on FD " << fd);
// schedule a negotiateSSl to allow openSSL parse received data
- Security::PeerConnector::NegotiateSsl(fd, this);
+ negotiateSsl();
return;
}
}
#endif
setReadTimeout();
- Comm::SetSelect(fd, COMM_SELECT_READ, &NegotiateSsl, this, 0);
+ Comm::SetSelect(fd, COMM_SELECT_READ, &NegotiateSsl, new Pointer(this), 0);
}
void
{
const int fd = serverConnection()->fd;
debugs(83, 5, serverConnection());
- Comm::SetSelect(fd, COMM_SELECT_WRITE, &NegotiateSsl, this, 0);
+ Comm::SetSelect(fd, COMM_SELECT_WRITE, &NegotiateSsl, new Pointer(this), 0);
return;
}
": " << Security::ErrorString(ssl_lib_error) << " (" <<
ssl_error << "/" << ret << "/" << xerr << ")");
- ErrorState *anErr = NULL;
- if (request != NULL)
- anErr = ErrorState::NewForwarding(ERR_SECURE_CONNECT_FAIL, request.getRaw());
- else
- anErr = new ErrorState(ERR_SECURE_CONNECT_FAIL, Http::scServiceUnavailable, NULL);
+ ErrorState *anErr = ErrorState::NewForwarding(ERR_SECURE_CONNECT_FAIL, request);
anErr->xerrno = sysErrNo;
#if USE_OPENSSL
PeerConnectorCertDownloaderDialer(&Security::PeerConnector::certDownloadingDone, this));
const Downloader *csd = (request ? dynamic_cast<const Downloader*>(request->downloader.valid()) : nullptr);
- Downloader *dl = new Downloader(url, certCallback, csd ? csd->nestedLevel() + 1 : 1);
+ Downloader *dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, csd ? csd->nestedLevel() + 1 : 1);
AsyncJob::Start(dl);
}
if (X509 *cert = d2i_X509(NULL, &raw, obj.length())) {
char buffer[1024];
debugs(81, 5, "Retrieved certificate: " << X509_NAME_oneline(X509_get_subject_name(cert), buffer, 1024));
+ ContextPointer ctx(getTlsContext());
const Security::CertList &certsList = srvBio->serverCertificatesIfAny();
- if (const char *issuerUri = Ssl::uriOfIssuerIfMissing(cert, certsList)) {
+ if (const char *issuerUri = Ssl::uriOfIssuerIfMissing(cert, certsList, ctx)) {
urlsOfMissingCerts.push(SBuf(issuerUri));
}
Ssl::SSL_add_untrusted_cert(session.get(), cert);
}
srvBio->holdRead(false);
- Security::PeerConnector::NegotiateSsl(serverConnection()->fd, this);
+ negotiateSsl();
}
bool
if (certs.size()) {
debugs(83, 5, "SSL server sent " << certs.size() << " certificates");
- Ssl::missingChainCertificatesUrls(urlsOfMissingCerts, certs);
+ ContextPointer ctx(getTlsContext());
+ Ssl::missingChainCertificatesUrls(urlsOfMissingCerts, certs, ctx);
if (urlsOfMissingCerts.size()) {
startCertDownloading(urlsOfMissingCerts.front());
urlsOfMissingCerts.pop();