1 #include <config.h>
2
3 #ifdef WITH_TLS
4 # ifndef IN_TLS_C
5 # define IN_TLS_C 1
6 # endif
7
8 # include "ftpd.h"
9 # include "tls.h"
10 # include "ftpwho-update.h"
11 # include "globals.h"
12 # include "messages.h"
13 # include "alt_arc4random.h"
14 # include "tls_extcert.h"
15
tls_error(const int line,int err)16 static void tls_error(const int line, int err)
17 {
18 if (err == 0) {
19 err = ERR_get_error();
20 }
21 if (err != 0) {
22 logfile(LOG_ERR, "TLS [%s](%d): %s",
23 cert_file, line, ERR_error_string(err, NULL));
24 }
25 _EXIT(EXIT_FAILURE);
26 }
27
validate_sni_name(const char * const sni_name)28 static int validate_sni_name(const char * const sni_name)
29 {
30 static const char *valid_chars =
31 "abcdefghijklmnopqrstuvwxyz.-0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZ";
32 const char *pnt = sni_name;
33
34 if (strlen(sni_name) > 255) {
35 return -1;
36 }
37 while (*pnt != 0) {
38 if (strchr(valid_chars, *pnt) == NULL) {
39 return -1;
40 }
41 pnt++;
42 }
43 return 0;
44 }
45
46 static int tls_create_new_context(const char *cert_file,
47 const char *key_file);
48
ssl_servername_cb(SSL * cnx,int * al,void * arg)49 static int ssl_servername_cb(SSL *cnx, int *al, void *arg)
50 {
51 CertResult result;
52 const char *sni_name;
53
54 (void) al;
55 (void) arg;
56 if ((sni_name = SSL_get_servername(cnx, TLSEXT_NAMETYPE_host_name))
57 == NULL || *sni_name == 0 || validate_sni_name(sni_name) != 0) {
58 return SSL_TLSEXT_ERR_NOACK;
59 }
60 logfile(LOG_INFO, "SNI: [%s]", sni_name);
61 if (chrooted != 0 || loggedin != 0) {
62 return SSL_TLSEXT_ERR_NOACK;
63 }
64 if (use_extcert == 0) {
65 return SSL_TLSEXT_ERR_OK;
66 }
67 memset(&result, 0, sizeof result);
68 tls_extcert_get(&result, sni_name);
69 if (result.cert_ok != 1) {
70 die(400, LOG_ERR, "Cert handler not ready");
71 }
72 if (result.action == CERT_ACTION_DENY) {
73 die(400, LOG_INFO, MSG_LOGOUT);
74 }
75 if (result.action == CERT_ACTION_DEFAULT) {
76 return SSL_TLSEXT_ERR_OK;
77 }
78 if (result.cert_file == NULL) {
79 if (result.action == CERT_ACTION_STRICT) {
80 die(400, LOG_ERR, "Missing certificate");
81 } else {
82 return SSL_TLSEXT_ERR_OK;
83 }
84 }
85 if (result.key_file == NULL) {
86 result.key_file = result.cert_file;
87 }
88 SSL_CTX_free(tls_ctx);
89 tls_ctx = NULL;
90 if (tls_create_new_context(result.cert_file, result.key_file) != 0) {
91 if (result.action != CERT_ACTION_FALLBACK) {
92 die(400, LOG_ERR, "Invalid certificate");
93 }
94 if (tls_create_new_context(cert_file, key_file) != 0) {
95 die(400, LOG_ERR, "SSL error");
96 }
97 }
98 if ((client_sni_name = strdup(sni_name)) == NULL) {
99 die_mem();
100 }
101 if (tls_cnx != NULL) {
102 const long ctx_options = SSL_CTX_get_options(tls_ctx);
103 SSL_set_SSL_CTX(tls_cnx, tls_ctx);
104 # ifdef SSL_CTRL_CLEAR_OPTIONS
105 SSL_clear_options(tls_cnx,
106 SSL_get_options(tls_cnx) & ~ctx_options);
107 # endif
108 SSL_set_options(tls_cnx, ctx_options);
109 }
110 if (tls_data_cnx != NULL) {
111 const long ctx_options = SSL_CTX_get_options(tls_ctx);
112 SSL_set_SSL_CTX(tls_data_cnx, tls_ctx);
113 # ifdef SSL_CTRL_CLEAR_OPTIONS
114 SSL_clear_options(tls_data_cnx,
115 SSL_get_options(tls_cnx) & ~ctx_options);
116 # endif
117 SSL_set_options(tls_data_cnx, ctx_options);
118 }
119 return SSL_TLSEXT_ERR_OK;
120 }
121
ssl_info_cb(const SSL * cnx,int where,int ret)122 static void ssl_info_cb(const SSL *cnx, int where, int ret)
123 {
124 (void) ret;
125
126 if ((where & SSL_CB_HANDSHAKE_DONE) != 0) {
127 if (cnx == tls_cnx) {
128 tls_cnx_handshook = 1;
129 } else if (cnx == tls_data_cnx) {
130 tls_data_cnx_handshook = 1;
131 }
132 }
133 }
134
tls_init_ecdh_curve(void)135 static int tls_init_ecdh_curve(void)
136 {
137 #ifdef SSL_CTRL_SET_ECDH_AUTO
138 SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
139 return 0;
140 #else
141 # ifndef SSL_OP_SINGLE_ECDH_USE
142 errno = ENOTSUP;
143 return -1;
144 # else
145 const char *curve_name;
146 EC_KEY *curve;
147 int nid;
148
149 curve_name = TLS_DEFAULT_ECDH_CURVE;
150 if ((nid = OBJ_sn2nid(curve_name)) == NID_undef) {
151 logfile(LOG_INFO, "Curve [%s] not supported", curve_name);
152 errno = ENOTSUP;
153 return -1;
154 }
155 if ((curve = EC_KEY_new_by_curve_name(nid)) == NULL) {
156 logfile(LOG_INFO, "Curve [%s] is not usable", curve_name);
157 errno = ENOTSUP;
158 return -1;
159 }
160 SSL_CTX_set_options(tls_ctx, SSL_OP_SINGLE_ECDH_USE);
161 SSL_CTX_set_tmp_ecdh(tls_ctx, curve);
162 EC_KEY_free(curve);
163
164 return 0;
165 # endif
166 #endif
167 }
168
169 #ifndef SSL_CTRL_SET_DH_AUTO
tls_load_dhparams_default(void)170 static int tls_load_dhparams_default(void)
171 {
172 # ifdef HAVE_DH_GET_2048_256
173 DH *dh;
174
175 if ((dh = DH_get_2048_256()) == NULL) {
176 die_mem();
177 }
178 # else
179 # if BN_BITS2 == 64
180 static const BN_ULONG dh2048_256_p[] = {
181 0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL,
182 0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL,
183 0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL,
184 0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL,
185 0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL,
186 0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL,
187 0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL,
188 0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL,
189 0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL,
190 0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL,
191 0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL
192 };
193 static const BN_ULONG dh2048_256_g[] = {
194 0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL,
195 0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL,
196 0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL,
197 0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL,
198 0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL,
199 0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL,
200 0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL,
201 0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL,
202 0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL,
203 0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL,
204 0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL
205 };
206 static const BN_ULONG dh2048_256_q[] = {
207 0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL,
208 0x8CF83642A709A097ULL
209 };
210 # elif BN_BITS2 == 32
211 static const BN_ULONG dh2048_256_p[] = {
212 0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227,
213 0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A,
214 0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79,
215 0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5,
216 0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267,
217 0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF,
218 0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF,
219 0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64,
220 0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45,
221 0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608,
222 0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D
223 };
224 static const BN_ULONG dh2048_256_g[] = {
225 0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148,
226 0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428,
227 0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15,
228 0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73,
229 0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1,
230 0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982,
231 0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5,
232 0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8,
233 0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A,
234 0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F,
235 0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B
236 };
237 static const BN_ULONG dh2048_256_q[] = {
238 0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976,
239 0xA709A097, 0x8CF83642
240 };
241 # else
242 # error "unsupported BN_BITS2"
243 # endif
244 static const BIGNUM p = {
245 (BN_ULONG *) dh2048_256_p,
246 sizeof(dh2048_256_p) / sizeof(BN_ULONG),
247 sizeof(dh2048_256_p) / sizeof(BN_ULONG),
248 0, BN_FLG_STATIC_DATA
249 };
250 static const BIGNUM g = {
251 (BN_ULONG *) dh2048_256_g,
252 sizeof(dh2048_256_g) / sizeof(BN_ULONG),
253 sizeof(dh2048_256_g) / sizeof(BN_ULONG),
254 0, BN_FLG_STATIC_DATA
255 };
256 static const BIGNUM q = {
257 (BN_ULONG *) dh2048_256_q,
258 sizeof(dh2048_256_q) / sizeof(BN_ULONG),
259 sizeof(dh2048_256_q) / sizeof(BN_ULONG),
260 0, BN_FLG_STATIC_DATA
261 };
262 DH *dh;
263
264 if ((dh = DH_new()) == NULL) {
265 die_mem();
266 }
267 dh->p = BN_dup(&p);
268 dh->g = BN_dup(&g);
269 dh->q = BN_dup(&q);
270 if (dh->p == NULL || dh->g == NULL || dh->q == NULL) {
271 DH_free(dh);
272 die_mem();
273 }
274 # endif
275 SSL_CTX_set_tmp_dh(tls_ctx, dh);
276 DH_free(dh);
277 # ifdef SSL_OP_SINGLE_DH_USE
278 SSL_CTX_set_options(tls_ctx, SSL_OP_SINGLE_DH_USE);
279 # endif
280
281 return 0;
282 }
283 #endif
284
tls_init_dhparams(void)285 static void tls_init_dhparams(void)
286 {
287 # ifdef SSL_CTRL_SET_DH_AUTO
288 SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_DH_AUTO, 1, NULL);
289 # else
290 tls_load_dhparams_default();
291 # endif
292 }
293
tls_init_cache(void)294 static void tls_init_cache(void)
295 {
296 static const char *tls_ctx_id = "pure-ftpd";
297
298 SSL_CTX_set_session_cache_mode(tls_ctx, SSL_SESS_CACHE_SERVER);
299 SSL_CTX_set_session_id_context(tls_ctx, (unsigned char *) tls_ctx_id,
300 (unsigned int) strlen(tls_ctx_id));
301 SSL_CTX_sess_set_cache_size(tls_ctx, 10);
302 SSL_CTX_set_timeout(tls_ctx, 60 * 60L);
303 }
304
tls_init_options(void)305 static void tls_init_options(void)
306 {
307 static int passes;
308
309 # ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
310 SSL_CTX_set_options(tls_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
311 # endif
312 # ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
313 SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
314 # endif
315 SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SSLv2);
316 SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SSLv3);
317 # ifdef SSL_OP_NO_TLSv1
318 SSL_CTX_set_options(tls_ctx, SSL_OP_NO_TLSv1);
319 # endif
320 # ifdef SSL_OP_NO_TLSv1_1
321 SSL_CTX_set_options(tls_ctx, SSL_OP_NO_TLSv1_1);
322 # endif
323 # ifdef SSL_OP_NO_TLSv1_2
324 SSL_CTX_clear_options(tls_ctx, SSL_OP_NO_TLSv1_2);
325 # endif
326 # ifdef SSL_OP_NO_TLSv1_3
327 SSL_CTX_clear_options(tls_ctx, SSL_OP_NO_TLSv1_3);
328 # endif
329 SSL_CTX_set_num_tickets(tls_ctx, 0);
330 if (tlsciphersuite != NULL) {
331 if (SSL_CTX_set_cipher_list(tls_ctx, tlsciphersuite) != 1) {
332 logfile(LOG_ERR, MSG_TLS_CIPHER_FAILED, tlsciphersuite);
333 _EXIT(EXIT_FAILURE);
334 }
335 }
336 SSL_CTX_set_info_callback(tls_ctx, ssl_info_cb);
337 if (passes == 0) {
338 SSL_CTX_set_tlsext_servername_callback(tls_ctx, ssl_servername_cb);
339 passes++;
340 }
341 SSL_CTX_set_verify_depth(tls_ctx, MAX_CERTIFICATE_DEPTH);
342 }
343
tls_load_cert_file(const char * const cert_file,const char * const key_file)344 static void tls_load_cert_file(const char * const cert_file,
345 const char * const key_file)
346 {
347 if (SSL_CTX_use_certificate_chain_file(tls_ctx, cert_file) != 1) {
348 die(421, LOG_ERR,
349 MSG_FILE_DOESNT_EXIST ": [%s]", cert_file);
350 }
351 if (SSL_CTX_use_PrivateKey_file(tls_ctx, key_file,
352 SSL_FILETYPE_PEM) != 1) {
353 die(421, LOG_ERR,
354 MSG_FILE_DOESNT_EXIST ": [%s]", key_file);
355 }
356 if (SSL_CTX_check_private_key(tls_ctx) != 1) {
357 tls_error(__LINE__, 0);
358 }
359 }
360
tls_init_client_cert_verification(const char * cert_file)361 static void tls_init_client_cert_verification(const char *cert_file)
362 {
363 if (cert_file == NULL) {
364 tls_error(__LINE__, 0);
365 }
366 SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
367 SSL_VERIFY_PEER, NULL);
368 if (SSL_CTX_load_verify_locations(tls_ctx, cert_file, NULL) != 1) {
369 tls_error(__LINE__, 0);
370 }
371 }
372
tls_create_new_context(const char * cert_file,const char * key_file)373 static int tls_create_new_context(const char *cert_file,
374 const char *key_file)
375 {
376 # ifdef HAVE_TLS_SERVER_METHOD
377 if ((tls_ctx = SSL_CTX_new(TLS_server_method())) == NULL) {
378 tls_error(__LINE__, 0);
379 }
380 # else
381 if ((tls_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
382 tls_error(__LINE__, 0);
383 }
384 # endif
385 tls_init_options();
386 tls_init_cache();
387 tls_load_cert_file(cert_file, key_file);
388 if (ssl_verify_client_cert) {
389 tls_init_client_cert_verification(cert_file);
390 }
391 tls_init_ecdh_curve();
392 tls_init_dhparams();
393
394 return 0;
395 }
396
tls_init_rnd(void)397 static void tls_init_rnd(void)
398 {
399 unsigned int rnd;
400
401 while (RAND_status() == 0) {
402 rnd = zrand();
403 RAND_seed(&rnd, (int) sizeof rnd);
404 }
405 }
406
tls_init_library(void)407 int tls_init_library(void)
408 {
409 tls_cnx = NULL;
410 tls_data_cnx = NULL;
411 tls_ctx = NULL;
412
413 # if (OPENSSL_VERSION_NUMBER < 0x10100000L) || !defined(OPENSSL_INIT_LOAD_SSL_STRINGS)
414 SSL_library_init();
415 SSL_load_error_strings();
416 OpenSSL_add_all_algorithms();
417 # else
418 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
419 OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
420 OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS |
421 OPENSSL_INIT_ADD_ALL_DIGESTS |
422 OPENSSL_INIT_LOAD_CONFIG, NULL);
423 # endif
424 tls_init_rnd();
425 tls_create_new_context(cert_file, key_file);
426 tls_cnx_handshook = 0;
427 tls_data_cnx_handshook = 0;
428
429 return 0;
430 }
431
tls_free_library(void)432 void tls_free_library(void)
433 {
434 if (tls_data_cnx != NULL) {
435 tls_close_session(&tls_data_cnx);
436 }
437 if (tls_cnx != NULL) {
438 SSL_free(tls_cnx);
439 tls_cnx = NULL;
440 }
441 if (tls_ctx != NULL) {
442 SSL_CTX_free(tls_ctx);
443 tls_ctx = NULL;
444 }
445 # if OPENSSL_API_COMPAT < 0x10100000L
446 EVP_cleanup();
447 # endif
448 }
449
tls_init_new_session(void)450 int tls_init_new_session(void)
451 {
452 const SSL_CIPHER *cipher;
453 int ret;
454 int ret_;
455
456 if (tls_ctx == NULL || (tls_cnx = SSL_new(tls_ctx)) == NULL) {
457 tls_error(__LINE__, 0);
458 }
459 if (SSL_set_fd(tls_cnx, clientfd) != 1) {
460 tls_error(__LINE__, 0);
461 }
462 SSL_set_accept_state(tls_cnx);
463 for (;;) {
464 ret = SSL_accept(tls_cnx);
465 if (ret != 1) {
466 ret_ = SSL_get_error(tls_cnx, ret);
467 if (ret == -1 &&
468 (ret_ == SSL_ERROR_WANT_READ ||
469 ret_ == SSL_ERROR_WANT_WRITE)) {
470 continue;
471 }
472 die(400, LOG_WARNING, MSG_TLS_NEEDED);
473 }
474 break;
475 }
476 if ((cipher = SSL_get_current_cipher(tls_cnx)) != NULL) {
477 int strength_bits = SSL_CIPHER_get_bits(cipher, NULL);
478
479 logfile(LOG_INFO, MSG_TLS_INFO, SSL_CIPHER_get_version(cipher),
480 SSL_CIPHER_get_name(cipher), strength_bits);
481 if (strength_bits < MINIMAL_CIPHER_STRENGTH_BITS) {
482 die(534, LOG_ERR, MSG_TLS_WEAK);
483 }
484 }
485 return 0;
486 }
487
tls_init_data_session(const int fd,const int passive)488 int tls_init_data_session(const int fd, const int passive)
489 {
490 const SSL_CIPHER *cipher;
491 int ret;
492 int ret_;
493
494 (void) passive;
495 if (tls_ctx == NULL) {
496 logfile(LOG_ERR, MSG_TLS_NO_CTX);
497 tls_error(__LINE__, 0);
498 }
499 if (tls_data_cnx != NULL) {
500 tls_close_session(&tls_data_cnx);
501 } else if ((tls_data_cnx = SSL_new(tls_ctx)) == NULL) {
502 tls_error(__LINE__, 0);
503 }
504 if (SSL_set_fd(tls_data_cnx, fd) != 1) {
505 tls_error(__LINE__, 0);
506 }
507 SSL_set_accept_state(tls_data_cnx);
508 for (;;) {
509 ret = SSL_accept(tls_data_cnx);
510 if (ret <= 0) {
511 ret_ = SSL_get_error(tls_data_cnx, ret);
512 if (ret == -1 && (ret_ == SSL_ERROR_WANT_READ ||
513 ret_ == SSL_ERROR_WANT_WRITE)) {
514 continue;
515 }
516 logfile(LOG_INFO, MSG_LOGOUT);
517 _EXIT(EXIT_FAILURE);
518 }
519 break;
520 }
521 if ((cipher = SSL_get_current_cipher(tls_data_cnx)) != NULL) {
522 int strength_bits = SSL_CIPHER_get_bits(cipher, NULL);
523
524 logfile(LOG_INFO, MSG_TLS_INFO, SSL_CIPHER_get_version(cipher),
525 SSL_CIPHER_get_name(cipher), strength_bits);
526 if (strength_bits < MINIMAL_CIPHER_STRENGTH_BITS) {
527 die(534, LOG_ERR, MSG_TLS_WEAK);
528 }
529 }
530 return 0;
531 }
532
tls_close_session(SSL ** const cnx)533 void tls_close_session(SSL ** const cnx)
534 {
535 unsigned int retries = 10U;
536 unsigned int max_shutdowns = 2;
537
538 if (*cnx == NULL) {
539 return;
540 }
541 retry:
542 switch (SSL_shutdown(*cnx)) {
543 case 0:
544 if (--max_shutdowns > 0) {
545 goto retry;
546 }
547 case 1:
548 break;
549 default: {
550 switch (SSL_get_error(*cnx, -1)) {
551 case SSL_ERROR_WANT_READ:
552 case SSL_ERROR_WANT_WRITE: {
553 struct pollfd pfd;
554 pfd.fd = SSL_get_fd(*cnx);
555 pfd.events = POLLIN | POLLOUT | POLLERR | POLLHUP;
556 pfd.revents = 0;
557 if (poll(&pfd, 1U, idletime * 1000UL) > 0 && retries-- > 0U) {
558 goto retry;
559 }
560 }
561 }
562 if (SSL_clear(*cnx) == 1) {
563 break;
564 }
565 tls_error(__LINE__, 0);
566 }
567 }
568 if (*cnx == tls_cnx) {
569 tls_cnx_handshook = 0;
570 } else if (*cnx == tls_data_cnx) {
571 tls_data_cnx_handshook = 0;
572 }
573 SSL_free(*cnx);
574 *cnx = NULL;
575 }
576
577 #endif
578