]> git.ipfire.org Git - thirdparty/squid.git/blame_incremental - src/security/PeerConnector.h
Fix SQUID_YESNO 'syntax error near unexpected token' (#2117)
[thirdparty/squid.git] / src / security / PeerConnector.h
... / ...
CommitLineData
1/*
2 * Copyright (C) 1996-2025 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#ifndef SQUID_SRC_SECURITY_PEERCONNECTOR_H
10#define SQUID_SRC_SECURITY_PEERCONNECTOR_H
11
12#include "acl/Acl.h"
13#include "acl/ChecklistFiller.h"
14#include "base/AsyncCallbacks.h"
15#include "base/AsyncJob.h"
16#include "base/JobWait.h"
17#include "CommCalls.h"
18#include "http/forward.h"
19#include "security/EncryptorAnswer.h"
20#include "security/forward.h"
21#include "security/KeyLogger.h"
22#if USE_OPENSSL
23#include "ssl/support.h"
24#endif
25
26#include <iosfwd>
27#include <queue>
28
29class Downloader;
30class DownloaderAnswer;
31class AccessLogEntry;
32typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
33
34namespace Security
35{
36
37class IoResult;
38typedef RefCount<IoResult> IoResultPointer;
39
40/**
41 * Initiates encryption of a given open TCP connection to a peer or server.
42 * Despite its name does not perform any connect(2) operations. Owns the
43 * connection during TLS negotiations. The caller receives EncryptorAnswer.
44 *
45 * Contains common code and interfaces of various specialized PeerConnector's,
46 * including peer certificate validation code.
47 */
48class PeerConnector: virtual public AsyncJob, public Acl::ChecklistFiller
49{
50 CBDATA_INTERMEDIATE();
51
52public:
53 typedef CbcPointer<PeerConnector> Pointer;
54
55 PeerConnector(const Comm::ConnectionPointer &aServerConn,
56 const AsyncCallback<EncryptorAnswer> &,
57 const AccessLogEntryPointer &alp,
58 const time_t timeout = 0);
59 ~PeerConnector() override;
60
61 /// hack: whether the connection requires fwdPconnPool->noteUses()
62 bool noteFwdPconnUse;
63
64protected:
65 // AsyncJob API
66 void start() override;
67 bool doneAll() const override;
68 void swanSong() override;
69 const char *status() const override;
70
71 /* Acl::ChecklistFiller API */
72 void fillChecklist(ACLFilledChecklist &) const override;
73
74 /// The connection read timeout callback handler.
75 void commTimeoutHandler(const CommTimeoutCbParams &);
76
77 /// The comm_close callback handler.
78 void commCloseHandler(const CommCloseCbParams &params);
79
80 /// \returns true on successful TLS session initialization
81 virtual bool initialize(Security::SessionPointer &);
82
83 /// Performs a single secure connection negotiation step.
84 /// It is called multiple times until the negotiation finishes or aborts.
85 void negotiate();
86
87 /// Called after negotiation has finished. Cleans up TLS/SSL state.
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
92 /// Called after each negotiation step to handle the result
93 void handleNegotiationResult(const Security::IoResult &);
94
95 /// Called when the openSSL SSL_connect fnction request more data from
96 /// the remote SSL server. Sets the read timeout and sets the
97 /// Squid COMM_SELECT_READ handler.
98 void noteWantRead();
99
100 /// Whether TLS negotiation has been paused and not yet resumed
101 bool isSuspended() const { return static_cast<bool>(suspendedError_); }
102
103#if USE_OPENSSL
104 /// Suspends TLS negotiation to download the missing certificates
105 /// \param lastError an error to handle when resuming negotiations
106 void suspendNegotiation(const Security::IoResult &lastError);
107
108 /// Resumes TLS negotiation paused by suspendNegotiation()
109 void resumeNegotiation();
110
111 /// Either initiates fetching of missing certificates or bails with an error
112 void handleMissingCertificates(const Security::IoResult &lastError);
113
114 /// Start downloading procedure for the given URL.
115 void startCertDownloading(SBuf &url);
116
117 /// Called by Downloader after a certificate object downloaded.
118 void certDownloadingDone(DownloaderAnswer &);
119#endif
120
121 /// Called when the openSSL SSL_connect function needs to write data to
122 /// the remote SSL server. Sets the Squid COMM_SELECT_WRITE handler.
123 virtual void noteWantWrite();
124
125 /// Called when the SSL_connect function aborts with an SSL negotiation error
126 virtual void noteNegotiationError(const Security::ErrorDetailPointer &);
127
128 /// Called when the SSL negotiation to the server completed and the certificates
129 /// validated using the cert validator.
130 /// \param error if not NULL the SSL negotiation was aborted with an error
131 virtual void noteNegotiationDone(ErrorState *) {}
132
133 /// peer's security context
134 /// \returns nil if Squid is built without TLS support (XXX: Prevent PeerConnector creation in those cases instead)
135 virtual FuturePeerContext *peerContext() const = 0;
136
137 /// mimics FwdState to minimize changes to FwdState::initiate/negotiateSsl
138 Comm::ConnectionPointer const &serverConnection() const { return serverConn; }
139
140 /// sends the given error to the initiator
141 void bail(ErrorState *error);
142
143 /// sends the encrypted connection to the initiator
144 void sendSuccess();
145
146 /// a bail(), sendSuccess() helper: sends results to the initiator
147 void callBack();
148
149 /// a bail(), sendSuccess() helper: stops monitoring the connection
150 void disconnect();
151
152 /// updates connection usage history before the connection is closed
153 void countFailingConnection();
154
155 /// If called the certificates validator will not used
156 void bypassCertValidator() {useCertValidator_ = false;}
157
158 /// Called after negotiation finishes to record connection details for
159 /// logging
160 void recordNegotiationDetails();
161
162 /// convenience method to get to the answer fields
163 EncryptorAnswer &answer();
164
165 HttpRequestPointer request; ///< peer connection trigger or cause
166 Comm::ConnectionPointer serverConn; ///< TCP connection to the peer
167 AccessLogEntryPointer al; ///< info for the future access.log entry
168
169 /// answer destination
170 AsyncCallback<EncryptorAnswer> callback;
171
172private:
173 PeerConnector(const PeerConnector &); // not implemented
174 PeerConnector &operator =(const PeerConnector &); // not implemented
175
176#if USE_OPENSSL
177 unsigned int certDownloadNestingLevel() const;
178
179 /// Process response from cert validator helper
180 void sslCrtvdHandleReply(Ssl::CertValidationResponsePointer &);
181
182 /// Check SSL errors returned from cert validator against sslproxy_cert_error access list
183 Security::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, ErrorDetailPointer &);
184
185 bool computeMissingCertificateUrls(const Connection &);
186#endif
187
188 static void NegotiateSsl(int fd, void *data);
189 void negotiateSsl();
190
191 /// The maximum number of missing certificates a single PeerConnector may download
192 static const unsigned int MaxCertsDownloads = 10;
193
194 /// The maximum number of inter-dependent Downloader jobs a worker may initiate
195 static const unsigned int MaxNestedDownloads = 3;
196
197 /// managers logging of the being-established TLS connection secrets
198 Security::KeyLogger keyLogger;
199
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
204 /// The list of URLs where missing certificates should be downloaded.
205 std::queue<SBuf> urlsOfMissingCerts;
206 unsigned int certsDownloads; ///< the number of downloaded missing certificates
207
208#if USE_OPENSSL
209 /// successfully downloaded intermediate certificates (omitted by the peer)
210 Ssl::X509_STACK_Pointer downloadedCerts;
211#endif
212
213 /// outcome of the last (failed and) suspended negotiation attempt (or nil)
214 Security::IoResultPointer suspendedError_;
215
216 JobWait<Downloader> certDownloadWait; ///< waits for the missing certificate to be downloaded
217};
218
219} // namespace Security
220
221#endif /* SQUID_SRC_SECURITY_PEERCONNECTOR_H */
222