]>
Commit | Line | Data |
---|---|---|
e227da8d | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
e227da8d AR |
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 | #include "squid.h" | |
10 | #include "acl/ChecklistFiller.h" | |
11 | #include "acl/FilledChecklist.h" | |
12 | #include "MasterXaction.h" | |
13 | #include "security/CommunicationSecrets.h" | |
14 | #include "security/KeyLog.h" | |
15 | #include "security/KeyLogger.h" | |
16 | #include "security/Session.h" | |
17 | #include "SquidConfig.h" | |
18 | ||
19 | #include <ostream> | |
20 | ||
21 | void | |
22 | Security::KeyLogger::maybeLog(const Connection &sconn, const Acl::ChecklistFiller &caller) | |
23 | { | |
24 | if (!shouldLog(caller)) { | |
25 | done_ = true; // do not try again | |
26 | return; | |
27 | } | |
28 | ||
29 | Security::CommunicationSecrets newSecrets(sconn); | |
30 | if (!secrets.learnNew(newSecrets)) // no new secrets extracted | |
31 | return; // will retry extracting secrets during the next checkpoint() | |
32 | ||
33 | // SSLKEYLOGFILE consumers probably discard incomplete record lines. To | |
34 | // avoid providing incomplete/unusable info in _each_ record, we always | |
35 | // record all the learned secrets, including any previously recorded ones. | |
36 | Config.Log.tlsKeys->record(secrets); | |
37 | ||
38 | // optimization: here, we assume learned secrets do not change | |
39 | if (secrets.gotAll()) | |
40 | done_ = true; | |
41 | } | |
42 | ||
43 | bool | |
44 | Security::KeyLogger::shouldLog(const Acl::ChecklistFiller &caller) const | |
45 | { | |
46 | // First, always check preconditions that may change, becoming unmet/false | |
47 | ||
48 | if (!Config.Log.tlsKeys) | |
49 | return false; // default: admin does not want us to log (implicitly) | |
50 | ||
51 | if (!Config.Log.tlsKeys->canLog()) { | |
52 | debugs(33, 3, "no: problems with the logging module"); | |
53 | return false; | |
54 | } | |
55 | ||
56 | if (done_) { // paranoid: we should not even be called w/o transaction | |
57 | debugs(33, 2, "BUG: caller problems or logged earlier"); | |
58 | return false; | |
59 | } | |
60 | ||
61 | // Second, do the ACL-related checks (that are presumed to be stable) | |
62 | ||
63 | // We can keep wanted_ a boolean (instead of a tri-state) member because if | |
64 | // shouldLog() returns false, there will be no further shouldLog() calls. | |
65 | if (wanted_) | |
66 | return true; // was allowed to log earlier | |
67 | ||
68 | const auto acls = Config.Log.tlsKeys->aclList; | |
69 | if (!acls) { | |
70 | debugs(33, 7, "yes: no ACLs"); | |
71 | wanted_ = true; | |
72 | return true; | |
73 | } | |
74 | ||
75 | ACLFilledChecklist checklist; | |
76 | caller.fillChecklist(checklist); | |
77 | if (!checklist.fastCheck(acls).allowed()) { | |
78 | debugs(33, 4, "no: admin does not want us to log (explicitly)"); | |
79 | return false; | |
80 | } | |
81 | ||
82 | debugs(33, 5, "yes: ACLs matched"); | |
83 | wanted_ = true; | |
84 | return true; | |
85 | } | |
86 |