]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/PeerConnector.h
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / security / PeerConnector.h
CommitLineData
a23223bf 1/*
77b1029d 2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
a23223bf 3 *
bbc27441
AJ
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.
a23223bf 7 */
bbc27441 8
0166128b
AJ
9#ifndef SQUID_SRC_SECURITY_PEERCONNECTOR_H
10#define SQUID_SRC_SECURITY_PEERCONNECTOR_H
a23223bf 11
20b79af2 12#include "acl/Acl.h"
a23223bf 13#include "base/AsyncCbdataCalls.h"
e2849af8 14#include "base/AsyncJob.h"
0e208dad 15#include "CommCalls.h"
0166128b 16#include "http/forward.h"
fcfdf7f9 17#include "security/EncryptorAnswer.h"
eba8d9bb 18#include "security/forward.h"
a72b6e88 19#if USE_OPENSSL
a23223bf 20#include "ssl/support.h"
a72b6e88 21#endif
32f1ca3f 22
a23223bf 23#include <iosfwd>
55369ae6 24#include <queue>
a23223bf 25
a23223bf 26class ErrorState;
d4ddb3e6
CT
27class AccessLogEntry;
28typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
a23223bf 29
a72b6e88 30namespace Security
e2849af8 31{
a23223bf 32
a23223bf 33/**
0166128b
AJ
34 * Initiates encryption on a connection to peers or servers.
35 * Despite its name does not perform any connect(2) operations.
36 *
37 * Contains common code and interfaces of various specialized PeerConnector's,
1b091aec 38 * including peer certificate validation code.
a23223bf 39 \par
fcfdf7f9 40 * The caller receives a call back with Security::EncryptorAnswer. If answer.error
0166128b 41 * is not nil, then there was an error and the encryption to the peer or server
a23223bf
CT
42 * was not fully established. The error object is suitable for error response
43 * generation.
44 \par
45 * The caller must monitor the connection for closure because this
46 * job will not inform the caller about such events.
47 \par
0166128b
AJ
48 * PeerConnector class currently supports a form of TLS negotiation timeout,
49 * which is accounted only when sets the read timeout from encrypted peers/servers.
8aec3e1b
CT
50 * For a complete solution, the caller must monitor the overall connection
51 * establishment timeout and close the connection on timeouts. This is probably
52 * better than having dedicated (or none at all!) timeouts for peer selection,
53 * DNS lookup, TCP handshake, SSL handshake, etc. Some steps may have their
719dc243 54 * own timeout, but not all steps should be forced to have theirs.
0166128b 55 * XXX: tunnel.cc and probably other subsystems do not have an "overall
8aec3e1b
CT
56 * connection establishment" timeout. We need to change their code so that they
57 * start monitoring earlier and close on timeouts. This change may need to be
58 * discussed on squid-dev.
a23223bf
CT
59 \par
60 * This job never closes the connection, even on errors. If a 3rd-party
61 * closes the connection, this job simply quits without informing the caller.
1b091aec 62 */
a23223bf
CT
63class PeerConnector: virtual public AsyncJob
64{
5c2f68b7
AJ
65 CBDATA_CLASS(PeerConnector);
66
a23223bf 67public:
ce9bb79c
CT
68 typedef CbcPointer<PeerConnector> Pointer;
69
0166128b 70 /// Callback dialer API to allow PeerConnector to set the answer.
e2849af8
A
71 class CbDialer
72 {
a23223bf
CT
73 public:
74 virtual ~CbDialer() {}
75 /// gives PeerConnector access to the in-dialer answer
fcfdf7f9 76 virtual Security::EncryptorAnswer &answer() = 0;
a23223bf
CT
77 };
78
a23223bf 79public:
1b091aec 80 PeerConnector(const Comm::ConnectionPointer &aServerConn,
d4ddb3e6
CT
81 AsyncCall::Pointer &aCallback,
82 const AccessLogEntryPointer &alp,
83 const time_t timeout = 0);
a23223bf
CT
84 virtual ~PeerConnector();
85
86protected:
87 // AsyncJob API
88 virtual void start();
89 virtual bool doneAll() const;
90 virtual void swanSong();
91 virtual const char *status() const;
92
93 /// The comm_close callback handler.
94 void commCloseHandler(const CommCloseCbParams &params);
95
96 /// Inform us that the connection is closed. Does the required clean-up.
97 void connectionClosed(const char *reason);
98
99 /// Sets up TCP socket-related notification callbacks if things go wrong.
100 /// If socket already closed return false, else install the comm_close
101 /// handler to monitor the socket.
102 bool prepareSocket();
103
eba8d9bb 104 /// \returns true on successful TLS session initialization
0166128b 105 virtual bool initialize(Security::SessionPointer &);
a23223bf
CT
106
107 /// Performs a single secure connection negotiation step.
0166128b
AJ
108 /// It is called multiple times untill the negotiation finishes or aborts.
109 void negotiate();
a23223bf 110
0166128b 111 /// Called after negotiation has finished. Cleans up TLS/SSL state.
c91d4d4e
CT
112 /// Returns false if we are now waiting for the certs validation job.
113 /// Otherwise, returns true, regardless of negotiation success/failure.
114 bool sslFinalized();
115
0166128b
AJ
116 /// Called when the negotiation step aborted because data needs to
117 /// be transferred to/from server or on error. In the first case
a23223bf
CT
118 /// setups the appropriate Comm::SetSelect handler. In second case
119 /// fill an error and report to the PeerConnector caller.
120 void handleNegotiateError(const int result);
121
1b091aec
CT
122 /// Called when the openSSL SSL_connect fnction request more data from
123 /// the remote SSL server. Sets the read timeout and sets the
124 /// Squid COMM_SELECT_READ handler.
125 void noteWantRead();
126
212e5aee 127#if USE_OPENSSL
7b4984f7 128 /// Run the certificates list sent by the SSL server and check if there
3945c91d 129 /// are missing certificates. Adds to the urlOfMissingCerts list the
7b4984f7
CT
130 /// URLS of missing certificates if this information provided by the
131 /// issued certificates with Authority Info Access extension.
55369ae6
AR
132 bool checkForMissingCertificates();
133
168d2b30 134 /// Start downloading procedure for the given URL.
55369ae6
AR
135 void startCertDownloading(SBuf &url);
136
168d2b30 137 /// Called by Downloader after a certificate object downloaded.
55369ae6 138 void certDownloadingDone(SBuf &object, int status);
212e5aee 139#endif
55369ae6 140
1b091aec
CT
141 /// Called when the openSSL SSL_connect function needs to write data to
142 /// the remote SSL server. Sets the Squid COMM_SELECT_WRITE handler.
143 virtual void noteWantWrite();
144
145 /// Called when the SSL_connect function aborts with an SSL negotiation error
146 /// \param result the SSL_connect return code
147 /// \param ssl_error the error code returned from the SSL_get_error function
148 /// \param ssl_lib_error the error returned from the ERR_Get_Error function
0166128b 149 virtual void noteNegotiationError(const int result, const int ssl_error, const int ssl_lib_error);
1b091aec
CT
150
151 /// Called when the SSL negotiation to the server completed and the certificates
152 /// validated using the cert validator.
153 /// \param error if not NULL the SSL negotiation was aborted with an error
154 virtual void noteNegotiationDone(ErrorState *error) {}
155
b23f5f9c 156 /// Must implemented by the kid classes to return the TLS context object to use
0166128b 157 /// for building the encryption context objects.
b23f5f9c 158 virtual Security::ContextPointer getTlsContext() = 0;
a23223bf
CT
159
160 /// mimics FwdState to minimize changes to FwdState::initiate/negotiateSsl
161 Comm::ConnectionPointer const &serverConnection() const { return serverConn; }
162
e2849af8 163 void bail(ErrorState *error); ///< Return an error to the PeerConnector caller
a23223bf 164
56753478
CT
165 /// Callback the caller class, and pass the ready to communicate secure
166 /// connection or an error if PeerConnector failed.
167 void callBack();
168
1b091aec
CT
169 /// If called the certificates validator will not used
170 void bypassCertValidator() {useCertValidator_ = false;}
171
36698640
CT
172 /// Called after negotiation finishes to record connection details for
173 /// logging
174 void recordNegotiationDetails();
175
1b091aec
CT
176 HttpRequestPointer request; ///< peer connection trigger or cause
177 Comm::ConnectionPointer serverConn; ///< TCP connection to the peer
d4ddb3e6 178 AccessLogEntryPointer al; ///< info for the future access.log entry
177a824c 179 AsyncCall::Pointer callback; ///< we call this with the results
1b091aec
CT
180private:
181 PeerConnector(const PeerConnector &); // not implemented
182 PeerConnector &operator =(const PeerConnector &); // not implemented
183
a72b6e88 184#if USE_OPENSSL
a23223bf 185 /// Process response from cert validator helper
0e208dad 186 void sslCrtvdHandleReply(Ssl::CertValidationResponsePointer);
a23223bf
CT
187
188 /// Check SSL errors returned from cert validator against sslproxy_cert_error access list
92e3827b 189 Security::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, Ssl::ErrorDetail *&);
a72b6e88 190#endif
a23223bf 191
a23223bf 192 static void NegotiateSsl(int fd, void *data);
ce9bb79c 193 void negotiateSsl();
4e526b93 194
168d2b30 195 /// The maximum allowed missing certificates downloads.
4e526b93 196 static const unsigned int MaxCertsDownloads = 10;
168d2b30 197 /// The maximum allowed nested certificates downloads.
4e526b93
CT
198 static const unsigned int MaxNestedDownloads = 3;
199
1b091aec
CT
200 AsyncCall::Pointer closeHandler; ///< we call this when the connection closed
201 time_t negotiationTimeout; ///< the SSL connection timeout to use
202 time_t startTime; ///< when the peer connector negotiation started
203 bool useCertValidator_; ///< whether the certificate validator should bypassed
168d2b30 204 /// The list of URLs where missing certificates should be downloaded.
55369ae6 205 std::queue<SBuf> urlsOfMissingCerts;
168d2b30 206 unsigned int certsDownloads; ///< the number of downloaded missing certificates
1b091aec
CT
207};
208
a72b6e88 209} // namespace Security
84321458 210
0166128b 211#endif /* SQUID_SRC_SECURITY_PEERCONNECTOR_H */
f53969cc 212