]>
Commit | Line | Data |
---|---|---|
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 | 26 | class ErrorState; |
d4ddb3e6 CT |
27 | class AccessLogEntry; |
28 | typedef RefCount<AccessLogEntry> AccessLogEntryPointer; | |
a23223bf | 29 | |
a72b6e88 | 30 | namespace Security |
e2849af8 | 31 | { |
a23223bf | 32 | |
a23223bf | 33 | /** |
25b0ce45 CT |
34 | * Initiates encryption of a given open TCP connection to a peer or server. |
35 | * Despite its name does not perform any connect(2) operations. Owns the | |
36 | * connection during TLS negotiations. The caller receives EncryptorAnswer. | |
0166128b AJ |
37 | * |
38 | * Contains common code and interfaces of various specialized PeerConnector's, | |
1b091aec | 39 | * including peer certificate validation code. |
1b091aec | 40 | */ |
a23223bf CT |
41 | class PeerConnector: virtual public AsyncJob |
42 | { | |
5c2f68b7 AJ |
43 | CBDATA_CLASS(PeerConnector); |
44 | ||
a23223bf | 45 | public: |
ce9bb79c CT |
46 | typedef CbcPointer<PeerConnector> Pointer; |
47 | ||
0166128b | 48 | /// Callback dialer API to allow PeerConnector to set the answer. |
e2849af8 A |
49 | class CbDialer |
50 | { | |
a23223bf CT |
51 | public: |
52 | virtual ~CbDialer() {} | |
53 | /// gives PeerConnector access to the in-dialer answer | |
fcfdf7f9 | 54 | virtual Security::EncryptorAnswer &answer() = 0; |
a23223bf CT |
55 | }; |
56 | ||
a23223bf | 57 | public: |
1b091aec | 58 | PeerConnector(const Comm::ConnectionPointer &aServerConn, |
d4ddb3e6 CT |
59 | AsyncCall::Pointer &aCallback, |
60 | const AccessLogEntryPointer &alp, | |
61 | const time_t timeout = 0); | |
25b0ce45 CT |
62 | virtual ~PeerConnector() = default; |
63 | ||
64 | /// hack: whether the connection requires fwdPconnPool->noteUses() | |
65 | bool noteFwdPconnUse; | |
a23223bf CT |
66 | |
67 | protected: | |
68 | // AsyncJob API | |
69 | virtual void start(); | |
70 | virtual bool doneAll() const; | |
71 | virtual void swanSong(); | |
72 | virtual const char *status() const; | |
73 | ||
25b0ce45 CT |
74 | /// The connection read timeout callback handler. |
75 | void commTimeoutHandler(const CommTimeoutCbParams &); | |
76 | ||
a23223bf CT |
77 | /// The comm_close callback handler. |
78 | void commCloseHandler(const CommCloseCbParams ¶ms); | |
79 | ||
eba8d9bb | 80 | /// \returns true on successful TLS session initialization |
0166128b | 81 | virtual bool initialize(Security::SessionPointer &); |
a23223bf CT |
82 | |
83 | /// Performs a single secure connection negotiation step. | |
2f8abb64 | 84 | /// It is called multiple times until the negotiation finishes or aborts. |
0166128b | 85 | void negotiate(); |
a23223bf | 86 | |
0166128b | 87 | /// Called after negotiation has finished. Cleans up TLS/SSL state. |
c91d4d4e CT |
88 | /// Returns false if we are now waiting for the certs validation job. |
89 | /// Otherwise, returns true, regardless of negotiation success/failure. | |
90 | bool sslFinalized(); | |
91 | ||
0166128b AJ |
92 | /// Called when the negotiation step aborted because data needs to |
93 | /// be transferred to/from server or on error. In the first case | |
a23223bf CT |
94 | /// setups the appropriate Comm::SetSelect handler. In second case |
95 | /// fill an error and report to the PeerConnector caller. | |
96 | void handleNegotiateError(const int result); | |
97 | ||
1b091aec CT |
98 | /// Called when the openSSL SSL_connect fnction request more data from |
99 | /// the remote SSL server. Sets the read timeout and sets the | |
100 | /// Squid COMM_SELECT_READ handler. | |
101 | void noteWantRead(); | |
102 | ||
212e5aee | 103 | #if USE_OPENSSL |
7b4984f7 | 104 | /// Run the certificates list sent by the SSL server and check if there |
3945c91d | 105 | /// are missing certificates. Adds to the urlOfMissingCerts list the |
7b4984f7 CT |
106 | /// URLS of missing certificates if this information provided by the |
107 | /// issued certificates with Authority Info Access extension. | |
55369ae6 AR |
108 | bool checkForMissingCertificates(); |
109 | ||
168d2b30 | 110 | /// Start downloading procedure for the given URL. |
55369ae6 AR |
111 | void startCertDownloading(SBuf &url); |
112 | ||
168d2b30 | 113 | /// Called by Downloader after a certificate object downloaded. |
55369ae6 | 114 | void certDownloadingDone(SBuf &object, int status); |
212e5aee | 115 | #endif |
55369ae6 | 116 | |
1b091aec CT |
117 | /// Called when the openSSL SSL_connect function needs to write data to |
118 | /// the remote SSL server. Sets the Squid COMM_SELECT_WRITE handler. | |
119 | virtual void noteWantWrite(); | |
120 | ||
121 | /// Called when the SSL_connect function aborts with an SSL negotiation error | |
122 | /// \param result the SSL_connect return code | |
123 | /// \param ssl_error the error code returned from the SSL_get_error function | |
124 | /// \param ssl_lib_error the error returned from the ERR_Get_Error function | |
0166128b | 125 | virtual void noteNegotiationError(const int result, const int ssl_error, const int ssl_lib_error); |
1b091aec CT |
126 | |
127 | /// Called when the SSL negotiation to the server completed and the certificates | |
128 | /// validated using the cert validator. | |
129 | /// \param error if not NULL the SSL negotiation was aborted with an error | |
130 | virtual void noteNegotiationDone(ErrorState *error) {} | |
131 | ||
b23f5f9c | 132 | /// Must implemented by the kid classes to return the TLS context object to use |
0166128b | 133 | /// for building the encryption context objects. |
b23f5f9c | 134 | virtual Security::ContextPointer getTlsContext() = 0; |
a23223bf CT |
135 | |
136 | /// mimics FwdState to minimize changes to FwdState::initiate/negotiateSsl | |
137 | Comm::ConnectionPointer const &serverConnection() const { return serverConn; } | |
138 | ||
25b0ce45 CT |
139 | /// sends the given error to the initiator |
140 | void bail(ErrorState *error); | |
141 | ||
142 | /// sends the encrypted connection to the initiator | |
143 | void sendSuccess(); | |
a23223bf | 144 | |
25b0ce45 | 145 | /// a bail(), sendSuccess() helper: sends results to the initiator |
56753478 CT |
146 | void callBack(); |
147 | ||
25b0ce45 CT |
148 | /// a bail(), sendSuccess() helper: stops monitoring the connection |
149 | void disconnect(); | |
150 | ||
1b091aec CT |
151 | /// If called the certificates validator will not used |
152 | void bypassCertValidator() {useCertValidator_ = false;} | |
153 | ||
36698640 CT |
154 | /// Called after negotiation finishes to record connection details for |
155 | /// logging | |
156 | void recordNegotiationDetails(); | |
157 | ||
1b091aec CT |
158 | HttpRequestPointer request; ///< peer connection trigger or cause |
159 | Comm::ConnectionPointer serverConn; ///< TCP connection to the peer | |
d4ddb3e6 | 160 | AccessLogEntryPointer al; ///< info for the future access.log entry |
177a824c | 161 | AsyncCall::Pointer callback; ///< we call this with the results |
1b091aec CT |
162 | private: |
163 | PeerConnector(const PeerConnector &); // not implemented | |
164 | PeerConnector &operator =(const PeerConnector &); // not implemented | |
165 | ||
a72b6e88 | 166 | #if USE_OPENSSL |
a23223bf | 167 | /// Process response from cert validator helper |
0e208dad | 168 | void sslCrtvdHandleReply(Ssl::CertValidationResponsePointer); |
a23223bf CT |
169 | |
170 | /// Check SSL errors returned from cert validator against sslproxy_cert_error access list | |
92e3827b | 171 | Security::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, Ssl::ErrorDetail *&); |
a72b6e88 | 172 | #endif |
a23223bf | 173 | |
a23223bf | 174 | static void NegotiateSsl(int fd, void *data); |
ce9bb79c | 175 | void negotiateSsl(); |
4e526b93 | 176 | |
168d2b30 | 177 | /// The maximum allowed missing certificates downloads. |
4e526b93 | 178 | static const unsigned int MaxCertsDownloads = 10; |
168d2b30 | 179 | /// The maximum allowed nested certificates downloads. |
4e526b93 CT |
180 | static const unsigned int MaxNestedDownloads = 3; |
181 | ||
1b091aec CT |
182 | AsyncCall::Pointer closeHandler; ///< we call this when the connection closed |
183 | time_t negotiationTimeout; ///< the SSL connection timeout to use | |
184 | time_t startTime; ///< when the peer connector negotiation started | |
185 | bool useCertValidator_; ///< whether the certificate validator should bypassed | |
168d2b30 | 186 | /// The list of URLs where missing certificates should be downloaded. |
55369ae6 | 187 | std::queue<SBuf> urlsOfMissingCerts; |
168d2b30 | 188 | unsigned int certsDownloads; ///< the number of downloaded missing certificates |
1b091aec CT |
189 | }; |
190 | ||
a72b6e88 | 191 | } // namespace Security |
84321458 | 192 | |
0166128b | 193 | #endif /* SQUID_SRC_SECURITY_PEERCONNECTOR_H */ |
f53969cc | 194 |