| Directory: | ./ |
|---|---|
| File: | pdserv/src/Session.cpp |
| Date: | 2025-11-02 04:09:49 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 214 | 292 | 73.3% |
| Branches: | 274 | 851 | 32.2% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright 2010 Richard Hacker (lerichi at gmx dot net) | ||
| 4 | * | ||
| 5 | * This file is part of the pdserv library. | ||
| 6 | * | ||
| 7 | * The pdserv library is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU Lesser General Public License as published | ||
| 9 | * by the Free Software Foundation, either version 3 of the License, or (at | ||
| 10 | * your option) any later version. | ||
| 11 | * | ||
| 12 | * The pdserv library is distributed in the hope that it will be useful, but | ||
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
| 15 | * License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public License | ||
| 18 | * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | * | ||
| 20 | ****************************************************************************/ | ||
| 21 | |||
| 22 | #include "Session.h" | ||
| 23 | #include "Main.h" | ||
| 24 | #include "Debug.h" | ||
| 25 | |||
| 26 | #include <sasl/saslutil.h> | ||
| 27 | #include <cerrno> | ||
| 28 | #include <cstring> // strerror() | ||
| 29 | #include <log4cplus/logger.h> | ||
| 30 | #include <log4cplus/loggingmacros.h> | ||
| 31 | |||
| 32 | #ifdef GNUTLS_FOUND | ||
| 33 | # include <gnutls/x509.h> | ||
| 34 | # include "TLS.h" | ||
| 35 | #endif | ||
| 36 | |||
| 37 | using namespace PdServ; | ||
| 38 | |||
| 39 | // Initialize SASL server. There are no callbacks, as well as an | ||
| 40 | // empty name so that no default configuration file is searched for | ||
| 41 | 3 | const int Session::saslServerInit = sasl_server_init(NULL, NULL); | |
| 42 | |||
| 43 | ///////////////////////////////////////////////////////////////////////////// | ||
| 44 | 148 | Session::Session(const Main *m, log4cplus::Logger& log, size_t bufsize) | |
| 45 | 148 | : main(m), log(log) | |
| 46 | { | ||
| 47 | 148 | conn = 0; | |
| 48 | 148 | p_eof = false; | |
| 49 | 148 | p_loggedIn = false; | |
| 50 | |||
| 51 |
1/2✓ Branch 24 taken 148 times.
✗ Branch 25 not taken.
|
148 | main->gettime(&connectedTime); |
| 52 |
1/2✓ Branch 24 taken 148 times.
✗ Branch 25 not taken.
|
148 | main->prepare(this); |
| 53 | |||
| 54 |
1/2✓ Branch 1 taken 148 times.
✗ Branch 2 not taken.
|
148 | char* buf = new char[bufsize]; |
| 55 |
1/2✓ Branch 4 taken 148 times.
✗ Branch 5 not taken.
|
148 | setp(buf, buf + bufsize); |
| 56 | 148 | } | |
| 57 | |||
| 58 | ///////////////////////////////////////////////////////////////////////////// | ||
| 59 | 296 | Session::~Session() | |
| 60 | { | ||
| 61 | 148 | saslDispose(); | |
| 62 | |||
| 63 | 148 | main->cleanup(this); | |
| 64 |
1/2✓ Branch 4 taken 148 times.
✗ Branch 5 not taken.
|
148 | delete[] pbase(); |
| 65 | 148 | } | |
| 66 | |||
| 67 | ///////////////////////////////////////////////////////////////////////////// | ||
| 68 | 30 | bool Session::saslInit() | |
| 69 | { | ||
| 70 |
1/2✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
|
60 | std::string remoteip = peerAddr(';'); |
| 71 |
1/2✓ Branch 4 taken 30 times.
✗ Branch 5 not taken.
|
60 | std::string localip = localAddr(';'); |
| 72 | |||
| 73 |
9/18✓ Branch 8 taken 30 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 30 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 30 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 30 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 30 times.
✗ Branch 21 not taken.
✓ Branch 23 taken 30 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 30 times.
✗ Branch 27 not taken.
✓ Branch 30 taken 30 times.
✗ Branch 31 not taken.
✓ Branch 34 taken 30 times.
✗ Branch 35 not taken.
|
30 | LOG4CPLUS_DEBUG(log, |
| 74 | LOG4CPLUS_TEXT("Creating new login session for remoteip=") | ||
| 75 | << LOG4CPLUS_STRING_TO_TSTRING(remoteip) | ||
| 76 | << LOG4CPLUS_TEXT(" localip=") | ||
| 77 | << LOG4CPLUS_STRING_TO_TSTRING(localip)); | ||
| 78 | |||
| 79 | // Make sure sasl_server_init() was successful | ||
| 80 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (saslServerInit != SASL_OK) { |
| 81 | ✗ | LOG4CPLUS_ERROR(log, | |
| 82 | LOG4CPLUS_TEXT("Could not initialize SASL server: ") | ||
| 83 | << LOG4CPLUS_C_STR_TO_TSTRING( | ||
| 84 | sasl_errstring(saslServerInit, NULL, NULL))); | ||
| 85 | ✗ | return true; | |
| 86 | } | ||
| 87 | |||
| 88 | // Setup callbacks. Only use SASL_CB_GETOPT | ||
| 89 | typedef int (*cb_t)(void); | ||
| 90 | static const sasl_callback_t _cb[CB_SIZE] = { | ||
| 91 | {SASL_CB_LOG, cb_t((void*)sasl_log), 0}, | ||
| 92 | {SASL_CB_GETOPT, cb_t((void*)sasl_getopt), 0}, | ||
| 93 | {SASL_CB_LIST_END, 0, 0}, | ||
| 94 | }; | ||
| 95 |
2/2✓ Branch 0 taken 60 times.
✓ Branch 1 taken 30 times.
|
90 | for (size_t i = 0; i < CB_SIZE-1; ++i) { |
| 96 | 60 | sasl_callbacks[i] = _cb[i]; | |
| 97 | 60 | sasl_callbacks[i].context = this; | |
| 98 | } | ||
| 99 | 30 | sasl_callbacks[0].context = const_cast<log4cplus::Logger*>(&log); | |
| 100 | 30 | const std::string default_realm = | |
| 101 |
4/8✓ Branch 15 taken 30 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 30 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 30 times.
✗ Branch 22 not taken.
✓ Branch 27 taken 30 times.
✗ Branch 28 not taken.
|
60 | main->config("access")["sasl"]["default_realm"].toString(); |
| 102 | |||
| 103 | 30 | const std::string service_name = | |
| 104 |
5/10✓ Branch 15 taken 30 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 30 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 30 times.
✗ Branch 22 not taken.
✓ Branch 27 taken 30 times.
✗ Branch 28 not taken.
✓ Branch 31 taken 30 times.
✗ Branch 32 not taken.
|
60 | main->config("access")["sasl"]["service_name"].toString("pdserv"); |
| 105 | |||
| 106 | // Create a new login session | ||
| 107 |
2/2✓ Branch 2 taken 2 times.
✓ Branch 3 taken 28 times.
|
60 | int result = sasl_server_new(service_name.c_str(), |
| 108 | NULL, /* serverFQDN; null = use gethostname() */ | ||
| 109 | /* user realm, null = use gethostname() */ | ||
| 110 | 30 | default_realm.empty() ? nullptr : default_realm.c_str(), | |
| 111 | localip.c_str(), /* Local IP */ | ||
| 112 | remoteip.c_str(), /* Remote IP */ | ||
| 113 | sasl_callbacks, | ||
| 114 | SASL_SUCCESS_DATA, | ||
| 115 |
1/2✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
|
30 | &conn); |
| 116 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
|
30 | if (result != SASL_OK) { |
| 117 | ✗ | LOG4CPLUS_ERROR(log, | |
| 118 | LOG4CPLUS_TEXT("Could not create new SASL server instance: ") | ||
| 119 | << LOG4CPLUS_C_STR_TO_TSTRING(sasl_errstring(result,0,0))); | ||
| 120 | ✗ | return true; | |
| 121 | } | ||
| 122 | |||
| 123 | 30 | return false; | |
| 124 | } | ||
| 125 | |||
| 126 | ///////////////////////////////////////////////////////////////////////////// | ||
| 127 | 32 | const char* Session::saslMechanisms() | |
| 128 | { | ||
| 129 |
5/8✓ Branch 3 taken 30 times.
✓ Branch 4 taken 2 times.
✓ Branch 9 taken 30 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 30 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 32 times.
|
32 | if (!conn and saslInit()) |
| 130 | ✗ | return 0; | |
| 131 | |||
| 132 | // Send the mechanisms back. | ||
| 133 | // This is a space separated list of words, no prefix or suffix | ||
| 134 | 32 | const char* mechanisms; | |
| 135 | 32 | int result = sasl_listmech(conn, | |
| 136 | NULL, // user | ||
| 137 | NULL, // prefix | ||
| 138 | NULL, // space | ||
| 139 | NULL, // suffix | ||
| 140 | &mechanisms, | ||
| 141 | NULL, // plen | ||
| 142 |
1/2✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
|
32 | NULL); // pcount |
| 143 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
|
32 | if (SASL_OK != result) { |
| 144 | ✗ | LOG4CPLUS_ERROR(log, | |
| 145 | LOG4CPLUS_TEXT("Could not create new SASL server instance: ") | ||
| 146 | << LOG4CPLUS_C_STR_TO_TSTRING(sasl_errstring(result,0,0))); | ||
| 147 | ✗ | return NULL; | |
| 148 | } | ||
| 149 |
8/16✓ Branch 8 taken 32 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 32 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 32 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 32 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 32 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 32 times.
✗ Branch 28 not taken.
✓ Branch 35 taken 32 times.
✗ Branch 36 not taken.
✓ Branch 39 taken 32 times.
✗ Branch 40 not taken.
|
32 | LOG4CPLUS_DEBUG(log, |
| 150 | LOG4CPLUS_TEXT("Available SASL authentication mechanisms: ") | ||
| 151 | << LOG4CPLUS_C_STR_TO_TSTRING(mechanisms)); | ||
| 152 | |||
| 153 | 32 | return mechanisms; | |
| 154 | } | ||
| 155 | |||
| 156 | ///////////////////////////////////////////////////////////////////////////// | ||
| 157 | 149 | void Session::saslDispose() | |
| 158 | { | ||
| 159 | 149 | sasl_dispose(&conn); | |
| 160 | 149 | p_loggedIn = false; | |
| 161 | 149 | conn = 0; | |
| 162 | 149 | } | |
| 163 | |||
| 164 | ///////////////////////////////////////////////////////////////////////////// | ||
| 165 | 59 | bool Session::saslProcess( | |
| 166 | const char* mech, const char* response, const std::string** serverout) | ||
| 167 | { | ||
| 168 | int result; | ||
| 169 | 59 | const char* out; | |
| 170 | 59 | unsigned int outlen; | |
| 171 | |||
| 172 |
3/4✓ Branch 0 taken 28 times.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
|
59 | unsigned int inlen = response ? strlen(response) : 0; |
| 173 | 59 | unsigned int buflen = inlen/4*3 + 1; | |
| 174 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
|
59 | char clientout[buflen]; |
| 175 | 59 | unsigned int clientoutlen; | |
| 176 | |||
| 177 | 59 | *serverout = NULL; | |
| 178 | |||
| 179 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 59 times.
|
59 | if (!conn) { |
| 180 | ✗ | p_loggedIn = false; | |
| 181 | |||
| 182 | ✗ | if (saslInit()) | |
| 183 | ✗ | return false; | |
| 184 | } | ||
| 185 | |||
| 186 | // First decode client base64 coded response | ||
| 187 |
1/2✓ Branch 1 taken 59 times.
✗ Branch 2 not taken.
|
59 | result = sasl_decode64(response, inlen, clientout, buflen, &clientoutlen); |
| 188 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
|
59 | if (SASL_OK != result) { |
| 189 | ✗ | LOG4CPLUS_ERROR(log, | |
| 190 | LOG4CPLUS_TEXT("Could not decode client base64 string: ") | ||
| 191 | << LOG4CPLUS_C_STR_TO_TSTRING(sasl_errstring(result, 0, 0))); | ||
| 192 | ✗ | return false; | |
| 193 | } | ||
| 194 | |||
| 195 | 59 | if (clientoutlen) | |
| 196 | LOG4CPLUS_TRACE(log, | ||
| 197 | LOG4CPLUS_TEXT("SASL: Receive client reply: ") | ||
| 198 | << LOG4CPLUS_STRING_TO_TSTRING( | ||
| 199 | std::string(clientout,clientoutlen))); | ||
| 200 | |||
| 201 | // If mech is not null, this is the first step in authentication | ||
| 202 | // otherwise it is another step | ||
| 203 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 28 times.
|
59 | if (mech) { |
| 204 |
8/16✓ Branch 8 taken 31 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 31 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 31 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 31 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 31 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 31 times.
✗ Branch 28 not taken.
✓ Branch 35 taken 31 times.
✗ Branch 36 not taken.
✓ Branch 39 taken 31 times.
✗ Branch 40 not taken.
|
31 | LOG4CPLUS_DEBUG(log, |
| 205 | LOG4CPLUS_TEXT("Login: using mechanism ") | ||
| 206 | << LOG4CPLUS_C_STR_TO_TSTRING(mech)); | ||
| 207 |
2/4✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✓ Branch 6 taken 31 times.
✗ Branch 7 not taken.
|
31 | result = sasl_server_start(conn, mech, |
| 208 | response ? clientout : 0, clientoutlen, | ||
| 209 | &out, &outlen); | ||
| 210 | } | ||
| 211 | else { | ||
| 212 |
1/2✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
|
28 | result = sasl_server_step(conn, |
| 213 | clientout, clientoutlen, | ||
| 214 | &out, &outlen); | ||
| 215 | } | ||
| 216 | |||
| 217 |
11/22✓ Branch 8 taken 59 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 59 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 59 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 59 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 59 times.
✗ Branch 24 not taken.
✓ Branch 26 taken 59 times.
✗ Branch 27 not taken.
✓ Branch 32 taken 59 times.
✗ Branch 33 not taken.
✓ Branch 36 taken 59 times.
✗ Branch 37 not taken.
✓ Branch 42 taken 59 times.
✗ Branch 43 not taken.
✓ Branch 46 taken 59 times.
✗ Branch 47 not taken.
✓ Branch 50 taken 59 times.
✗ Branch 51 not taken.
|
59 | LOG4CPLUS_DEBUG(log, |
| 218 | LOG4CPLUS_TEXT("Login: result ") | ||
| 219 | << result << ' ' << (void*)out << ' ' << outlen); | ||
| 220 | |||
| 221 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 35 times.
|
59 | if (result == SASL_OK) { |
| 222 | 24 | const char* str; | |
| 223 | 24 | const void** strp = (const void**)&str; | |
| 224 | |||
| 225 | const char* userName = | ||
| 226 |
2/4✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
|
48 | (SASL_OK == sasl_getprop(conn, SASL_USERNAME, strp) and str) |
| 227 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
48 | ? str : "unknown_user"; |
| 228 | |||
| 229 |
8/16✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 24 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 24 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 24 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 24 times.
✗ Branch 28 not taken.
✓ Branch 35 taken 24 times.
✗ Branch 36 not taken.
✓ Branch 39 taken 24 times.
✗ Branch 40 not taken.
|
24 | LOG4CPLUS_INFO(log, |
| 230 | LOG4CPLUS_TEXT("Successfully logged in ") | ||
| 231 | << LOG4CPLUS_C_STR_TO_TSTRING(userName)); | ||
| 232 | |||
| 233 |
2/4✓ Branch 7 taken 24 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
|
24 | if (log.isEnabledFor(log4cplus::DEBUG_LOG_LEVEL)) { |
| 234 |
1/2✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
48 | std::ostringstream os; |
| 235 | |||
| 236 |
4/8✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 11 not taken.
|
24 | if (SASL_OK == sasl_getprop(conn, SASL_AUTHUSER, strp) and str) |
| 237 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | os << " authname=" << str; |
| 238 | |||
| 239 |
4/8✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 24 times.
✗ Branch 11 not taken.
|
24 | if (SASL_OK == sasl_getprop(conn, SASL_MECHNAME, strp) and str) |
| 240 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | os << " mechanism=" << str; |
| 241 | |||
| 242 |
3/4✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 23 times.
✓ Branch 7 taken 1 times.
|
48 | if (SASL_OK == sasl_getprop(conn, SASL_DEFUSERREALM, strp) |
| 243 |
3/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 1 times.
|
24 | and str) |
| 244 |
2/4✓ Branch 1 taken 23 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 23 times.
✗ Branch 5 not taken.
|
23 | os << " realm=" << str; |
| 245 | |||
| 246 |
2/4✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
|
48 | if (SASL_OK == sasl_getprop(conn, SASL_IPREMOTEPORT, strp) |
| 247 |
2/4✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
24 | and str) |
| 248 |
2/4✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
|
24 | os << " remoteip=" << str; |
| 249 | |||
| 250 |
1/2✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
|
48 | log.forcedLog(log4cplus::DEBUG_LOG_LEVEL, |
| 251 |
1/2✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
|
48 | LOG4CPLUS_STRING_TO_TSTRING(os.str())); |
| 252 | } | ||
| 253 | |||
| 254 | 24 | p_loggedIn = true; | |
| 255 | } | ||
| 256 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 31 times.
|
35 | else if (result != SASL_CONTINUE) { |
| 257 | 4 | const char* str; | |
| 258 | 4 | const void** sptr = (const void**)&str; | |
| 259 | |||
| 260 | const char* userName = | ||
| 261 |
2/4✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
8 | (SASL_OK == sasl_getprop(conn, SASL_USERNAME, sptr) and str) |
| 262 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
8 | ? str : "unknown_user"; |
| 263 | |||
| 264 | const char* authSrc = | ||
| 265 |
2/4✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
8 | (SASL_OK == sasl_getprop(conn, SASL_AUTHSOURCE, sptr) and str) |
| 266 |
1/2✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
|
8 | ? str : "unknown"; |
| 267 | |||
| 268 |
15/30✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 4 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 4 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 4 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 4 times.
✗ Branch 28 not taken.
✓ Branch 30 taken 4 times.
✗ Branch 31 not taken.
✓ Branch 36 taken 4 times.
✗ Branch 37 not taken.
✓ Branch 40 taken 4 times.
✗ Branch 41 not taken.
✓ Branch 43 taken 4 times.
✗ Branch 44 not taken.
✓ Branch 52 taken 4 times.
✗ Branch 53 not taken.
✓ Branch 55 taken 4 times.
✗ Branch 56 not taken.
✓ Branch 59 taken 4 times.
✗ Branch 60 not taken.
✓ Branch 75 taken 4 times.
✗ Branch 76 not taken.
✓ Branch 79 taken 4 times.
✗ Branch 80 not taken.
|
4 | LOG4CPLUS_ERROR(log, |
| 269 | LOG4CPLUS_TEXT("Login failed for user ") | ||
| 270 | << LOG4CPLUS_C_STR_TO_TSTRING(userName) | ||
| 271 | << LOG4CPLUS_TEXT(" using ") | ||
| 272 | << LOG4CPLUS_C_STR_TO_TSTRING(authSrc) | ||
| 273 | << LOG4CPLUS_TEXT(": ") | ||
| 274 | << LOG4CPLUS_C_STR_TO_TSTRING(sasl_errdetail(conn))); | ||
| 275 | 4 | return false; | |
| 276 | } | ||
| 277 | |||
| 278 |
2/2✓ Branch 0 taken 31 times.
✓ Branch 1 taken 24 times.
|
55 | if (outlen) { |
| 279 | 31 | buflen = (outlen+2)/3*4 + 1; | |
| 280 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
|
31 | char outbuf[buflen]; |
| 281 |
1/2✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
|
31 | int rv = sasl_encode64(out, outlen, outbuf, buflen, &buflen); |
| 282 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
|
31 | if (rv != SASL_OK) { |
| 283 | ✗ | LOG4CPLUS_ERROR(log, | |
| 284 | LOG4CPLUS_TEXT("Could not base64-encode string: ") | ||
| 285 | << LOG4CPLUS_C_STR_TO_TSTRING(sasl_errstring(rv,0,0))); | ||
| 286 | ✗ | return false; | |
| 287 | } | ||
| 288 |
1/2✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
|
31 | sasl_reply.assign(outbuf, buflen); |
| 289 | 31 | *serverout = &sasl_reply; | |
| 290 | LOG4CPLUS_TRACE(log, | ||
| 291 | LOG4CPLUS_TEXT("SASL: Sending challenge ") | ||
| 292 | 31 | << LOG4CPLUS_STRING_TO_TSTRING(std::string(out,outlen))); | |
| 293 | } | ||
| 294 | |||
| 295 | 114 | return result == SASL_OK; | |
| 296 | } | ||
| 297 | |||
| 298 | /////////////////////////////////////////////////////////////////////////// | ||
| 299 | // man: sasl_log_t | ||
| 300 | 3 | int Session::sasl_log(void *context, int level, | |
| 301 | const char *message) | ||
| 302 | { | ||
| 303 | log4cplus::LogLevel log4cpluslevel; | ||
| 304 |
1/7✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
3 | switch (level) { |
| 305 | ✗ | case SASL_LOG_NONE: /* don't log anything */ | |
| 306 | ✗ | log4cpluslevel = log4cplus::OFF_LOG_LEVEL; | |
| 307 | ✗ | break; | |
| 308 | |||
| 309 | ✗ | case SASL_LOG_ERR: /* log unusual errors (default) */ | |
| 310 | ✗ | log4cpluslevel = log4cplus::FATAL_LOG_LEVEL; | |
| 311 | ✗ | break; | |
| 312 | |||
| 313 | 3 | case SASL_LOG_FAIL: /* log all authentication failures */ | |
| 314 | 3 | log4cpluslevel = log4cplus::ERROR_LOG_LEVEL; | |
| 315 | 3 | break; | |
| 316 | |||
| 317 | ✗ | case SASL_LOG_WARN: /* log non-fatal warnings */ | |
| 318 | ✗ | log4cpluslevel = log4cplus::WARN_LOG_LEVEL; | |
| 319 | ✗ | break; | |
| 320 | |||
| 321 | ✗ | case SASL_LOG_NOTE: /* more verbose than LOG_WARN */ | |
| 322 | ✗ | log4cpluslevel = log4cplus::INFO_LOG_LEVEL; | |
| 323 | ✗ | break; | |
| 324 | |||
| 325 | ✗ | case SASL_LOG_DEBUG: /* more verbose than LOG_NOTE */ | |
| 326 | ✗ | log4cpluslevel = log4cplus::DEBUG_LOG_LEVEL; | |
| 327 | ✗ | break; | |
| 328 | |||
| 329 | ✗ | case SASL_LOG_TRACE: /* traces of internal protocols */ | |
| 330 | case SASL_LOG_PASS: /* traces of internal protocols, including | ||
| 331 | * passwords */ | ||
| 332 | default: | ||
| 333 | ✗ | log4cpluslevel = log4cplus::TRACE_LOG_LEVEL; | |
| 334 | ✗ | break; | |
| 335 | } | ||
| 336 | |||
| 337 | 3 | log4cplus::Logger* logger = reinterpret_cast<log4cplus::Logger*>(context); | |
| 338 |
3/6✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3 times.
✗ Branch 9 not taken.
|
3 | if (logger and logger->isEnabledFor(log4cpluslevel)) { |
| 339 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
6 | log4cplus::tostringstream os; |
| 340 | os << LOG4CPLUS_TEXT("SASL: ") | ||
| 341 |
3/6✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 3 times.
✗ Branch 12 not taken.
|
3 | << LOG4CPLUS_C_STR_TO_TSTRING(message); |
| 342 |
2/4✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 3 times.
✗ Branch 10 not taken.
|
3 | logger->forcedLog(log4cpluslevel, os.str(), __FILE__, __LINE__); |
| 343 | } | ||
| 344 | |||
| 345 | 3 | return SASL_OK; | |
| 346 | } | ||
| 347 | |||
| 348 | /////////////////////////////////////////////////////////////////////////// | ||
| 349 | // man: sasl_getopt_t | ||
| 350 | 230 | int Session::sasl_getopt(void *context, const char* /*plugin_name*/, | |
| 351 | const char *option, const char **result, unsigned *len) | ||
| 352 | { | ||
| 353 | 230 | int rv = SASL_BADPARAM; | |
| 354 | log_debug("context=%p, option=%s, result=%p len=%p", | ||
| 355 | context, option, result, len); | ||
| 356 | 230 | Session* session = reinterpret_cast<Session*>(context); | |
| 357 | |||
| 358 |
2/4✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 230 times.
✗ Branch 3 not taken.
|
230 | if (session and option) { |
| 359 |
2/4✓ Branch 5 taken 230 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 230 times.
✗ Branch 10 not taken.
|
460 | SaslParam::iterator it = session->saslParam.find(option); |
| 360 |
2/2✓ Branch 6 taken 172 times.
✓ Branch 7 taken 58 times.
|
230 | if (it == session->saslParam.end()) { |
| 361 |
3/6✓ Branch 15 taken 172 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 172 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 172 times.
✗ Branch 22 not taken.
|
344 | Config param = session->main->config("access")["sasl"][option]; |
| 362 |
3/4✓ Branch 1 taken 172 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 114 times.
✓ Branch 4 taken 58 times.
|
172 | if (param) |
| 363 |
1/2✓ Branch 3 taken 114 times.
✗ Branch 4 not taken.
|
342 | it = session->saslParam.insert( |
| 364 |
3/6✓ Branch 5 taken 114 times.
✗ Branch 6 not taken.
✓ Branch 12 taken 114 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 114 times.
✗ Branch 17 not taken.
|
228 | std::make_pair(std::string(option), param.toString())) |
| 365 | 228 | .first; | |
| 366 | else { | ||
| 367 |
8/16✓ Branch 8 taken 58 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 58 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 58 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 58 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 58 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 58 times.
✗ Branch 28 not taken.
✓ Branch 35 taken 58 times.
✗ Branch 36 not taken.
✓ Branch 39 taken 58 times.
✗ Branch 40 not taken.
|
58 | LOG4CPLUS_DEBUG(session->log, |
| 368 | LOG4CPLUS_TEXT("SASL parameter not specified: ") | ||
| 369 | << LOG4CPLUS_C_STR_TO_TSTRING(option)); | ||
| 370 | } | ||
| 371 | } | ||
| 372 |
2/2✓ Branch 6 taken 172 times.
✓ Branch 7 taken 58 times.
|
230 | if (it != session->saslParam.end()) { |
| 373 | 172 | *result = it->second.c_str(); | |
| 374 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 172 times.
|
172 | if (len) |
| 375 | ✗ | *len = it->second.size(); | |
| 376 | 172 | rv = SASL_OK; | |
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | //#define STR(x) #x | ||
| 381 | //#define QUOTE(x) STR(x) | ||
| 382 | // if (!strcmp(option, "log_level") and rv != SASL_OK) { | ||
| 383 | // *result = QUOTE(SASL_LOG_PASS); | ||
| 384 | // log_debug("setting log level rv=%s", *result); | ||
| 385 | // rv = SASL_OK; | ||
| 386 | // } | ||
| 387 | |||
| 388 | 230 | return rv; | |
| 389 | } | ||
| 390 | |||
| 391 | ///////////////////////////////////////////////////////////////////////////// | ||
| 392 | 105 | bool Session::eof() const | |
| 393 | { | ||
| 394 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 105 times.
|
105 | return p_eof; |
| 395 | } | ||
| 396 | |||
| 397 | ///////////////////////////////////////////////////////////////////////////// | ||
| 398 | 606 | bool Session::loggedIn() const | |
| 399 | { | ||
| 400 |
5/6✓ Branch 3 taken 142 times.
✓ Branch 4 taken 464 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 142 times.
✓ Branch 10 taken 81 times.
✓ Branch 11 taken 61 times.
|
606 | return conn and p_loggedIn; |
| 401 | } | ||
| 402 | |||
| 403 | ///////////////////////////////////////////////////////////////////////////// | ||
| 404 | ✗ | int Session::overflow(int value) | |
| 405 | { | ||
| 406 | ✗ | char c = value; | |
| 407 | ✗ | return xsputn(&c, 1) ? c : traits_type::eof(); | |
| 408 | } | ||
| 409 | |||
| 410 | ///////////////////////////////////////////////////////////////////////////// | ||
| 411 | 72700 | std::streamsize Session::xsputn(const char * buf, std::streamsize count) | |
| 412 | { | ||
| 413 | 72700 | const char* ptr = buf; | |
| 414 | |||
| 415 | ✗ | do { | |
| 416 | // Put data into buffer | ||
| 417 | 72700 | size_t n = std::min(epptr() - pptr(), count); | |
| 418 | 72700 | std::copy(ptr, ptr + n, pptr()); | |
| 419 | |||
| 420 | // Update pointers | ||
| 421 | 72700 | pbump(n); | |
| 422 | 72700 | ptr += n; | |
| 423 | 72700 | count -= n; | |
| 424 | |||
| 425 |
5/8✓ Branch 8 taken 2 times.
✓ Branch 9 taken 72698 times.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 72700 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 72700 times.
|
72700 | } while (!(pptr() == epptr() and flush(true)) and count); |
| 426 | |||
| 427 | 72700 | return ptr - buf; | |
| 428 | } | ||
| 429 | |||
| 430 | ///////////////////////////////////////////////////////////////////////////// | ||
| 431 | 9763 | int Session::sync() | |
| 432 | { | ||
| 433 | 9763 | return flush(false); | |
| 434 | } | ||
| 435 | |||
| 436 | ///////////////////////////////////////////////////////////////////////////// | ||
| 437 | // Flush output buffer. | ||
| 438 | // | ||
| 439 | // partial: true: do only one flush pass | ||
| 440 | 9765 | int Session::flush(bool partial) | |
| 441 | { | ||
| 442 | 9765 | const char* buf = pbase(); | |
| 443 | 9765 | size_t count = pptr() - buf; | |
| 444 | |||
| 445 |
2/4✗ Branch 3 not taken.
✓ Branch 4 taken 9765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9765 times.
|
9765 | if (p_eof) |
| 446 | ✗ | return -1; | |
| 447 |
2/2✓ Branch 0 taken 8718 times.
✓ Branch 1 taken 1047 times.
|
9765 | else if (!count) |
| 448 | 8718 | return 0; | |
| 449 | |||
| 450 | // log_debug("flushing %i %zu", partial, count); | ||
| 451 | 1047 | ssize_t result = 0; | |
| 452 | ✗ | do { | |
| 453 | |||
| 454 | 1047 | result = write(buf, count); | |
| 455 | |||
| 456 | // log_debug("flushing result %i", result); | ||
| 457 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1047 times.
|
1047 | if (result <= 0) |
| 458 | ✗ | break; | |
| 459 | |||
| 460 | 1047 | buf += result; | |
| 461 | 1047 | count -= result; | |
| 462 | |||
| 463 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1047 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1047 | } while (count and !partial); |
| 464 | |||
| 465 | // Copy remaining data to buffer start and | ||
| 466 | // update std::streambuf's current put pointer pptr() | ||
| 467 | 1047 | std::copy(buf, const_cast<const char*>(pptr()), pbase()); | |
| 468 | 1047 | pbump(pbase() - buf); | |
| 469 | |||
| 470 | // Calculate EOF | ||
| 471 |
1/2✗ Branch 3 not taken.
✓ Branch 4 taken 1047 times.
|
2094 | p_eof |= !result |
| 472 |
2/6✓ Branch 0 taken 1047 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1047 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
|
1047 | or (result < 0 and (result != -EAGAIN)); |
| 473 | |||
| 474 |
1/2✓ Branch 0 taken 1047 times.
✗ Branch 1 not taken.
|
1047 | if (result > 0) |
| 475 | 1047 | return 0; | |
| 476 | |||
| 477 | // Interpret EOF | ||
| 478 | ✗ | if (!result) | |
| 479 | ✗ | LOG4CPLUS_INFO_STR(log, | |
| 480 | LOG4CPLUS_TEXT("Client closed connection")); | ||
| 481 | ✗ | else if (result != -EAGAIN) | |
| 482 | ✗ | LOG4CPLUS_ERROR(log, | |
| 483 | LOG4CPLUS_TEXT("Network write() error: ") | ||
| 484 | << LOG4CPLUS_C_STR_TO_TSTRING(strerror(-result))); | ||
| 485 | |||
| 486 | ✗ | return -1; | |
| 487 | } | ||
| 488 | |||
| 489 | ///////////////////////////////////////////////////////////////////////////// | ||
| 490 | ✗ | int Session::underflow() | |
| 491 | { | ||
| 492 | ✗ | char c; | |
| 493 | ✗ | return xsgetn(&c, 1) == 1 ? c : traits_type::eof(); | |
| 494 | } | ||
| 495 | |||
| 496 | ///////////////////////////////////////////////////////////////////////////// | ||
| 497 | 8962 | std::streamsize Session::xsgetn(char* s, std::streamsize n) | |
| 498 | { | ||
| 499 | 8962 | const ssize_t result = read(s, n); | |
| 500 | |||
| 501 |
2/2✓ Branch 0 taken 8857 times.
✓ Branch 1 taken 105 times.
|
8962 | if (result > 0) |
| 502 | 8857 | return result; | |
| 503 | |||
| 504 | // Calculate EOF | ||
| 505 |
2/4✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 105 times.
✗ Branch 3 not taken.
|
105 | if (!result and result != -EAGAIN) |
| 506 | 105 | p_eof = true; | |
| 507 | |||
| 508 | // Interpret EOF | ||
| 509 |
2/4✗ Branch 3 not taken.
✓ Branch 4 taken 105 times.
✓ Branch 5 taken 105 times.
✗ Branch 6 not taken.
|
105 | if (p_eof) { |
| 510 |
1/2✓ Branch 0 taken 105 times.
✗ Branch 1 not taken.
|
105 | if (!result) |
| 511 |
3/6✓ Branch 8 taken 105 times.
✗ Branch 9 not taken.
✓ Branch 14 taken 105 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 105 times.
✗ Branch 19 not taken.
|
105 | LOG4CPLUS_INFO_STR(log, |
| 512 | LOG4CPLUS_TEXT("Client closed connection")); | ||
| 513 | ✗ | else if (result != -EAGAIN) | |
| 514 | ✗ | LOG4CPLUS_ERROR(log, | |
| 515 | LOG4CPLUS_TEXT("Network error: ") | ||
| 516 | << LOG4CPLUS_C_STR_TO_TSTRING(strerror(-result))); | ||
| 517 | } | ||
| 518 | |||
| 519 | 105 | return 0; | |
| 520 | } | ||
| 521 | |||
| 522 | ///////////////////////////////////////////////////////////////////////////// | ||
| 523 | ///////////////////////////////////////////////////////////////////////////// | ||
| 524 | #ifdef GNUTLS_FOUND | ||
| 525 | ///////////////////////////////////////////////////////////////////////////// | ||
| 526 | 27 | int Session::gnutls_verify_client(gnutls_session_t tls_session) | |
| 527 | { | ||
| 528 | int result; | ||
| 529 | Session* session = | ||
| 530 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | reinterpret_cast<Session*>(gnutls_session_get_ptr(tls_session)); |
| 531 | 27 | const Blacklist& blacklist = session->main->getBlacklist(); | |
| 532 | |||
| 533 | 27 | unsigned int list_size = ~0U; | |
| 534 | const gnutls_datum_t* certs = | ||
| 535 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | gnutls_certificate_get_peers (tls_session, &list_size); |
| 536 |
3/6✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 27 times.
|
27 | if (list_size == ~0U or !certs or !list_size) { |
| 537 | ✗ | LOG4CPLUS_FATAL_STR(session->log, | |
| 538 | LOG4CPLUS_TEXT( | ||
| 539 | "gnutls_certificate_get_peers() failed: " | ||
| 540 | "Client did not send a certificate or " | ||
| 541 | "there was an error retrieving it")); | ||
| 542 | ✗ | return -1; | |
| 543 | } | ||
| 544 | else { | ||
| 545 |
8/16✓ Branch 8 taken 27 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 27 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 27 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 27 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 27 times.
✗ Branch 28 not taken.
✓ Branch 31 taken 27 times.
✗ Branch 32 not taken.
✓ Branch 35 taken 27 times.
✗ Branch 36 not taken.
|
27 | LOG4CPLUS_INFO(session->log, |
| 546 | LOG4CPLUS_TEXT("Received ") | ||
| 547 | << list_size | ||
| 548 | << LOG4CPLUS_TEXT(" certificates from peer")); | ||
| 549 | } | ||
| 550 | |||
| 551 | 27 | gnutls_x509_crt_t raw_crt = nullptr; | |
| 552 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | result = gnutls_x509_crt_init (&raw_crt); |
| 553 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | if (result) { |
| 554 | ✗ | LOG4CPLUS_FATAL(session->log, | |
| 555 | LOG4CPLUS_TEXT("gnutls_x509_crt_init() failed: ") | ||
| 556 | << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result)) | ||
| 557 | << LOG4CPLUS_TEXT(" (") | ||
| 558 | << LOG4CPLUS_C_STR_TO_TSTRING( | ||
| 559 | gnutls_strerror_name(result)) | ||
| 560 | << LOG4CPLUS_TEXT(")")); | ||
| 561 | ✗ | return -1; | |
| 562 | } | ||
| 563 | 54 | std::unique_ptr<gnutls_x509_crt_int, TlsDeleter> crt(raw_crt); | |
| 564 | |||
| 565 |
3/4✓ Branch 0 taken 79 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52 times.
✓ Branch 3 taken 27 times.
|
79 | for (unsigned int i = 0; !result and i < list_size; ++i) { |
| 566 |
1/2✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
|
52 | result = gnutls_x509_crt_import (crt.get(), certs++, |
| 567 | GNUTLS_X509_FMT_DER); | ||
| 568 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
|
52 | if (result) { |
| 569 | ✗ | LOG4CPLUS_FATAL(session->log, | |
| 570 | LOG4CPLUS_TEXT("gnutls_x509_crt_import(") | ||
| 571 | << i | ||
| 572 | << LOG4CPLUS_TEXT(") failed: ") | ||
| 573 | << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result)) | ||
| 574 | << LOG4CPLUS_TEXT(" (") | ||
| 575 | << LOG4CPLUS_C_STR_TO_TSTRING( | ||
| 576 | gnutls_strerror_name(result)) | ||
| 577 | << LOG4CPLUS_TEXT(")")); | ||
| 578 | ✗ | break; | |
| 579 | } | ||
| 580 | |||
| 581 | 52 | gnutls_datum_t cinfo = { NULL, 0 }; | |
| 582 |
1/2✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
|
52 | result = gnutls_x509_crt_print( |
| 583 | crt.get(), GNUTLS_CRT_PRINT_ONELINE, &cinfo); | ||
| 584 |
1/2✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
|
52 | if (result == GNUTLS_E_SUCCESS) { |
| 585 |
10/20✓ Branch 8 taken 52 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 52 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 52 times.
✗ Branch 14 not taken.
✓ Branch 17 taken 52 times.
✗ Branch 18 not taken.
✓ Branch 23 taken 52 times.
✗ Branch 24 not taken.
✓ Branch 27 taken 52 times.
✗ Branch 28 not taken.
✓ Branch 33 taken 52 times.
✗ Branch 34 not taken.
✓ Branch 37 taken 52 times.
✗ Branch 38 not taken.
✓ Branch 45 taken 52 times.
✗ Branch 46 not taken.
✓ Branch 49 taken 52 times.
✗ Branch 50 not taken.
|
52 | LOG4CPLUS_INFO(session->log, |
| 586 | LOG4CPLUS_TEXT("Certificate[") | ||
| 587 | << i | ||
| 588 | << LOG4CPLUS_TEXT("].info: ") | ||
| 589 | << LOG4CPLUS_C_STR_TO_TSTRING((const char*)cinfo.data)); | ||
| 590 | } | ||
| 591 | else { | ||
| 592 | ✗ | LOG4CPLUS_INFO(session->log, | |
| 593 | LOG4CPLUS_TEXT("gnutls_x509_crt_print(") | ||
| 594 | << i | ||
| 595 | << LOG4CPLUS_TEXT(") failed: ") | ||
| 596 | << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result)) | ||
| 597 | << LOG4CPLUS_TEXT(" (") | ||
| 598 | << LOG4CPLUS_C_STR_TO_TSTRING( | ||
| 599 | gnutls_strerror_name(result)) | ||
| 600 | << LOG4CPLUS_TEXT(")")); | ||
| 601 | } | ||
| 602 |
1/2✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
|
52 | gnutls_free(cinfo.data); |
| 603 | |||
| 604 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 52 times.
|
52 | if (!blacklist.empty()) { |
| 605 | ✗ | unsigned char buf[100]; | |
| 606 | ✗ | size_t len = sizeof(buf); | |
| 607 | ✗ | result = gnutls_x509_crt_get_key_id(crt.get(), 0, buf, &len); | |
| 608 | ✗ | if (result or !len) { | |
| 609 | ✗ | LOG4CPLUS_FATAL(session->log, | |
| 610 | LOG4CPLUS_TEXT("gnutls_x509_crt_get_key_id(") | ||
| 611 | << i | ||
| 612 | << LOG4CPLUS_TEXT(") failed: ") | ||
| 613 | << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result)) | ||
| 614 | << LOG4CPLUS_TEXT(" (") | ||
| 615 | << LOG4CPLUS_C_STR_TO_TSTRING( | ||
| 616 | gnutls_strerror_name(result)) | ||
| 617 | << LOG4CPLUS_TEXT(")")); | ||
| 618 | ✗ | result = -1; | |
| 619 | ✗ | break; | |
| 620 | } | ||
| 621 | else { | ||
| 622 | ✗ | Blacklist::const_iterator it = | |
| 623 | ✗ | blacklist.find(datum_string(buf, len)); | |
| 624 | ✗ | if (it != blacklist.end()) { | |
| 625 | ✗ | LOG4CPLUS_FATAL(session->log, | |
| 626 | LOG4CPLUS_TEXT( | ||
| 627 | "Certificate is blacklisted." | ||
| 628 | " Public Key Id = ") | ||
| 629 | << LOG4CPLUS_STRING_TO_TSTRING(std::string(*it))); | ||
| 630 | ✗ | result = -1; | |
| 631 | ✗ | break; | |
| 632 | } | ||
| 633 | } | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 637 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | if (result) |
| 638 | ✗ | return result; | |
| 639 | |||
| 640 | 27 | unsigned int status; | |
| 641 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | result = gnutls_certificate_verify_peers2(tls_session, &status); |
| 642 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
|
27 | if (result) { |
| 643 | // Complain | ||
| 644 | ✗ | LOG4CPLUS_FATAL(session->log, | |
| 645 | LOG4CPLUS_TEXT("gnutls_certificate_verify_peers2() failed: ") | ||
| 646 | << LOG4CPLUS_C_STR_TO_TSTRING(gnutls_strerror(result)) | ||
| 647 | << LOG4CPLUS_TEXT(" (") | ||
| 648 | << LOG4CPLUS_C_STR_TO_TSTRING( | ||
| 649 | gnutls_strerror_name(result)) | ||
| 650 | << LOG4CPLUS_TEXT(")")); | ||
| 651 | ✗ | return -1; | |
| 652 | } | ||
| 653 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
|
27 | else if (status) { |
| 654 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | std::ostringstream os; |
| 655 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | os << "Verification of peer's certificate failed: "; |
| 656 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (status & GNUTLS_CERT_INVALID) |
| 657 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | os << "Certificate is invalid"; |
| 658 | |||
| 659 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (status & GNUTLS_CERT_REVOKED) |
| 660 | ✗ | os << "Certificate is revoked"; | |
| 661 | |||
| 662 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) |
| 663 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | os << "Certificate signer is not found"; |
| 664 | |||
| 665 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (status & GNUTLS_CERT_SIGNER_NOT_CA) |
| 666 | ✗ | os << "Certificate signer is not a certification authority"; | |
| 667 | |||
| 668 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (status & GNUTLS_CERT_INSECURE_ALGORITHM) |
| 669 | ✗ | os << "Certificate uses an insecure algorithm"; | |
| 670 | |||
| 671 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (status & GNUTLS_CERT_NOT_ACTIVATED) |
| 672 | ✗ | os << "Certificate is not activated"; | |
| 673 | |||
| 674 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (status & GNUTLS_CERT_EXPIRED) |
| 675 | ✗ | os << "Certificate expired"; | |
| 676 | |||
| 677 |
4/8✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
|
1 | LOG4CPLUS_FATAL_STR(session->log, |
| 678 | LOG4CPLUS_STRING_TO_TSTRING(os.str())); | ||
| 679 | |||
| 680 | 1 | return -1; | |
| 681 | } | ||
| 682 | |||
| 683 | 26 | return 0; | |
| 684 | 9 | } | |
| 685 | |||
| 686 | #endif | ||
| 687 |