]>
Commit | Line | Data |
---|---|---|
a23223bf | 1 | /* |
bde978a6 | 2 | * Copyright (C) 1996-2015 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 | |
a23223bf CT |
9 | #ifndef SQUID_SSL_PEER_CONNECTOR_H |
10 | #define SQUID_SSL_PEER_CONNECTOR_H | |
11 | ||
20b79af2 | 12 | #include "acl/Acl.h" |
a23223bf | 13 | #include "base/AsyncCbdataCalls.h" |
e2849af8 | 14 | #include "base/AsyncJob.h" |
a23223bf CT |
15 | #include "ssl/support.h" |
16 | #include <iosfwd> | |
17 | ||
18 | class HttpRequest; | |
19 | class ErrorState; | |
20 | ||
e2849af8 A |
21 | namespace Ssl |
22 | { | |
a23223bf CT |
23 | |
24 | class ErrorDetail; | |
25 | class CertValidationResponse; | |
26 | ||
27 | /// PeerConnector results (supplied via a callback). | |
28 | /// The connection to peer was secured if and only if the error member is nil. | |
e2849af8 A |
29 | class PeerConnectorAnswer |
30 | { | |
a23223bf CT |
31 | public: |
32 | ~PeerConnectorAnswer(); ///< deletes error if it is still set | |
33 | Comm::ConnectionPointer conn; ///< peer connection (secured on success) | |
34 | ||
35 | /// answer recepients must clear the error member in order to keep its info | |
36 | /// XXX: We should refcount ErrorState instead of cbdata-protecting it. | |
37 | CbcPointer<ErrorState> error; ///< problem details (nil on success) | |
38 | }; | |
39 | ||
40 | /** | |
41 | \par | |
42 | * Connects Squid client-side to an SSL peer (cache_peer ... ssl). | |
43 | * Handles peer certificate validation. | |
44 | * Used by TunnelStateData, FwdState, and PeerPoolMgr to start talking to an | |
45 | * SSL peer. | |
46 | \par | |
47 | * The caller receives a call back with PeerConnectorAnswer. If answer.error | |
48 | * is not nil, then there was an error and the SSL connection to the SSL peer | |
49 | * was not fully established. The error object is suitable for error response | |
50 | * generation. | |
51 | \par | |
52 | * The caller must monitor the connection for closure because this | |
53 | * job will not inform the caller about such events. | |
54 | \par | |
8aec3e1b CT |
55 | * PeerConnector class curently supports a form of SSL negotiation timeout, |
56 | * which accounted only when sets the read timeout from SSL peer. | |
57 | * For a complete solution, the caller must monitor the overall connection | |
58 | * establishment timeout and close the connection on timeouts. This is probably | |
59 | * better than having dedicated (or none at all!) timeouts for peer selection, | |
60 | * DNS lookup, TCP handshake, SSL handshake, etc. Some steps may have their | |
719dc243 | 61 | * own timeout, but not all steps should be forced to have theirs. |
8aec3e1b CT |
62 | * XXX: tunnel.cc and probably other subsystems does not have an "overall |
63 | * connection establishment" timeout. We need to change their code so that they | |
64 | * start monitoring earlier and close on timeouts. This change may need to be | |
65 | * discussed on squid-dev. | |
a23223bf CT |
66 | \par |
67 | * This job never closes the connection, even on errors. If a 3rd-party | |
68 | * closes the connection, this job simply quits without informing the caller. | |
e2849af8 | 69 | */ |
a23223bf CT |
70 | class PeerConnector: virtual public AsyncJob |
71 | { | |
5c2f68b7 AJ |
72 | CBDATA_CLASS(PeerConnector); |
73 | ||
a23223bf CT |
74 | public: |
75 | /// Callback dialier API to allow PeerConnector to set the answer. | |
e2849af8 A |
76 | class CbDialer |
77 | { | |
a23223bf CT |
78 | public: |
79 | virtual ~CbDialer() {} | |
80 | /// gives PeerConnector access to the in-dialer answer | |
81 | virtual PeerConnectorAnswer &answer() = 0; | |
82 | }; | |
83 | ||
84 | typedef RefCount<HttpRequest> HttpRequestPointer; | |
85 | ||
86 | public: | |
87 | PeerConnector(HttpRequestPointer &aRequest, | |
88 | const Comm::ConnectionPointer &aServerConn, | |
93ead3fd | 89 | const Comm::ConnectionPointer &aClientConn, |
8aec3e1b | 90 | AsyncCall::Pointer &aCallback, const time_t timeout = 0); |
a23223bf CT |
91 | virtual ~PeerConnector(); |
92 | ||
93 | protected: | |
94 | // AsyncJob API | |
95 | virtual void start(); | |
96 | virtual bool doneAll() const; | |
97 | virtual void swanSong(); | |
98 | virtual const char *status() const; | |
99 | ||
100 | /// The comm_close callback handler. | |
101 | void commCloseHandler(const CommCloseCbParams ¶ms); | |
102 | ||
103 | /// Inform us that the connection is closed. Does the required clean-up. | |
104 | void connectionClosed(const char *reason); | |
105 | ||
106 | /// Sets up TCP socket-related notification callbacks if things go wrong. | |
107 | /// If socket already closed return false, else install the comm_close | |
108 | /// handler to monitor the socket. | |
109 | bool prepareSocket(); | |
110 | ||
8aec3e1b CT |
111 | /// Sets the read timeout to avoid getting stuck while reading from a |
112 | /// silent server | |
719dc243 | 113 | void setReadTimeout(); |
8aec3e1b | 114 | |
a23223bf CT |
115 | void initializeSsl(); ///< Initializes SSL state |
116 | ||
117 | /// Performs a single secure connection negotiation step. | |
118 | /// It is called multiple times untill the negotiation finish or aborted. | |
119 | void negotiateSsl(); | |
120 | ||
c91d4d4e CT |
121 | /// Called after SSL negotiations have finished. Cleans up SSL state. |
122 | /// Returns false if we are now waiting for the certs validation job. | |
123 | /// Otherwise, returns true, regardless of negotiation success/failure. | |
124 | bool sslFinalized(); | |
125 | ||
a9c2dd2f CT |
126 | /// Initiates the ssl_bump acl check in step3 SSL bump step to decide |
127 | /// about bumping, splicing or terminating the connection. | |
128 | void checkForPeekAndSplice(); | |
129 | ||
130 | /// Callback function for ssl_bump acl check in step3 SSL bump step. | |
131 | /// Handles the final bumping decision. | |
132 | void checkForPeekAndSpliceDone(Ssl::BumpMode const); | |
31855516 | 133 | |
a23223bf CT |
134 | /// Called when the SSL negotiation step aborted because data needs to |
135 | /// be transferred to/from SSL server or on error. In the first case | |
136 | /// setups the appropriate Comm::SetSelect handler. In second case | |
137 | /// fill an error and report to the PeerConnector caller. | |
138 | void handleNegotiateError(const int result); | |
139 | ||
140 | private: | |
141 | PeerConnector(const PeerConnector &); // not implemented | |
142 | PeerConnector &operator =(const PeerConnector &); // not implemented | |
143 | ||
144 | /// mimics FwdState to minimize changes to FwdState::initiate/negotiateSsl | |
145 | Comm::ConnectionPointer const &serverConnection() const { return serverConn; } | |
146 | ||
e2849af8 | 147 | void bail(ErrorState *error); ///< Return an error to the PeerConnector caller |
a23223bf CT |
148 | |
149 | /// Callback the caller class, and pass the ready to communicate secure | |
150 | /// connection or an error if PeerConnector failed. | |
151 | void callBack(); | |
152 | ||
153 | /// Process response from cert validator helper | |
154 | void sslCrtvdHandleReply(Ssl::CertValidationResponse const &); | |
155 | ||
156 | /// Check SSL errors returned from cert validator against sslproxy_cert_error access list | |
157 | Ssl::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, Ssl::ErrorDetail *&); | |
158 | ||
159 | /// Callback function called when squid receive message from cert validator helper | |
160 | static void sslCrtvdHandleReplyWrapper(void *data, Ssl::CertValidationResponse const &); | |
161 | ||
162 | /// A wrapper function for negotiateSsl for use with Comm::SetSelect | |
163 | static void NegotiateSsl(int fd, void *data); | |
164 | ||
a9c2dd2f CT |
165 | /// A wrapper function for checkForPeekAndSpliceDone for use with acl |
166 | static void cbCheckForPeekAndSpliceDone(allow_t answer, void *data); | |
7f4e9b73 | 167 | |
a23223bf CT |
168 | HttpRequestPointer request; ///< peer connection trigger or cause |
169 | Comm::ConnectionPointer serverConn; ///< TCP connection to the peer | |
93ead3fd | 170 | Comm::ConnectionPointer clientConn; ///< TCP connection to the client |
a23223bf CT |
171 | AsyncCall::Pointer callback; ///< we call this with the results |
172 | AsyncCall::Pointer closeHandler; ///< we call this when the connection closed | |
8aec3e1b CT |
173 | time_t negotiationTimeout; ///< the ssl connection timeout to use |
174 | time_t startTime; ///< when the peer connector negotiation started | |
c91d4d4e | 175 | bool splice; ///< Whether we are going to splice or not |
a23223bf CT |
176 | }; |
177 | ||
a23223bf CT |
178 | std::ostream &operator <<(std::ostream &os, const Ssl::PeerConnectorAnswer &a); |
179 | ||
84321458 CT |
180 | } // namespace Ssl |
181 | ||
a23223bf | 182 | #endif /* SQUID_PEER_CONNECTOR_H */ |
f53969cc | 183 |