1 /* $NetBSD: tls_proxy_client_scan.c,v 1.6 2026/05/09 18:49:21 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* tls_proxy_client_scan 3 6 /* SUMMARY 7 /* read TLS_CLIENT_XXX structures from stream 8 /* SYNOPSIS 9 /* #include <tls_proxy.h> 10 /* 11 /* int tls_proxy_client_param_scan(scan_fn, stream, flags, ptr) 12 /* ATTR_SCAN_COMMON_FN scan_fn; 13 /* VSTREAM *stream; 14 /* int flags; 15 /* void *ptr; 16 /* 17 /* void tls_proxy_client_param_free(params) 18 /* TLS_CLIENT_PARAMS *params; 19 /* 20 /* int tls_proxy_client_init_scan(scan_fn, stream, flags, ptr) 21 /* ATTR_SCAN_COMMON_FN scan_fn; 22 /* VSTREAM *stream; 23 /* int flags; 24 /* void *ptr; 25 /* 26 /* void tls_proxy_client_init_free(init_props) 27 /* TLS_CLIENT_INIT_PROPS *init_props; 28 /* 29 /* int tls_proxy_client_start_scan(scan_fn, stream, flags, ptr) 30 /* ATTR_SCAN_COMMON_FN scan_fn; 31 /* VSTREAM *stream; 32 /* int flags; 33 /* void *ptr; 34 /* 35 /* void tls_proxy_client_start_free(start_props) 36 /* TLS_CLIENT_START_PROPS *start_props; 37 /* DESCRIPTION 38 /* tls_proxy_client_param_scan() reads a TLS_CLIENT_PARAMS structure from 39 /* the named stream using the specified attribute scan routine. 40 /* tls_proxy_client_param_scan() is meant to be passed as a call-back 41 /* function to attr_scan(), as shown below. 42 /* 43 /* tls_proxy_client_param_free() destroys a TLS_CLIENT_PARAMS structure 44 /* that was created by tls_proxy_client_param_scan(). 45 /* 46 /* TLS_CLIENT_PARAMS *param = 0; 47 /* ... 48 /* ... RECV_ATTR_FUNC(tls_proxy_client_param_scan, (void *) ¶m) 49 /* ... 50 /* if (param != 0) 51 /* tls_proxy_client_param_free(param); 52 /* 53 /* tls_proxy_client_init_scan() reads a full TLS_CLIENT_INIT_PROPS 54 /* structure from the named stream using the specified attribute 55 /* scan routine. tls_proxy_client_init_scan() is meant to be passed 56 /* as a call-back function to attr_scan(), as shown below. 57 /* 58 /* tls_proxy_client_init_free() destroys a TLS_CLIENT_INIT_PROPS 59 /* structure that was created by tls_proxy_client_init_scan(). 60 /* 61 /* TLS_CLIENT_INIT_PROPS *init_props = 0; 62 /* ... 63 /* ... RECV_ATTR_FUNC(tls_proxy_client_init_scan, (void *) &init_props) 64 /* ... 65 /* if (init_props != 0) 66 /* tls_proxy_client_init_free(init_props); 67 /* 68 /* tls_proxy_client_start_scan() reads a TLS_CLIENT_START_PROPS 69 /* structure, without the stream of file descriptor members, 70 /* from the named stream using the specified attribute scan 71 /* routine. tls_proxy_client_start_scan() is meant to be passed 72 /* as a call-back function to attr_scan(), as shown below. 73 /* 74 /* tls_proxy_client_start_free() destroys a TLS_CLIENT_START_PROPS 75 /* structure that was created by tls_proxy_client_start_scan(). 76 /* 77 /* TLS_CLIENT_START_PROPS *start_props = 0; 78 /* ... 79 /* ... RECV_ATTR_FUNC(tls_proxy_client_start_scan, (void *) &start_props) 80 /* ... 81 /* if (start_props != 0) 82 /* tls_proxy_client_start_free(start_props); 83 /* DIAGNOSTICS 84 /* Fatal: out of memory. 85 /* LICENSE 86 /* .ad 87 /* .fi 88 /* The Secure Mailer license must be distributed with this software. 89 /* AUTHOR(S) 90 /* Wietse Venema 91 /* Google, Inc. 92 /* 111 8th Avenue 93 /* New York, NY 10011, USA 94 /*--*/ 95 96 #ifdef USE_TLS 97 98 /* System library. */ 99 100 #include <sys_defs.h> 101 102 /* Utility library */ 103 104 #include <argv_attr.h> 105 #include <attr.h> 106 #include <msg.h> 107 #include <vstring.h> 108 109 /* Global library. */ 110 111 #include <mail_params.h> 112 113 /* TLS library. */ 114 115 #define TLS_INTERNAL 116 #include <tls.h> 117 #include <tls_proxy.h> 118 #ifdef USE_TLSRPT 119 #define TLSRPT_WRAPPER_INTERNAL 120 #include <tlsrpt_wrapper.h> 121 #endif 122 123 #define STR(x) vstring_str(x) 124 #define LEN(x) VSTRING_LEN(x) 125 126 /* tls_proxy_client_param_free - destroy TLS_CLIENT_PARAMS structure */ 127 128 void tls_proxy_client_param_free(TLS_CLIENT_PARAMS *params) 129 { 130 myfree(params->tls_cnf_file); 131 myfree(params->tls_cnf_name); 132 myfree(params->tls_high_clist); 133 myfree(params->tls_medium_clist); 134 myfree(params->tls_null_clist); 135 myfree(params->tls_eecdh_auto); 136 myfree(params->tls_eecdh_strong); 137 myfree(params->tls_eecdh_ultra); 138 myfree(params->tls_ffdhe_auto); 139 myfree(params->tls_bug_tweaks); 140 myfree(params->tls_ssl_options); 141 myfree(params->tls_dane_digests); 142 myfree(params->tls_mgr_service); 143 myfree(params->tls_tkt_cipher); 144 myfree((void *) params); 145 } 146 147 /* tls_proxy_client_param_scan - receive TLS_CLIENT_PARAMS from stream */ 148 149 int tls_proxy_client_param_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp, 150 int flags, void *ptr) 151 { 152 TLS_CLIENT_PARAMS *params 153 = (TLS_CLIENT_PARAMS *) mymalloc(sizeof(*params)); 154 int ret; 155 VSTRING *cnf_file = vstring_alloc(25); 156 VSTRING *cnf_name = vstring_alloc(25); 157 VSTRING *tls_high_clist = vstring_alloc(25); 158 VSTRING *tls_medium_clist = vstring_alloc(25); 159 VSTRING *tls_null_clist = vstring_alloc(25); 160 VSTRING *tls_eecdh_auto = vstring_alloc(25); 161 VSTRING *tls_eecdh_strong = vstring_alloc(25); 162 VSTRING *tls_eecdh_ultra = vstring_alloc(25); 163 VSTRING *tls_ffdhe_auto = vstring_alloc(25); 164 VSTRING *tls_bug_tweaks = vstring_alloc(25); 165 VSTRING *tls_ssl_options = vstring_alloc(25); 166 VSTRING *tls_dane_digests = vstring_alloc(25); 167 VSTRING *tls_mgr_service = vstring_alloc(25); 168 VSTRING *tls_tkt_cipher = vstring_alloc(25); 169 170 if (msg_verbose) 171 msg_info("begin tls_proxy_client_param_scan"); 172 173 /* 174 * Note: memset() is not a portable way to initialize non-integer types. 175 */ 176 memset(params, 0, sizeof(*params)); 177 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 178 RECV_ATTR_STR(TLS_ATTR_CNF_FILE, cnf_file), 179 RECV_ATTR_STR(TLS_ATTR_CNF_NAME, cnf_name), 180 RECV_ATTR_STR(VAR_TLS_HIGH_CLIST, tls_high_clist), 181 RECV_ATTR_STR(VAR_TLS_MEDIUM_CLIST, tls_medium_clist), 182 RECV_ATTR_STR(VAR_TLS_NULL_CLIST, tls_null_clist), 183 RECV_ATTR_STR(VAR_TLS_EECDH_AUTO, tls_eecdh_auto), 184 RECV_ATTR_STR(VAR_TLS_EECDH_STRONG, tls_eecdh_strong), 185 RECV_ATTR_STR(VAR_TLS_EECDH_ULTRA, tls_eecdh_ultra), 186 RECV_ATTR_STR(VAR_TLS_FFDHE_AUTO, tls_ffdhe_auto), 187 RECV_ATTR_STR(VAR_TLS_BUG_TWEAKS, tls_bug_tweaks), 188 RECV_ATTR_STR(VAR_TLS_SSL_OPTIONS, tls_ssl_options), 189 RECV_ATTR_STR(VAR_TLS_DANE_DIGESTS, tls_dane_digests), 190 RECV_ATTR_STR(VAR_TLS_MGR_SERVICE, tls_mgr_service), 191 RECV_ATTR_STR(VAR_TLS_TKT_CIPHER, tls_tkt_cipher), 192 RECV_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES, 193 ¶ms->tls_daemon_rand_bytes), 194 RECV_ATTR_INT(VAR_TLS_APPEND_DEF_CA, 195 ¶ms->tls_append_def_CA), 196 RECV_ATTR_INT(VAR_TLS_PREEMPT_CLIST, 197 ¶ms->tls_preempt_clist), 198 RECV_ATTR_INT(VAR_TLS_MULTI_WILDCARD, 199 ¶ms->tls_multi_wildcard), 200 ATTR_TYPE_END); 201 /* Always construct a well-formed structure. */ 202 params->tls_cnf_file = vstring_export(cnf_file); 203 params->tls_cnf_name = vstring_export(cnf_name); 204 params->tls_high_clist = vstring_export(tls_high_clist); 205 params->tls_medium_clist = vstring_export(tls_medium_clist); 206 params->tls_null_clist = vstring_export(tls_null_clist); 207 params->tls_eecdh_auto = vstring_export(tls_eecdh_auto); 208 params->tls_eecdh_strong = vstring_export(tls_eecdh_strong); 209 params->tls_eecdh_ultra = vstring_export(tls_eecdh_ultra); 210 params->tls_ffdhe_auto = vstring_export(tls_ffdhe_auto); 211 params->tls_bug_tweaks = vstring_export(tls_bug_tweaks); 212 params->tls_ssl_options = vstring_export(tls_ssl_options); 213 params->tls_dane_digests = vstring_export(tls_dane_digests); 214 params->tls_mgr_service = vstring_export(tls_mgr_service); 215 params->tls_tkt_cipher = vstring_export(tls_tkt_cipher); 216 217 ret = (ret == 18 ? 1 : -1); 218 if (ret != 1) { 219 tls_proxy_client_param_free(params); 220 params = 0; 221 } 222 *(TLS_CLIENT_PARAMS **) ptr = params; 223 if (msg_verbose) 224 msg_info("tls_proxy_client_param_scan ret=%d", ret); 225 return (ret); 226 } 227 228 /* tls_proxy_client_init_free - destroy TLS_CLIENT_INIT_PROPS structure */ 229 230 void tls_proxy_client_init_free(TLS_CLIENT_INIT_PROPS *props) 231 { 232 myfree((void *) props->log_param); 233 myfree((void *) props->log_level); 234 myfree((void *) props->cache_type); 235 myfree((void *) props->chain_files); 236 myfree((void *) props->cert_file); 237 myfree((void *) props->key_file); 238 myfree((void *) props->dcert_file); 239 myfree((void *) props->dkey_file); 240 myfree((void *) props->eccert_file); 241 myfree((void *) props->eckey_file); 242 myfree((void *) props->CAfile); 243 myfree((void *) props->CApath); 244 myfree((void *) props->mdalg); 245 myfree((void *) props); 246 } 247 248 /* tls_proxy_client_init_scan - receive TLS_CLIENT_INIT_PROPS from stream */ 249 250 int tls_proxy_client_init_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp, 251 int flags, void *ptr) 252 { 253 TLS_CLIENT_INIT_PROPS *props 254 = (TLS_CLIENT_INIT_PROPS *) mymalloc(sizeof(*props)); 255 int ret; 256 VSTRING *log_param = vstring_alloc(25); 257 VSTRING *log_level = vstring_alloc(25); 258 VSTRING *cache_type = vstring_alloc(25); 259 VSTRING *chain_files = vstring_alloc(25); 260 VSTRING *cert_file = vstring_alloc(25); 261 VSTRING *key_file = vstring_alloc(25); 262 VSTRING *dcert_file = vstring_alloc(25); 263 VSTRING *dkey_file = vstring_alloc(25); 264 VSTRING *eccert_file = vstring_alloc(25); 265 VSTRING *eckey_file = vstring_alloc(25); 266 VSTRING *CAfile = vstring_alloc(25); 267 VSTRING *CApath = vstring_alloc(25); 268 VSTRING *mdalg = vstring_alloc(25); 269 270 if (msg_verbose) 271 msg_info("begin tls_proxy_client_init_scan"); 272 273 /* 274 * Note: memset() is not a portable way to initialize non-integer types. 275 */ 276 memset(props, 0, sizeof(*props)); 277 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 278 RECV_ATTR_STR(TLS_ATTR_LOG_PARAM, log_param), 279 RECV_ATTR_STR(TLS_ATTR_LOG_LEVEL, log_level), 280 RECV_ATTR_INT(TLS_ATTR_VERIFYDEPTH, &props->verifydepth), 281 RECV_ATTR_STR(TLS_ATTR_CACHE_TYPE, cache_type), 282 RECV_ATTR_STR(TLS_ATTR_CHAIN_FILES, chain_files), 283 RECV_ATTR_STR(TLS_ATTR_CERT_FILE, cert_file), 284 RECV_ATTR_STR(TLS_ATTR_KEY_FILE, key_file), 285 RECV_ATTR_STR(TLS_ATTR_DCERT_FILE, dcert_file), 286 RECV_ATTR_STR(TLS_ATTR_DKEY_FILE, dkey_file), 287 RECV_ATTR_STR(TLS_ATTR_ECCERT_FILE, eccert_file), 288 RECV_ATTR_STR(TLS_ATTR_ECKEY_FILE, eckey_file), 289 RECV_ATTR_STR(TLS_ATTR_CAFILE, CAfile), 290 RECV_ATTR_STR(TLS_ATTR_CAPATH, CApath), 291 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg), 292 ATTR_TYPE_END); 293 /* Always construct a well-formed structure. */ 294 props->log_param = vstring_export(log_param); 295 props->log_level = vstring_export(log_level); 296 props->cache_type = vstring_export(cache_type); 297 props->chain_files = vstring_export(chain_files); 298 props->cert_file = vstring_export(cert_file); 299 props->key_file = vstring_export(key_file); 300 props->dcert_file = vstring_export(dcert_file); 301 props->dkey_file = vstring_export(dkey_file); 302 props->eccert_file = vstring_export(eccert_file); 303 props->eckey_file = vstring_export(eckey_file); 304 props->CAfile = vstring_export(CAfile); 305 props->CApath = vstring_export(CApath); 306 props->mdalg = vstring_export(mdalg); 307 ret = (ret == 14 ? 1 : -1); 308 if (ret != 1) { 309 tls_proxy_client_init_free(props); 310 props = 0; 311 } 312 *(TLS_CLIENT_INIT_PROPS **) ptr = props; 313 if (msg_verbose) 314 msg_info("tls_proxy_client_init_scan ret=%d", ret); 315 return (ret); 316 } 317 318 /* tls_proxy_client_start_free - destroy TLS_CLIENT_START_PROPS structure */ 319 320 void tls_proxy_client_start_free(TLS_CLIENT_START_PROPS *props) 321 { 322 myfree((void *) props->nexthop); 323 myfree((void *) props->host); 324 myfree((void *) props->namaddr); 325 myfree((void *) props->sni); 326 myfree((void *) props->serverid); 327 myfree((void *) props->helo); 328 myfree((void *) props->protocols); 329 myfree((void *) props->cipher_grade); 330 myfree((void *) props->cipher_exclusions); 331 if (props->matchargv) 332 argv_free((ARGV *) props->matchargv); 333 myfree((void *) props->mdalg); 334 if (props->dane) 335 tls_dane_free((TLS_DANE *) props->dane); 336 #ifdef USE_TLSRPT 337 if (props->tlsrpt) 338 trw_free(props->tlsrpt); 339 #endif 340 if (props->ffail_type) 341 myfree(props->ffail_type); 342 myfree((void *) props); 343 } 344 345 /* tls_proxy_client_tlsa_scan - receive TLS_TLSA from stream */ 346 347 static int tls_proxy_client_tlsa_scan(ATTR_SCAN_COMMON_FN scan_fn, 348 VSTREAM *fp, int flags, void *ptr) 349 { 350 static VSTRING *data; 351 TLS_TLSA *head; 352 int count; 353 int ret; 354 355 if (data == 0) 356 data = vstring_alloc(64); 357 358 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 359 RECV_ATTR_INT(TLS_ATTR_COUNT, &count), 360 ATTR_TYPE_END); 361 if (ret == 1 && msg_verbose) 362 msg_info("tls_proxy_client_tlsa_scan count=%d", count); 363 364 for (head = 0; ret == 1 && count > 0; --count) { 365 int u, s, m; 366 367 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 368 RECV_ATTR_INT(TLS_ATTR_USAGE, &u), 369 RECV_ATTR_INT(TLS_ATTR_SELECTOR, &s), 370 RECV_ATTR_INT(TLS_ATTR_MTYPE, &m), 371 RECV_ATTR_DATA(TLS_ATTR_DATA, data), 372 ATTR_TYPE_END); 373 if (ret == 4) { 374 ret = 1; 375 /* This makes a copy of the static vstring content */ 376 head = tlsa_prepend(head, u, s, m, (unsigned char *) STR(data), 377 LEN(data)); 378 } else 379 ret = -1; 380 } 381 382 if (ret != 1) { 383 tls_tlsa_free(head); 384 head = 0; 385 } 386 *(TLS_TLSA **) ptr = head; 387 if (msg_verbose) 388 msg_info("tls_proxy_client_tlsa_scan ret=%d", ret); 389 return (ret); 390 } 391 392 /* tls_proxy_client_dane_scan - receive TLS_DANE from stream */ 393 394 static int tls_proxy_client_dane_scan(ATTR_SCAN_COMMON_FN scan_fn, 395 VSTREAM *fp, int flags, void *ptr) 396 { 397 TLS_DANE *dane = 0; 398 int ret; 399 int have_dane = 0; 400 401 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 402 RECV_ATTR_INT(TLS_ATTR_DANE, &have_dane), 403 ATTR_TYPE_END); 404 if (msg_verbose) 405 msg_info("tls_proxy_client_dane_scan have_dane=%d", have_dane); 406 407 if (ret == 1 && have_dane) { 408 VSTRING *base_domain = vstring_alloc(25); 409 410 dane = tls_dane_alloc(); 411 /* We only need the base domain and TLSA RRs */ 412 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 413 RECV_ATTR_STR(TLS_ATTR_DOMAIN, base_domain), 414 RECV_ATTR_FUNC(tls_proxy_client_tlsa_scan, 415 &dane->tlsa), 416 ATTR_TYPE_END); 417 418 /* Always construct a well-formed structure. */ 419 dane->base_domain = vstring_export(base_domain); 420 ret = (ret == 2 ? 1 : -1); 421 if (ret != 1) { 422 tls_dane_free(dane); 423 dane = 0; 424 } 425 } 426 *(TLS_DANE **) ptr = dane; 427 if (msg_verbose) 428 msg_info("tls_proxy_client_dane_scan ret=%d", ret); 429 return (ret); 430 } 431 432 #define EXPORT_OR_NULL(str, vstr) do { \ 433 if (LEN(vstr) > 0) { \ 434 (str) = vstring_export(vstr); \ 435 } else { \ 436 (str) = 0; \ 437 vstring_free(vstr); \ 438 } \ 439 } while (0) 440 441 #ifdef USE_TLSRPT 442 443 /* tls_proxy_client_tlsrpt_scan - receive TLSRPT_WRAPPER from stream */ 444 445 static int tls_proxy_client_tlsrpt_scan(ATTR_SCAN_COMMON_FN scan_fn, 446 VSTREAM *fp, int flags, void *ptr) 447 { 448 TLSRPT_WRAPPER *trw = 0; 449 int ret; 450 int have_tlsrpt = 0; 451 452 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 453 RECV_ATTR_INT(TLS_ATTR_TLSRPT, &have_tlsrpt), 454 ATTR_TYPE_END); 455 if (msg_verbose) 456 msg_info("tls_proxy_client_tlsrpt_scan have_tlsrpt=%d", have_tlsrpt); 457 458 if (ret == 1 && have_tlsrpt) { 459 VSTRING *rpt_socket_name = vstring_alloc(100); 460 VSTRING *rpt_policy_domain = vstring_alloc(100); 461 VSTRING *rpt_policy_string = vstring_alloc(100); 462 int tls_policy_type; 463 ARGV *tls_policy_strings = 0; 464 VSTRING *tls_policy_domain = vstring_alloc(100); 465 ARGV *mx_host_patterns = 0; 466 VSTRING *snd_mta_addr = vstring_alloc(100); 467 VSTRING *rcv_mta_name = vstring_alloc(100); 468 VSTRING *rcv_mta_addr = vstring_alloc(100); 469 VSTRING *rcv_mta_ehlo = vstring_alloc(100); 470 int skip_reused_hs; 471 int trw_flags; 472 473 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 474 RECV_ATTR_STR(TRW_RPT_SOCKET_NAME, rpt_socket_name), 475 RECV_ATTR_STR(TRW_RPT_POLICY_DOMAIN, rpt_policy_domain), 476 RECV_ATTR_STR(TRW_RPT_POLICY_STRING, rpt_policy_string), 477 RECV_ATTR_INT(TRW_TLS_POLICY_TYPE, &tls_policy_type), 478 RECV_ATTR_FUNC(argv_attr_scan, &tls_policy_strings), 479 RECV_ATTR_STR(TRW_TLS_POLICY_DOMAIN, tls_policy_domain), 480 RECV_ATTR_FUNC(argv_attr_scan, &mx_host_patterns), 481 RECV_ATTR_STR(TRW_SRC_MTA_ADDR, snd_mta_addr), 482 RECV_ATTR_STR(TRW_DST_MTA_NAME, rcv_mta_name), 483 RECV_ATTR_STR(TRW_DST_MTA_ADDR, rcv_mta_addr), 484 RECV_ATTR_STR(TRW_DST_MTA_EHLO, rcv_mta_ehlo), 485 RECV_ATTR_INT(TRW_SKIP_REUSED_HS, &skip_reused_hs), 486 RECV_ATTR_INT(TRW_FLAGS, &trw_flags), 487 ATTR_TYPE_END); 488 489 /* Always construct a well-formed structure. */ 490 trw = (TLSRPT_WRAPPER *) mymalloc(sizeof(*trw)); 491 trw->rpt_socket_name = vstring_export(rpt_socket_name); 492 trw->rpt_policy_domain = vstring_export(rpt_policy_domain); 493 trw->rpt_policy_string = vstring_export(rpt_policy_string); 494 trw->tls_policy_type = tls_policy_type; 495 trw->tls_policy_strings = tls_policy_strings; 496 EXPORT_OR_NULL(trw->tls_policy_domain, tls_policy_domain); 497 trw->mx_host_patterns = mx_host_patterns; 498 EXPORT_OR_NULL(trw->snd_mta_addr, snd_mta_addr); 499 EXPORT_OR_NULL(trw->rcv_mta_name, rcv_mta_name); 500 EXPORT_OR_NULL(trw->rcv_mta_addr, rcv_mta_addr); 501 EXPORT_OR_NULL(trw->rcv_mta_ehlo, rcv_mta_ehlo); 502 trw->skip_reused_hs = skip_reused_hs; 503 trw->flags = trw_flags; 504 ret = (ret == 13 ? 1 : -1); 505 if (ret != 1) { 506 trw_free(trw); 507 trw = 0; 508 } 509 } 510 *(TLSRPT_WRAPPER **) ptr = trw; 511 if (msg_verbose) 512 msg_info("tls_proxy_client_tlsrpt_scan ret=%d", ret); 513 return (ret); 514 } 515 516 #endif 517 518 /* tls_proxy_client_start_scan - receive TLS_CLIENT_START_PROPS from stream */ 519 520 int tls_proxy_client_start_scan(ATTR_SCAN_COMMON_FN scan_fn, VSTREAM *fp, 521 int flags, void *ptr) 522 { 523 TLS_CLIENT_START_PROPS *props 524 = (TLS_CLIENT_START_PROPS *) mymalloc(sizeof(*props)); 525 int ret; 526 VSTRING *nexthop = vstring_alloc(25); 527 VSTRING *host = vstring_alloc(25); 528 VSTRING *namaddr = vstring_alloc(25); 529 VSTRING *sni = vstring_alloc(25); 530 VSTRING *serverid = vstring_alloc(25); 531 VSTRING *helo = vstring_alloc(25); 532 VSTRING *protocols = vstring_alloc(25); 533 VSTRING *cipher_grade = vstring_alloc(25); 534 VSTRING *cipher_exclusions = vstring_alloc(25); 535 VSTRING *mdalg = vstring_alloc(25); 536 VSTRING *ffail_type = vstring_alloc(25); 537 538 #ifdef USE_TLSRPT 539 #define EXPECT_START_SCAN_RETURN 17 540 #else 541 #define EXPECT_START_SCAN_RETURN 16 542 #endif 543 544 if (msg_verbose) 545 msg_info("begin tls_proxy_client_start_scan"); 546 547 /* 548 * Note: memset() is not a portable way to initialize non-integer types. 549 */ 550 memset(props, 0, sizeof(*props)); 551 props->ctx = 0; 552 props->stream = 0; 553 props->fd = -1; 554 props->dane = 0; /* scan_fn may return early */ 555 ret = scan_fn(fp, flags | ATTR_FLAG_MORE, 556 RECV_ATTR_INT(TLS_ATTR_TIMEOUT, &props->timeout), 557 RECV_ATTR_INT(TLS_ATTR_ENABLE_RPK, &props->enable_rpk), 558 RECV_ATTR_INT(TLS_ATTR_TLS_LEVEL, &props->tls_level), 559 RECV_ATTR_STR(TLS_ATTR_NEXTHOP, nexthop), 560 RECV_ATTR_STR(TLS_ATTR_HOST, host), 561 RECV_ATTR_STR(TLS_ATTR_NAMADDR, namaddr), 562 RECV_ATTR_STR(TLS_ATTR_SNI, sni), 563 RECV_ATTR_STR(TLS_ATTR_SERVERID, serverid), 564 RECV_ATTR_STR(TLS_ATTR_HELO, helo), 565 RECV_ATTR_STR(TLS_ATTR_PROTOCOLS, protocols), 566 RECV_ATTR_STR(TLS_ATTR_CIPHER_GRADE, cipher_grade), 567 RECV_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS, 568 cipher_exclusions), 569 RECV_ATTR_FUNC(argv_attr_scan, &props->matchargv), 570 RECV_ATTR_STR(TLS_ATTR_MDALG, mdalg), 571 RECV_ATTR_FUNC(tls_proxy_client_dane_scan, 572 &props->dane), 573 #ifdef USE_TLSRPT 574 RECV_ATTR_FUNC(tls_proxy_client_tlsrpt_scan, 575 &props->tlsrpt), 576 #endif 577 RECV_ATTR_STR(TLS_ATTR_FFAIL_TYPE, ffail_type), 578 ATTR_TYPE_END); 579 /* Always construct a well-formed structure. */ 580 props->nexthop = vstring_export(nexthop); 581 props->host = vstring_export(host); 582 props->namaddr = vstring_export(namaddr); 583 props->sni = vstring_export(sni); 584 props->serverid = vstring_export(serverid); 585 props->helo = vstring_export(helo); 586 props->protocols = vstring_export(protocols); 587 props->cipher_grade = vstring_export(cipher_grade); 588 props->cipher_exclusions = vstring_export(cipher_exclusions); 589 props->mdalg = vstring_export(mdalg); 590 EXPORT_OR_NULL(props->ffail_type, ffail_type); 591 ret = (ret == EXPECT_START_SCAN_RETURN ? 1 : -1); 592 if (ret != 1) { 593 tls_proxy_client_start_free(props); 594 props = 0; 595 } 596 *(TLS_CLIENT_START_PROPS **) ptr = props; 597 if (msg_verbose) 598 msg_info("tls_proxy_client_start_scan ret=%d", ret); 599 return (ret); 600 } 601 602 #endif 603