PeerConnector.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2019 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 83 TLS Server/Peer negotiation */
10 
11 #include "squid.h"
12 #include "acl/FilledChecklist.h"
13 #include "comm/Loops.h"
14 #include "comm/Read.h"
15 #include "Downloader.h"
16 #include "errorpage.h"
17 #include "fde.h"
18 #include "http/Stream.h"
19 #include "HttpRequest.h"
21 #include "security/PeerConnector.h"
22 #include "SquidConfig.h"
23 #if USE_OPENSSL
24 #include "ssl/bio.h"
26 #include "ssl/Config.h"
27 #include "ssl/helper.h"
28 #endif
29 
31 
32 Security::PeerConnector::PeerConnector(const Comm::ConnectionPointer &aServerConn, AsyncCall::Pointer &aCallback, const AccessLogEntryPointer &alp, const time_t timeout) :
33  AsyncJob("Security::PeerConnector"),
34  serverConn(aServerConn),
35  al(alp),
36  callback(aCallback),
37  negotiationTimeout(timeout),
38  startTime(squid_curtime),
39  useCertValidator_(true),
40  certsDownloads(0)
41 {
42  debugs(83, 5, "Security::PeerConnector constructed, this=" << (void*)this);
43  // if this throws, the caller's cb dialer is not our CbDialer
44  Must(dynamic_cast<CbDialer*>(callback->getDialer()));
45 }
46 
48 {
49  debugs(83, 5, "Security::PeerConnector destructed, this=" << (void*)this);
50 }
51 
53 {
54  return (!callback || callback->canceled()) && AsyncJob::doneAll();
55 }
56 
58 void
60 {
62  debugs(83, 5, "this=" << (void*)this);
63 
65  if (prepareSocket() && initialize(tmp))
66  negotiate();
67  else
68  mustStop("Security::PeerConnector TLS socket initialize failed");
69 }
70 
71 void
73 {
74  debugs(83, 5, "FD " << params.fd << ", Security::PeerConnector=" << params.data);
75  connectionClosed("Security::PeerConnector::commCloseHandler");
76 }
77 
78 void
80 {
81  debugs(83, 5, reason << " socket closed/closing. this=" << (void*)this);
82  mustStop(reason);
83  callback = NULL;
84 }
85 
86 bool
88 {
89  debugs(83, 5, serverConnection() << ", this=" << (void*)this);
90  if (!Comm::IsConnOpen(serverConnection()) || fd_table[serverConnection()->fd].closing()) {
91  connectionClosed("Security::PeerConnector::prepareSocket");
92  return false;
93  }
94 
95  debugs(83, 5, serverConnection());
96 
97  // watch for external connection closures
101  return true;
102 }
103 
104 bool
106 {
108  debugs(83, 5, serverConnection() << ", ctx=" << (void*)ctx.get());
109 
110  if (!ctx || !Security::CreateClientSession(ctx, serverConnection(), "server https start")) {
111  const auto xerrno = errno;
112  if (!ctx) {
113  debugs(83, DBG_IMPORTANT, "Error initializing TLS connection: No security context.");
114  } // else CreateClientSession() did the appropriate debugs() already
116  anErr->xerrno = xerrno;
117  noteNegotiationDone(anErr);
118  bail(anErr);
119  return false;
120  }
121 
122  // A TLS/SSL session has now been created for the connection and stored in fd_table
123  serverSession = fd_table[serverConnection()->fd].ssl;
124  debugs(83, 5, serverConnection() << ", session=" << (void*)serverSession.get());
125 
126 #if USE_OPENSSL
127  // If CertValidation Helper used do not lookup checklist for errors,
128  // but keep a list of errors to send it to CertValidator
129  if (!Ssl::TheConfig.ssl_crt_validator) {
130  // Create the ACL check list now, while we have access to more info.
131  // The list is used in ssl_verify_cb() and is freed in ssl_free().
132  if (acl_access *acl = ::Config.ssl_client.cert_error) {
134  check->al = al;
135  check->syncAle(request.getRaw(), nullptr);
136  // check->fd(fd); XXX: need client FD here
137  SSL_set_ex_data(serverSession.get(), ssl_ex_index_cert_error_check, check);
138  }
139  }
140 #endif
141 
142  return true;
143 }
144 
145 void
147 {
148  const int fd = serverConnection()->fd;
149  Security::SessionPointer session(fd_table[fd].ssl);
150 
151  // retrieve TLS server negotiated information if any
153 
154 #if USE_OPENSSL
155  // retrieve TLS parsed extra info
156  BIO *b = SSL_get_rbio(session.get());
157  Ssl::ServerBio *bio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
158  if (const Security::TlsDetails::Pointer &details = bio->receivedHelloDetails())
160 #endif
161 }
162 
163 void
165 {
167  return;
168 
169  const int fd = serverConnection()->fd;
170  if (fd_table[fd].closing())
171  return;
172 
173 #if USE_OPENSSL
174  auto session = fd_table[fd].ssl.get();
175  debugs(83, 5, "SSL_connect session=" << (void*)session);
176  const int result = SSL_connect(session);
177  if (result <= 0) {
178 #elif USE_GNUTLS
179  auto session = fd_table[fd].ssl.get();
180  const int result = gnutls_handshake(session);
181  debugs(83, 5, "gnutls_handshake session=" << (void*)session << ", result=" << result);
182 
183  if (result == GNUTLS_E_SUCCESS) {
184  char *desc = gnutls_session_get_desc(session);
185  debugs(83, 2, serverConnection() << " TLS Session info: " << desc);
186  gnutls_free(desc);
187  }
188 
189  if (result != GNUTLS_E_SUCCESS) {
190  // debug the TLS session state so far
191  auto descIn = gnutls_handshake_get_last_in(session);
192  debugs(83, 2, "handshake IN: " << gnutls_handshake_description_get_name(descIn));
193  auto descOut = gnutls_handshake_get_last_out(session);
194  debugs(83, 2, "handshake OUT: " << gnutls_handshake_description_get_name(descOut));
195 #else
196  if (const int result = -1) {
197 #endif
198  handleNegotiateError(result);
199  return; // we might be gone by now
200  }
201 
203 
204  if (!sslFinalized())
205  return;
206 
207  callBack();
208 }
209 
210 bool
212 {
213 #if USE_OPENSSL
214  if (Ssl::TheConfig.ssl_crt_validator && useCertValidator_) {
215  const int fd = serverConnection()->fd;
216  Security::SessionPointer session(fd_table[fd].ssl);
217 
218  Ssl::CertValidationRequest validationRequest;
219  // WARNING: Currently we do not use any locking for 'errors' member
220  // of the Ssl::CertValidationRequest class. In this code the
221  // Ssl::CertValidationRequest object used only to pass data to
222  // Ssl::CertValidationHelper::submit method.
223  validationRequest.ssl = session;
224  if (SBuf *dName = (SBuf *)SSL_get_ex_data(session.get(), ssl_ex_index_server))
225  validationRequest.domainName = dName->c_str();
226  if (Security::CertErrors *errs = static_cast<Security::CertErrors *>(SSL_get_ex_data(session.get(), ssl_ex_index_ssl_errors)))
227  // validationRequest disappears on return so no need to cbdataReference
228  validationRequest.errors = errs;
229  try {
230  debugs(83, 5, "Sending SSL certificate for validation to ssl_crtvd.");
231  AsyncCall::Pointer call = asyncCall(83,5, "Security::PeerConnector::sslCrtvdHandleReply", Ssl::CertValidationHelper::CbDialer(this, &Security::PeerConnector::sslCrtvdHandleReply, nullptr));
232  Ssl::CertValidationHelper::Submit(validationRequest, call);
233  return false;
234  } catch (const std::exception &e) {
235  debugs(83, DBG_IMPORTANT, "ERROR: Failed to compose ssl_crtvd " <<
236  "request for " << validationRequest.domainName <<
237  " certificate: " << e.what() << "; will now block to " <<
238  "validate that certificate.");
239  // fall through to do blocking in-process generation.
241 
242  noteNegotiationDone(anErr);
243  bail(anErr);
244  serverConn->close();
245  return true;
246  }
247  }
248 #endif
249 
251  return true;
252 }
253 
254 #if USE_OPENSSL
255 void
257 {
258  Must(validationResponse != NULL);
259 
260  Ssl::ErrorDetail *errDetails = NULL;
261  bool validatorFailed = false;
263  return;
264  }
265 
266  if (Debug::Enabled(83, 5)) {
268  SBuf *server = static_cast<SBuf *>(SSL_get_ex_data(ssl.get(), ssl_ex_index_server));
269  debugs(83,5, RawPointer("host", server) << " cert validation result: " << validationResponse->resultCode);
270  }
271 
272  if (validationResponse->resultCode == ::Helper::Error) {
273  if (Security::CertErrors *errs = sslCrtvdCheckForErrors(*validationResponse, errDetails)) {
275  Security::CertErrors *oldErrs = static_cast<Security::CertErrors*>(SSL_get_ex_data(session.get(), ssl_ex_index_ssl_errors));
276  SSL_set_ex_data(session.get(), ssl_ex_index_ssl_errors, (void *)errs);
277  delete oldErrs;
278  }
279  } else if (validationResponse->resultCode != ::Helper::Okay)
280  validatorFailed = true;
281 
282  if (!errDetails && !validatorFailed) {
284  callBack();
285  return;
286  }
287 
288  ErrorState *anErr = NULL;
289  if (validatorFailed) {
291  } else {
293  anErr->detail = errDetails;
294  /*anErr->xerrno= Should preserved*/
295  }
296 
297  noteNegotiationDone(anErr);
298  bail(anErr);
299  serverConn->close();
300  return;
301 }
302 #endif
303 
304 #if USE_OPENSSL
310 {
311  ACLFilledChecklist *check = NULL;
312  if (acl_access *acl = ::Config.ssl_client.cert_error) {
313  check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
314  check->al = al;
315  check->syncAle(request.getRaw(), nullptr);
316  }
317 
318  Security::CertErrors *errs = nullptr;
320  typedef Ssl::CertValidationResponse::RecvdErrors::const_iterator SVCRECI;
321  for (SVCRECI i = resp.errors.begin(); i != resp.errors.end(); ++i) {
322  debugs(83, 7, "Error item: " << i->error_no << " " << i->error_reason);
323 
324  assert(i->error_no != SSL_ERROR_NONE);
325 
326  if (!errDetails) {
327  bool allowed = false;
328  if (check) {
329  check->sslErrors = new Security::CertErrors(Security::CertError(i->error_no, i->cert, i->error_depth));
330  if (check->fastCheck().allowed())
331  allowed = true;
332  }
333  // else the Config.ssl_client.cert_error access list is not defined
334  // and the first error will cause the error page
335 
336  if (allowed) {
337  debugs(83, 3, "bypassing SSL error " << i->error_no << " in " << "buffer");
338  } else {
339  debugs(83, 5, "confirming SSL error " << i->error_no);
340  X509 *brokenCert = i->cert.get();
341  Security::CertPointer peerCert(SSL_get_peer_certificate(session.get()));
342  const char *aReason = i->error_reason.empty() ? NULL : i->error_reason.c_str();
343  errDetails = new Ssl::ErrorDetail(i->error_no, peerCert.get(), brokenCert, aReason);
344  }
345  if (check) {
346  delete check->sslErrors;
347  check->sslErrors = NULL;
348  }
349  }
350 
351  if (!errs)
352  errs = new Security::CertErrors(Security::CertError(i->error_no, i->cert, i->error_depth));
353  else
354  errs->push_back_unique(Security::CertError(i->error_no, i->cert, i->error_depth));
355  }
356  if (check)
357  delete check;
358 
359  return errs;
360 }
361 #endif
362 
364 void
366 {
367  const auto pc = static_cast<PeerConnector::Pointer*>(data);
368  if (pc->valid())
369  (*pc)->negotiateSsl();
370  delete pc;
371 }
372 
374 void
376 {
377  // Use job calls to add done() checks and other job logic/protections.
379 }
380 
381 void
383 {
384  const int fd = serverConnection()->fd;
385  const Security::SessionPointer session(fd_table[fd].ssl);
386  unsigned long ssl_lib_error = ret;
387 
388 #if USE_OPENSSL
389  const int ssl_error = SSL_get_error(session.get(), ret);
390 
391  switch (ssl_error) {
392  case SSL_ERROR_WANT_READ:
393  noteWantRead();
394  return;
395 
396  case SSL_ERROR_WANT_WRITE:
397  noteWantWrite();
398  return;
399 
400  case SSL_ERROR_SSL:
401  case SSL_ERROR_SYSCALL:
402  ssl_lib_error = ERR_get_error();
403  // proceed to the general error handling code
404  break;
405  default:
406  // no special error handling for all other errors
407  ssl_lib_error = SSL_ERROR_NONE;
408  break;
409  }
410 
411 #elif USE_GNUTLS
412  const int ssl_error = ret;
413 
414  switch (ret) {
415  case GNUTLS_E_WARNING_ALERT_RECEIVED: {
416  auto alert = gnutls_alert_get(session.get());
417  debugs(83, DBG_IMPORTANT, "TLS ALERT: " << gnutls_alert_get_name(alert));
418  }
419  // drop through to next case
420 
421  case GNUTLS_E_AGAIN:
422  case GNUTLS_E_INTERRUPTED:
423  if (gnutls_record_get_direction(session.get()) == 0)
424  noteWantRead();
425  else
426  noteWantWrite();
427  return;
428 
429  default:
430  // no special error handling for all other errors
431  break;
432  }
433 
434 #else
435  // this avoids unused variable compiler warnings.
436  Must(!session);
437  const int ssl_error = ret;
438 #endif
439 
440  // Log connection details, if any
442  noteNegotiationError(ret, ssl_error, ssl_lib_error);
443 }
444 
445 void
447 {
448  const int fd = serverConnection()->fd;
449  debugs(83, 5, serverConnection());
450 #if USE_OPENSSL
451  Security::SessionPointer session(fd_table[fd].ssl);
452  BIO *b = SSL_get_rbio(session.get());
453  Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
454  if (srvBio->holdRead()) {
455  if (srvBio->gotHello()) {
457  return; // Wait to download certificates before proceed.
458 
459  srvBio->holdRead(false);
460  // schedule a negotiateSSl to allow openSSL parse received data
461  negotiateSsl();
462  return;
463  } else if (srvBio->gotHelloFailed()) {
464  srvBio->holdRead(false);
465  debugs(83, DBG_IMPORTANT, "Error parsing SSL Server Hello Message on FD " << fd);
466  // schedule a negotiateSSl to allow openSSL parse received data
467  negotiateSsl();
468  return;
469  }
470  }
471 #endif
472 
473  // read timeout to avoid getting stuck while reading from a silent server
476  commSetConnTimeout(serverConnection(), timeout, nil);
477 
479 }
480 
481 void
483 {
484  const int fd = serverConnection()->fd;
485  debugs(83, 5, serverConnection());
487  return;
488 }
489 
490 void
491 Security::PeerConnector::noteNegotiationError(const int ret, const int ssl_error, const int ssl_lib_error)
492 {
493 #if defined(EPROTO)
494  int sysErrNo = EPROTO;
495 #else
496  int sysErrNo = EACCES;
497 #endif
498 
499 #if USE_OPENSSL
500  // store/report errno when ssl_error is SSL_ERROR_SYSCALL, ssl_lib_error is 0, and ret is -1
501  if (ssl_error == SSL_ERROR_SYSCALL && ret == -1 && ssl_lib_error == 0)
502  sysErrNo = errno;
503 #endif
504  int xerr = errno;
505 
506  const int fd = serverConnection()->fd;
507  debugs(83, DBG_IMPORTANT, "ERROR: negotiating TLS on FD " << fd <<
508  ": " << Security::ErrorString(ssl_lib_error) << " (" <<
509  ssl_error << "/" << ret << "/" << xerr << ")");
510 
512  anErr->xerrno = sysErrNo;
513 
514 #if USE_OPENSSL
515  Security::SessionPointer session(fd_table[fd].ssl);
516  Ssl::ErrorDetail *errFromFailure = static_cast<Ssl::ErrorDetail *>(SSL_get_ex_data(session.get(), ssl_ex_index_ssl_error_detail));
517  if (errFromFailure != NULL) {
518  // The errFromFailure is attached to the ssl object
519  // and will be released when ssl object destroyed.
520  // Copy errFromFailure to a new Ssl::ErrorDetail object
521  anErr->detail = new Ssl::ErrorDetail(*errFromFailure);
522  } else {
523  // server_cert can be NULL here
524  X509 *server_cert = SSL_get_peer_certificate(session.get());
525  anErr->detail = new Ssl::ErrorDetail(SQUID_ERR_SSL_HANDSHAKE, server_cert, NULL);
526  X509_free(server_cert);
527  }
528 
529  if (ssl_lib_error != SSL_ERROR_NONE)
530  anErr->detail->setLibError(ssl_lib_error);
531 #endif
532 
533  noteNegotiationDone(anErr);
534  bail(anErr);
535 }
536 
537 void
539 {
540  Must(error); // or the recepient will not know there was a problem
541  Must(callback != NULL);
542  CbDialer *dialer = dynamic_cast<CbDialer*>(callback->getDialer());
543  Must(dialer);
544  dialer->answer().error = error;
545 
546  callBack();
547  // Our job is done. The callabck recepient will probably close the failed
548  // peer connection and try another peer or go direct (if possible). We
549  // can close the connection ourselves (our error notification would reach
550  // the recepient before the fd-closure notification), but we would rather
551  // minimize the number of fd-closure notifications and let the recepient
552  // manage the TCP state of the connection.
553 }
554 
555 void
557 {
558  debugs(83, 5, "TLS setup ended for " << serverConnection());
559 
561  // Do this now so that if we throw below, swanSong() assert that we _tried_
562  // to call back holds.
563  callback = NULL; // this should make done() true
564 
565  // remove close handler
567 
568  CbDialer *dialer = dynamic_cast<CbDialer*>(cb->getDialer());
569  Must(dialer);
570  dialer->answer().conn = serverConnection();
571  ScheduleCallHere(cb);
572 }
573 
574 void
576 {
577  // XXX: unregister fd-closure monitoring and CommSetSelect interest, if any
579  if (callback != NULL) { // paranoid: we have left the caller waiting
580  debugs(83, DBG_IMPORTANT, "BUG: Unexpected state while connecting to a cache_peer or origin server");
582  bail(anErr);
583  assert(!callback);
584  return;
585  }
586 }
587 
588 const char *
590 {
591  static MemBuf buf;
592  buf.reset();
593 
594  // TODO: redesign AsyncJob::status() API to avoid this
595  // id and stop reason reporting duplication.
596  buf.append(" [", 2);
597  if (stopReason != NULL) {
598  buf.append("Stopped, reason:", 16);
599  buf.appendf("%s",stopReason);
600  }
601  if (serverConn != NULL)
602  buf.appendf(" FD %d", serverConn->fd);
603  buf.appendf(" %s%u]", id.prefix(), id.value);
604  buf.terminate();
605 
606  return buf.content();
607 }
608 
609 #if USE_OPENSSL
612 {
613 public:
614  typedef void (Security::PeerConnector::*Method)(SBuf &object, int status);
615 
617  method_(method),
618  peerConnector_(pc) {}
619 
620  /* CallDialer API */
621  virtual bool canDial(AsyncCall &call) { return peerConnector_.valid(); }
622  virtual void dial(AsyncCall &call) { ((&(*peerConnector_))->*method_)(object, status); }
625 };
626 
627 void
629 {
630  AsyncCall::Pointer certCallback = asyncCall(81, 4,
631  "Security::PeerConnector::certDownloadingDone",
633 
634  const Downloader *csd = (request ? dynamic_cast<const Downloader*>(request->downloader.valid()) : nullptr);
635  Downloader *dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, csd ? csd->nestedLevel() + 1 : 1);
636  AsyncJob::Start(dl);
637 }
638 
639 void
641 {
642  ++certsDownloads;
643  debugs(81, 5, "Certificate downloading status: " << downloadStatus << " certificate size: " << obj.length());
644 
645  // get ServerBio from SSL object
646  const int fd = serverConnection()->fd;
647  Security::SessionPointer session(fd_table[fd].ssl);
648  BIO *b = SSL_get_rbio(session.get());
649  Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
650 
651  // Parse Certificate. Assume that it is in DER format.
652  // According to RFC 4325:
653  // The server must provide a DER encoded certificate or a collection
654  // collection of certificates in a "certs-only" CMS message.
655  // The applications MUST accept DER encoded certificates and SHOULD
656  // be able to accept collection of certificates.
657  // TODO: support collection of certificates
658  const unsigned char *raw = (const unsigned char*)obj.rawContent();
659  if (X509 *cert = d2i_X509(NULL, &raw, obj.length())) {
660  char buffer[1024];
661  debugs(81, 5, "Retrieved certificate: " << X509_NAME_oneline(X509_get_subject_name(cert), buffer, 1024));
663  const Security::CertList &certsList = srvBio->serverCertificatesIfAny();
664  if (const char *issuerUri = Ssl::uriOfIssuerIfMissing(cert, certsList, ctx)) {
665  urlsOfMissingCerts.push(SBuf(issuerUri));
666  }
667  Ssl::SSL_add_untrusted_cert(session.get(), cert);
668  }
669 
670  // Check if there are URIs to download from and if yes start downloading
671  // the first in queue.
674  urlsOfMissingCerts.pop();
675  return;
676  }
677 
678  srvBio->holdRead(false);
679  negotiateSsl();
680 }
681 
682 bool
684 {
685  // Check for nested SSL certificates downloads. For example when the
686  // certificate located in an SSL site which requires to download a
687  // a missing certificate (... from an SSL site which requires to ...).
688 
689  const Downloader *csd = (request ? request->downloader.get() : nullptr);
690  if (csd && csd->nestedLevel() >= MaxNestedDownloads)
691  return false;
692 
693  const int fd = serverConnection()->fd;
694  Security::SessionPointer session(fd_table[fd].ssl);
695  BIO *b = SSL_get_rbio(session.get());
696  Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
697  const Security::CertList &certs = srvBio->serverCertificatesIfAny();
698 
699  if (certs.size()) {
700  debugs(83, 5, "SSL server sent " << certs.size() << " certificates");
703  if (urlsOfMissingCerts.size()) {
705  urlsOfMissingCerts.pop();
706  return true;
707  }
708  }
709 
710  return false;
711 }
712 #endif //USE_OPENSSL
713 
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:404
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:69
#define fd_table
Definition: fde.h:174
#define COMM_SELECT_READ
Definition: defines.h:36
#define assert(EX)
Definition: assert.h:17
virtual bool doneAll() const
whether positive goal has been reached
bool holdRead() const
The read hold state.
Definition: bio.h:151
void const char HLPCB * callback
Definition: stub_helper.cc:16
AccessLogEntryPointer al
info for the future access.log entry
RecvdErrors errors
The list of parsed errors.
#define CallJobHere(debugSection, debugLevel, job, Class, method)
Definition: AsyncJobCalls.h:58
void connectionClosed(const char *reason)
Inform us that the connection is closed. Does the required clean-up.
virtual void append(const char *c, int sz)
Definition: MemBuf.cc:216
int ssl_ex_index_server
Security::NegotiationHistory * tlsNegotiations()
Definition: Connection.cc:130
CbcPointer< ErrorState > error
problem details (nil on success)
void mustStop(const char *aReason)
Definition: AsyncJob.cc:69
Definition: SBuf.h:86
void startCertDownloading(SBuf &url)
Start downloading procedure for the given URL.
PeerConnector(const Comm::ConnectionPointer &aServerConn, AsyncCall::Pointer &aCallback, const AccessLogEntryPointer &alp, const time_t timeout=0)
void error(char *format,...)
int i
Definition: membanger.c:49
T * get() const
Returns raw and possibly nullptr pointer.
CbcPointer< Security::PeerConnector > peerConnector_
The Security::PeerConnector object.
std::list< Security::CertPointer > CertList
Definition: forward.h:80
AccessLogEntry::Pointer al
info for the future access.log, and external ACL
static const unsigned int MaxCertsDownloads
The maximum allowed missing certificates downloads.
Missing intermediate certificates fetching code.
int ssl_ex_index_cert_error_check
time_t startTime
when the peer connector negotiation started
unsigned int nestedLevel() const
The nested level of Downloader object (downloads inside downloads).
Definition: Downloader.h:57
#define Must(condition)
Like assert() but throws an exception instead of aborting the process.
Definition: TextException.h:69
CallDialer to allow use Downloader objects within PeerConnector class.
virtual const char * status() const
internal cleanup; do not call directly
AsyncCall::Pointer callback
we call this with the results
struct SquidConfig::@123 ssl_client
time_t squid_curtime
Definition: stub_time.cc:17
Acl::Answer const & fastCheck()
Definition: Checklist.cc:336
virtual void noteWantWrite()
void * BIO_get_data(BIO *table)
Definition: openssl.h:60
AsyncCall * asyncCall(int aDebugSection, int aDebugLevel, const char *aName, const Dialer &aDialer)
Definition: AsyncCall.h:156
CbcPointer< PeerConnector > Pointer
Definition: PeerConnector.h:68
void commCloseHandler(const CommCloseCbParams &params)
The comm_close callback handler.
static void Submit(Ssl::CertValidationRequest const &request, AsyncCall::Pointer &)
Submit crtd request message to external crtd server.
Definition: helper.cc:290
static Pointer Start(AsyncJob *job)
starts a freshly created job (i.e., makes the job asynchronous)
Definition: AsyncJob.cc:23
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:24
void const char HLPCB void * data
Definition: stub_helper.cc:16
CbDataList< Security::CertError > CertErrors
Holds a list of X.509 certificate errors.
Definition: forward.h:57
virtual CallDialer * getDialer()=0
Security::SessionPointer ssl
int fd
FD which the call was about. Set by the async call creator.
Definition: CommCalls.h:90
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Debug.h:124
#define true
Definition: GnuRegex.c:234
#define DBG_IMPORTANT
Definition: Debug.h:46
bool CreateClientSession(const Security::ContextPointer &, const Comm::ConnectionPointer &, const char *squidCtx)
Definition: Session.cc:184
void SetSelect(int, unsigned int, PF *, void *, time_t)
Mark an FD to be watched for its IO status.
Definition: ModDevPoll.cc:225
Cbc * valid() const
was set and is valid
Definition: CbcPointer.h:41
int ssl_ex_index_ssl_error_detail
bool push_back_unique(C const &element)
Definition: CbDataList.h:87
virtual void swanSong()
Definition: AsyncJob.h:54
bool allowed() const
Definition: Acl.h:143
Comm::ConnectionPointer serverConn
TCP connection to the peer.
void reset()
Definition: MemBuf.cc:132
void missingChainCertificatesUrls(std::queue< SBuf > &URIs, Security::CertList const &serverCertificates, const Security::ContextPointer &context)
Definition: support.cc:1050
#define COMM_SELECT_WRITE
Definition: defines.h:37
static void NegotiateSsl(int fd, void *data)
A wrapper for Comm::SetSelect() notifications.
static ErrorState * NewForwarding(err_type, HttpRequestPointer &, const AccessLogEntryPointer &)
Creates a general request forwarding error with the right http_status.
Definition: errorpage.cc:667
std::shared_ptr< SSL_CTX > ContextPointer
Definition: Context.h:29
void retrieveParsedInfo(Security::TlsDetails::Pointer const &details)
Extract information from parser stored in TlsDetails object.
Network/connection security abstraction layer.
Definition: Connection.h:31
virtual Security::EncryptorAnswer & answer()=0
gives PeerConnector access to the in-dialer answer
void sslCrtvdHandleReply(Ssl::CertValidationResponsePointer)
Process response from cert validator helper.
void handleNegotiateError(const int result)
unsigned int certsDownloads
the number of downloaded missing certificates
AsyncCall::Pointer closeHandler
we call this when the connection closed
void SSL_add_untrusted_cert(SSL *ssl, X509 *cert)
Definition: support.cc:1062
int ssl_ex_index_ssl_errors
virtual void start()
Preps connection and SSL state. Calls negotiate().
char * content()
start of the added data
Definition: MemBuf.h:41
void const char * buf
Definition: stub_helper.cc:16
acl_access * cert_error
Definition: SquidConfig.h:516
static const unsigned int MaxNestedDownloads
The maximum allowed nested certificates downloads.
const char * uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates, const Security::ContextPointer &context)
Definition: support.cc:1029
virtual void syncAle(HttpRequest *adaptedRequest, const char *logUri) const
assigns uninitialized adapted_request and url ALE components
virtual void dial(AsyncCall &call)
#define SQUID_ERR_SSL_HANDSHAKE
Definition: support.h:43
HttpRequestPointer request
peer connection trigger or cause
Security::CertErrors * errors
The list of errors detected.
std::string domainName
The server name.
time_t MortalReadTimeout(const time_t startTime, const time_t lifetimeLimit)
maximum read delay for readers with limited lifetime
Definition: Read.cc:246
const Security::CertList & serverCertificatesIfAny()
Definition: bio.h:171
virtual bool canDial(AsyncCall &call)
CbcPointer< Downloader > downloader
The Downloader object which initiated the HTTP request if any.
Definition: HttpRequest.h:236
#define ScheduleCallHere(call)
Definition: AsyncCall.h:166
const char * stopReason
reason for forcing done() to be true
Definition: AsyncJob.h:69
Cbc * get() const
a temporary valid raw Cbc pointer or NULL
Definition: CbcPointer.h:162
static char server[MAXLINE]
void certDownloadingDone(SBuf &object, int status)
Called by Downloader after a certificate object downloaded.
virtual bool doneAll() const
whether positive goal has been reached
Definition: AsyncJob.cc:96
bool canceled()
Definition: AsyncCall.h:58
virtual void noteNegotiationDone(ErrorState *error)
Callback dialer API to allow PeerConnector to set the answer.
Definition: PeerConnector.h:71
C * getRaw() const
Definition: RefCount.h:74
Callback data to use with Downloader callbacks.
Definition: Downloader.h:35
void appendf(const char *fmt,...) PRINTF_FORMAT_ARG2
Append operation with printf-style arguments.
Definition: Packable.h:61
size_t HttpReply *STUB StoreEntry const KeyScope scope const HttpRequestMethod & method
Definition: stub_store.cc:112
Method method_
The Security::PeerConnector method to dial.
PeerConnectorCertDownloaderDialer(Method method, Security::PeerConnector *pc)
Definition: MemBuf.h:23
const Security::CertErrors * sslErrors
SSL [certificate validation] errors, in undefined order.
Comm::ConnectionPointer conn
peer connection (secured on success)
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:961
virtual bool initialize(Security::SessionPointer &)
int xerrno
Definition: errorpage.h:180
void retrieveNegotiatedInfo(const Security::SessionPointer &)
Extract negotiation information from TLS object.
CBDATA_NAMESPACED_CLASS_INIT(Security, PeerConnector)
virtual Security::ContextPointer getTlsContext()=0
virtual void start()
called by AsyncStart; do not call directly
Definition: AsyncJob.cc:43
#define acl_access
Definition: forward.h:44
void comm_remove_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:988
static bool Enabled(const int section, const int level)
whether debugging the given section and the given level produces output
Definition: Debug.h:75
virtual void noteNegotiationError(const int result, const int ssl_error, const int ssl_lib_error)
void negotiateSsl()
Comm::SetSelect() callback. Direct calls tickle/resume negotiations.
Ssl::ErrorDetail * detail
Definition: errorpage.h:204
Security::CertErrors * sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, Ssl::ErrorDetail *&)
Check SSL errors returned from cert validator against sslproxy_cert_error access list.
RawPointerT< Pointer > RawPointer(const char *label, const Pointer &ptr)
convenience wrapper for creating RawPointerT<> objects
Definition: Debug.h:240
Config TheConfig
Definition: Config.cc:12
const char * ErrorString(const ErrorCode code)
Definition: forward.h:96
Comm::ConnectionPointer const & serverConnection() const
mimics FwdState to minimize changes to FwdState::initiate/negotiateSsl
int commSetConnTimeout(const Comm::ConnectionPointer &conn, int timeout, AsyncCall::Pointer &callback)
Definition: comm.cc:552
void bail(ErrorState *error)
Return an error to the PeerConnector caller.
class SquidConfig Config
Definition: SquidConfig.cc:12
void Controller::create() STUB void Controller Controller nil
#define NULL
Definition: types.h:166
std::queue< SBuf > urlsOfMissingCerts
The list of URLs where missing certificates should be downloaded.
const char * rawContent() const
Definition: SBuf.cc:519
const char * dash_str
std::shared_ptr< SSL > SessionPointer
Definition: Session.h:44
time_t negotiationTimeout
the SSL connection timeout to use
void terminate()
Definition: MemBuf.cc:250

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors