]> git.ipfire.org Git - thirdparty/squid.git/blame - src/security/PeerConnector.h
Fix SQUID_YESNO 'syntax error near unexpected token' (#2117)
[thirdparty/squid.git] / src / security / PeerConnector.h
CommitLineData
a23223bf 1/*
1f7b830e 2 * Copyright (C) 1996-2025 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"
e227da8d 13#include "acl/ChecklistFiller.h"
e5ddd4ce 14#include "base/AsyncCallbacks.h"
e2849af8 15#include "base/AsyncJob.h"
2b6b1bcb 16#include "base/JobWait.h"
0e208dad 17#include "CommCalls.h"
0166128b 18#include "http/forward.h"
fcfdf7f9 19#include "security/EncryptorAnswer.h"
eba8d9bb 20#include "security/forward.h"
e227da8d 21#include "security/KeyLogger.h"
a72b6e88 22#if USE_OPENSSL
a23223bf 23#include "ssl/support.h"
a72b6e88 24#endif
32f1ca3f 25
a23223bf 26#include <iosfwd>
55369ae6 27#include <queue>
a23223bf 28
2b6b1bcb 29class Downloader;
e5ddd4ce 30class DownloaderAnswer;
d4ddb3e6
CT
31class AccessLogEntry;
32typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
a23223bf 33
a72b6e88 34namespace Security
e2849af8 35{
a23223bf 36
800967af
CT
37class IoResult;
38typedef RefCount<IoResult> IoResultPointer;
39
a23223bf 40/**
25b0ce45
CT
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.
0166128b
AJ
44 *
45 * Contains common code and interfaces of various specialized PeerConnector's,
1b091aec 46 * including peer certificate validation code.
1b091aec 47 */
e227da8d 48class PeerConnector: virtual public AsyncJob, public Acl::ChecklistFiller
a23223bf 49{
337b9aa4 50 CBDATA_INTERMEDIATE();
5c2f68b7 51
a23223bf 52public:
ce9bb79c
CT
53 typedef CbcPointer<PeerConnector> Pointer;
54
1b091aec 55 PeerConnector(const Comm::ConnectionPointer &aServerConn,
e5ddd4ce 56 const AsyncCallback<EncryptorAnswer> &,
d4ddb3e6
CT
57 const AccessLogEntryPointer &alp,
58 const time_t timeout = 0);
337b9aa4 59 ~PeerConnector() override;
25b0ce45
CT
60
61 /// hack: whether the connection requires fwdPconnPool->noteUses()
62 bool noteFwdPconnUse;
a23223bf
CT
63
64protected:
65 // AsyncJob API
337b9aa4
AR
66 void start() override;
67 bool doneAll() const override;
68 void swanSong() override;
69 const char *status() const override;
a23223bf 70
e227da8d 71 /* Acl::ChecklistFiller API */
337b9aa4 72 void fillChecklist(ACLFilledChecklist &) const override;
e227da8d 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 &params);
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
800967af
CT
92 /// Called after each negotiation step to handle the result
93 void handleNegotiationResult(const Security::IoResult &);
a23223bf 94
1b091aec
CT
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
800967af
CT
100 /// Whether TLS negotiation has been paused and not yet resumed
101 bool isSuspended() const { return static_cast<bool>(suspendedError_); }
102
212e5aee 103#if USE_OPENSSL
800967af
CT
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);
55369ae6 113
168d2b30 114 /// Start downloading procedure for the given URL.
55369ae6
AR
115 void startCertDownloading(SBuf &url);
116
168d2b30 117 /// Called by Downloader after a certificate object downloaded.
e5ddd4ce 118 void certDownloadingDone(DownloaderAnswer &);
212e5aee 119#endif
55369ae6 120
1b091aec
CT
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
83b053a0 126 virtual void noteNegotiationError(const Security::ErrorDetailPointer &);
1b091aec
CT
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
8b082ed9 131 virtual void noteNegotiationDone(ErrorState *) {}
1b091aec 132
908634e8
AR
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;
a23223bf
CT
136
137 /// mimics FwdState to minimize changes to FwdState::initiate/negotiateSsl
138 Comm::ConnectionPointer const &serverConnection() const { return serverConn; }
139
25b0ce45
CT
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();
a23223bf 145
25b0ce45 146 /// a bail(), sendSuccess() helper: sends results to the initiator
56753478
CT
147 void callBack();
148
25b0ce45
CT
149 /// a bail(), sendSuccess() helper: stops monitoring the connection
150 void disconnect();
151
2b6b1bcb 152 /// updates connection usage history before the connection is closed
2e7dea3c 153 void countFailingConnection();
2b6b1bcb 154
1b091aec
CT
155 /// If called the certificates validator will not used
156 void bypassCertValidator() {useCertValidator_ = false;}
157
36698640
CT
158 /// Called after negotiation finishes to record connection details for
159 /// logging
160 void recordNegotiationDetails();
161
2b6b1bcb
AR
162 /// convenience method to get to the answer fields
163 EncryptorAnswer &answer();
164
1b091aec
CT
165 HttpRequestPointer request; ///< peer connection trigger or cause
166 Comm::ConnectionPointer serverConn; ///< TCP connection to the peer
d4ddb3e6 167 AccessLogEntryPointer al; ///< info for the future access.log entry
e5ddd4ce
AR
168
169 /// answer destination
170 AsyncCallback<EncryptorAnswer> callback;
171
1b091aec
CT
172private:
173 PeerConnector(const PeerConnector &); // not implemented
174 PeerConnector &operator =(const PeerConnector &); // not implemented
175
a72b6e88 176#if USE_OPENSSL
800967af
CT
177 unsigned int certDownloadNestingLevel() const;
178
a23223bf 179 /// Process response from cert validator helper
e5ddd4ce 180 void sslCrtvdHandleReply(Ssl::CertValidationResponsePointer &);
a23223bf
CT
181
182 /// Check SSL errors returned from cert validator against sslproxy_cert_error access list
83b053a0 183 Security::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, ErrorDetailPointer &);
800967af
CT
184
185 bool computeMissingCertificateUrls(const Connection &);
a72b6e88 186#endif
a23223bf 187
a23223bf 188 static void NegotiateSsl(int fd, void *data);
ce9bb79c 189 void negotiateSsl();
4e526b93 190
800967af 191 /// The maximum number of missing certificates a single PeerConnector may download
4e526b93 192 static const unsigned int MaxCertsDownloads = 10;
800967af
CT
193
194 /// The maximum number of inter-dependent Downloader jobs a worker may initiate
4e526b93
CT
195 static const unsigned int MaxNestedDownloads = 3;
196
e227da8d
AR
197 /// managers logging of the being-established TLS connection secrets
198 Security::KeyLogger keyLogger;
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
800967af
CT
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_;
2b6b1bcb
AR
215
216 JobWait<Downloader> certDownloadWait; ///< waits for the missing certificate to be downloaded
1b091aec
CT
217};
218
a72b6e88 219} // namespace Security
84321458 220
0166128b 221#endif /* SQUID_SRC_SECURITY_PEERCONNECTOR_H */
f53969cc 222