1 /* 2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #define OPENSSL_SUPPRESS_DEPRECATED 11 12 #include <stdio.h> 13 #include <errno.h> 14 #include "bio_local.h" 15 16 #ifndef OPENSSL_NO_SOCK 17 18 typedef struct bio_accept_st { 19 int state; 20 int accept_family; 21 int bind_mode; /* Socket mode for BIO_listen */ 22 int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */ 23 char *param_addr; 24 char *param_serv; 25 26 int accept_sock; 27 28 BIO_ADDRINFO *addr_first; 29 const BIO_ADDRINFO *addr_iter; 30 BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */ 31 char *cache_accepting_name, *cache_accepting_serv; 32 BIO_ADDR cache_peer_addr; 33 char *cache_peer_name, *cache_peer_serv; 34 35 BIO *bio_chain; 36 } BIO_ACCEPT; 37 38 static int acpt_write(BIO *h, const char *buf, int num); 39 static int acpt_read(BIO *h, char *buf, int size); 40 static int acpt_puts(BIO *h, const char *str); 41 static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2); 42 static int acpt_new(BIO *h); 43 static int acpt_free(BIO *data); 44 static int acpt_state(BIO *b, BIO_ACCEPT *c); 45 static void acpt_close_socket(BIO *data); 46 static BIO_ACCEPT *BIO_ACCEPT_new(void); 47 static void BIO_ACCEPT_free(BIO_ACCEPT *a); 48 49 # define ACPT_S_BEFORE 1 50 # define ACPT_S_GET_ADDR 2 51 # define ACPT_S_CREATE_SOCKET 3 52 # define ACPT_S_LISTEN 4 53 # define ACPT_S_ACCEPT 5 54 # define ACPT_S_OK 6 55 56 static const BIO_METHOD methods_acceptp = { 57 BIO_TYPE_ACCEPT, 58 "socket accept", 59 bwrite_conv, 60 acpt_write, 61 bread_conv, 62 acpt_read, 63 acpt_puts, 64 NULL, /* connect_gets, */ 65 acpt_ctrl, 66 acpt_new, 67 acpt_free, 68 NULL, /* connect_callback_ctrl */ 69 }; 70 71 const BIO_METHOD *BIO_s_accept(void) 72 { 73 return &methods_acceptp; 74 } 75 76 static int acpt_new(BIO *bi) 77 { 78 BIO_ACCEPT *ba; 79 80 bi->init = 0; 81 bi->num = (int)INVALID_SOCKET; 82 bi->flags = 0; 83 if ((ba = BIO_ACCEPT_new()) == NULL) 84 return 0; 85 bi->ptr = (char *)ba; 86 ba->state = ACPT_S_BEFORE; 87 bi->shutdown = 1; 88 return 1; 89 } 90 91 static BIO_ACCEPT *BIO_ACCEPT_new(void) 92 { 93 BIO_ACCEPT *ret; 94 95 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { 96 ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); 97 return NULL; 98 } 99 ret->accept_family = BIO_FAMILY_IPANY; 100 ret->accept_sock = (int)INVALID_SOCKET; 101 return ret; 102 } 103 104 static void BIO_ACCEPT_free(BIO_ACCEPT *a) 105 { 106 if (a == NULL) 107 return; 108 OPENSSL_free(a->param_addr); 109 OPENSSL_free(a->param_serv); 110 BIO_ADDRINFO_free(a->addr_first); 111 OPENSSL_free(a->cache_accepting_name); 112 OPENSSL_free(a->cache_accepting_serv); 113 OPENSSL_free(a->cache_peer_name); 114 OPENSSL_free(a->cache_peer_serv); 115 BIO_free(a->bio_chain); 116 OPENSSL_free(a); 117 } 118 119 static void acpt_close_socket(BIO *bio) 120 { 121 BIO_ACCEPT *c; 122 123 c = (BIO_ACCEPT *)bio->ptr; 124 if (c->accept_sock != (int)INVALID_SOCKET) { 125 shutdown(c->accept_sock, 2); 126 closesocket(c->accept_sock); 127 c->accept_sock = (int)INVALID_SOCKET; 128 bio->num = (int)INVALID_SOCKET; 129 } 130 } 131 132 static int acpt_free(BIO *a) 133 { 134 BIO_ACCEPT *data; 135 136 if (a == NULL) 137 return 0; 138 data = (BIO_ACCEPT *)a->ptr; 139 140 if (a->shutdown) { 141 acpt_close_socket(a); 142 BIO_ACCEPT_free(data); 143 a->ptr = NULL; 144 a->flags = 0; 145 a->init = 0; 146 } 147 return 1; 148 } 149 150 static int acpt_state(BIO *b, BIO_ACCEPT *c) 151 { 152 BIO *bio = NULL, *dbio; 153 int s = -1, ret = -1; 154 155 for (;;) { 156 switch (c->state) { 157 case ACPT_S_BEFORE: 158 if (c->param_addr == NULL && c->param_serv == NULL) { 159 ERR_raise_data(ERR_LIB_BIO, 160 BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED, 161 "hostname=%s, service=%s", 162 c->param_addr, c->param_serv); 163 goto exit_loop; 164 } 165 166 /* Because we're starting a new bind, any cached name and serv 167 * are now obsolete and need to be cleaned out. 168 * QUESTION: should this be done in acpt_close_socket() instead? 169 */ 170 OPENSSL_free(c->cache_accepting_name); 171 c->cache_accepting_name = NULL; 172 OPENSSL_free(c->cache_accepting_serv); 173 c->cache_accepting_serv = NULL; 174 OPENSSL_free(c->cache_peer_name); 175 c->cache_peer_name = NULL; 176 OPENSSL_free(c->cache_peer_serv); 177 c->cache_peer_serv = NULL; 178 179 c->state = ACPT_S_GET_ADDR; 180 break; 181 182 case ACPT_S_GET_ADDR: 183 { 184 int family = AF_UNSPEC; 185 switch (c->accept_family) { 186 case BIO_FAMILY_IPV6: 187 if (1) { /* This is a trick we use to avoid bit rot. 188 * at least the "else" part will always be 189 * compiled. 190 */ 191 #ifdef AF_INET6 192 family = AF_INET6; 193 } else { 194 #endif 195 ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY); 196 goto exit_loop; 197 } 198 break; 199 case BIO_FAMILY_IPV4: 200 family = AF_INET; 201 break; 202 case BIO_FAMILY_IPANY: 203 family = AF_UNSPEC; 204 break; 205 default: 206 ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY); 207 goto exit_loop; 208 } 209 if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER, 210 family, SOCK_STREAM, &c->addr_first) == 0) 211 goto exit_loop; 212 } 213 if (c->addr_first == NULL) { 214 ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING); 215 goto exit_loop; 216 } 217 c->addr_iter = c->addr_first; 218 c->state = ACPT_S_CREATE_SOCKET; 219 break; 220 221 case ACPT_S_CREATE_SOCKET: 222 ERR_set_mark(); 223 s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter), 224 BIO_ADDRINFO_socktype(c->addr_iter), 225 BIO_ADDRINFO_protocol(c->addr_iter), 0); 226 if (s == (int)INVALID_SOCKET) { 227 if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) { 228 /* 229 * if there are more addresses to try, do that first 230 */ 231 ERR_pop_to_mark(); 232 break; 233 } 234 ERR_clear_last_mark(); 235 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(), 236 "calling socket(%s, %s)", 237 c->param_addr, c->param_serv); 238 ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); 239 goto exit_loop; 240 } 241 c->accept_sock = s; 242 b->num = s; 243 c->state = ACPT_S_LISTEN; 244 s = -1; 245 break; 246 247 case ACPT_S_LISTEN: 248 { 249 if (!BIO_listen(c->accept_sock, 250 BIO_ADDRINFO_address(c->addr_iter), 251 c->bind_mode)) { 252 BIO_closesocket(c->accept_sock); 253 goto exit_loop; 254 } 255 } 256 257 { 258 union BIO_sock_info_u info; 259 260 info.addr = &c->cache_accepting_addr; 261 if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS, 262 &info)) { 263 BIO_closesocket(c->accept_sock); 264 goto exit_loop; 265 } 266 } 267 268 c->cache_accepting_name = 269 BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1); 270 c->cache_accepting_serv = 271 BIO_ADDR_service_string(&c->cache_accepting_addr, 1); 272 c->state = ACPT_S_ACCEPT; 273 s = -1; 274 ret = 1; 275 goto end; 276 277 case ACPT_S_ACCEPT: 278 if (b->next_bio != NULL) { 279 c->state = ACPT_S_OK; 280 break; 281 } 282 BIO_clear_retry_flags(b); 283 b->retry_reason = 0; 284 285 OPENSSL_free(c->cache_peer_name); 286 c->cache_peer_name = NULL; 287 OPENSSL_free(c->cache_peer_serv); 288 c->cache_peer_serv = NULL; 289 290 s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr, 291 c->accepted_mode); 292 293 /* If the returned socket is invalid, this might still be 294 * retryable 295 */ 296 if (s < 0) { 297 if (BIO_sock_should_retry(s)) { 298 BIO_set_retry_special(b); 299 b->retry_reason = BIO_RR_ACCEPT; 300 goto end; 301 } 302 } 303 304 /* If it wasn't retryable, we fail */ 305 if (s < 0) { 306 ret = s; 307 goto exit_loop; 308 } 309 310 bio = BIO_new_socket(s, BIO_CLOSE); 311 if (bio == NULL) 312 goto exit_loop; 313 314 BIO_set_callback_ex(bio, BIO_get_callback_ex(b)); 315 #ifndef OPENSSL_NO_DEPRECATED_3_0 316 BIO_set_callback(bio, BIO_get_callback(b)); 317 #endif 318 BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); 319 /* 320 * If the accept BIO has an bio_chain, we dup it and put the new 321 * socket at the end. 322 */ 323 if (c->bio_chain != NULL) { 324 if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) 325 goto exit_loop; 326 if (!BIO_push(dbio, bio)) 327 goto exit_loop; 328 bio = dbio; 329 } 330 if (BIO_push(b, bio) == NULL) 331 goto exit_loop; 332 333 c->cache_peer_name = 334 BIO_ADDR_hostname_string(&c->cache_peer_addr, 1); 335 c->cache_peer_serv = 336 BIO_ADDR_service_string(&c->cache_peer_addr, 1); 337 c->state = ACPT_S_OK; 338 bio = NULL; 339 ret = 1; 340 goto end; 341 342 case ACPT_S_OK: 343 if (b->next_bio == NULL) { 344 c->state = ACPT_S_ACCEPT; 345 break; 346 } 347 ret = 1; 348 goto end; 349 350 default: 351 ret = 0; 352 goto end; 353 } 354 } 355 356 exit_loop: 357 if (bio != NULL) 358 BIO_free(bio); 359 else if (s >= 0) 360 BIO_closesocket(s); 361 end: 362 return ret; 363 } 364 365 static int acpt_read(BIO *b, char *out, int outl) 366 { 367 int ret = 0; 368 BIO_ACCEPT *data; 369 370 BIO_clear_retry_flags(b); 371 data = (BIO_ACCEPT *)b->ptr; 372 373 while (b->next_bio == NULL) { 374 ret = acpt_state(b, data); 375 if (ret <= 0) 376 return ret; 377 } 378 379 ret = BIO_read(b->next_bio, out, outl); 380 BIO_copy_next_retry(b); 381 return ret; 382 } 383 384 static int acpt_write(BIO *b, const char *in, int inl) 385 { 386 int ret; 387 BIO_ACCEPT *data; 388 389 BIO_clear_retry_flags(b); 390 data = (BIO_ACCEPT *)b->ptr; 391 392 while (b->next_bio == NULL) { 393 ret = acpt_state(b, data); 394 if (ret <= 0) 395 return ret; 396 } 397 398 ret = BIO_write(b->next_bio, in, inl); 399 BIO_copy_next_retry(b); 400 return ret; 401 } 402 403 static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) 404 { 405 int *ip; 406 long ret = 1; 407 BIO_ACCEPT *data; 408 char **pp; 409 410 data = (BIO_ACCEPT *)b->ptr; 411 412 switch (cmd) { 413 case BIO_CTRL_RESET: 414 ret = 0; 415 data->state = ACPT_S_BEFORE; 416 acpt_close_socket(b); 417 BIO_ADDRINFO_free(data->addr_first); 418 data->addr_first = NULL; 419 b->flags = 0; 420 break; 421 case BIO_C_DO_STATE_MACHINE: 422 /* use this one to start the connection */ 423 ret = (long)acpt_state(b, data); 424 break; 425 case BIO_C_SET_ACCEPT: 426 if (ptr != NULL) { 427 if (num == 0) { 428 char *hold_serv = data->param_serv; 429 /* We affect the hostname regardless. However, the input 430 * string might contain a host:service spec, so we must 431 * parse it, which might or might not affect the service 432 */ 433 OPENSSL_free(data->param_addr); 434 data->param_addr = NULL; 435 ret = BIO_parse_hostserv(ptr, 436 &data->param_addr, 437 &data->param_serv, 438 BIO_PARSE_PRIO_SERV); 439 if (hold_serv != data->param_serv) 440 OPENSSL_free(hold_serv); 441 b->init = 1; 442 } else if (num == 1) { 443 OPENSSL_free(data->param_serv); 444 if ((data->param_serv = OPENSSL_strdup(ptr)) == NULL) 445 ret = 0; 446 else 447 b->init = 1; 448 } else if (num == 2) { 449 data->bind_mode |= BIO_SOCK_NONBLOCK; 450 } else if (num == 3) { 451 BIO_free(data->bio_chain); 452 data->bio_chain = (BIO *)ptr; 453 } else if (num == 4) { 454 data->accept_family = *(int *)ptr; 455 } 456 } else { 457 if (num == 2) { 458 data->bind_mode &= ~BIO_SOCK_NONBLOCK; 459 } 460 } 461 break; 462 case BIO_C_SET_NBIO: 463 if (num != 0) 464 data->accepted_mode |= BIO_SOCK_NONBLOCK; 465 else 466 data->accepted_mode &= ~BIO_SOCK_NONBLOCK; 467 break; 468 case BIO_C_SET_FD: 469 b->num = *((int *)ptr); 470 data->accept_sock = b->num; 471 data->state = ACPT_S_ACCEPT; 472 b->shutdown = (int)num; 473 b->init = 1; 474 break; 475 case BIO_C_GET_FD: 476 if (b->init) { 477 ip = (int *)ptr; 478 if (ip != NULL) 479 *ip = data->accept_sock; 480 ret = data->accept_sock; 481 } else 482 ret = -1; 483 break; 484 case BIO_C_GET_ACCEPT: 485 if (b->init) { 486 if (num == 0 && ptr != NULL) { 487 pp = (char **)ptr; 488 *pp = data->cache_accepting_name; 489 } else if (num == 1 && ptr != NULL) { 490 pp = (char **)ptr; 491 *pp = data->cache_accepting_serv; 492 } else if (num == 2 && ptr != NULL) { 493 pp = (char **)ptr; 494 *pp = data->cache_peer_name; 495 } else if (num == 3 && ptr != NULL) { 496 pp = (char **)ptr; 497 *pp = data->cache_peer_serv; 498 } else if (num == 4) { 499 switch (BIO_ADDRINFO_family(data->addr_iter)) { 500 #ifdef AF_INET6 501 case AF_INET6: 502 ret = BIO_FAMILY_IPV6; 503 break; 504 #endif 505 case AF_INET: 506 ret = BIO_FAMILY_IPV4; 507 break; 508 case 0: 509 ret = data->accept_family; 510 break; 511 default: 512 ret = -1; 513 break; 514 } 515 } else 516 ret = -1; 517 } else 518 ret = -1; 519 break; 520 case BIO_CTRL_GET_CLOSE: 521 ret = b->shutdown; 522 break; 523 case BIO_CTRL_SET_CLOSE: 524 b->shutdown = (int)num; 525 break; 526 case BIO_CTRL_PENDING: 527 case BIO_CTRL_WPENDING: 528 ret = 0; 529 break; 530 case BIO_CTRL_FLUSH: 531 break; 532 case BIO_C_SET_BIND_MODE: 533 data->bind_mode = (int)num; 534 break; 535 case BIO_C_GET_BIND_MODE: 536 ret = (long)data->bind_mode; 537 break; 538 case BIO_CTRL_DUP: 539 break; 540 case BIO_CTRL_EOF: 541 if (b->next_bio == NULL) 542 ret = 0; 543 else 544 ret = BIO_ctrl(b->next_bio, cmd, num, ptr); 545 break; 546 default: 547 ret = 0; 548 break; 549 } 550 return ret; 551 } 552 553 static int acpt_puts(BIO *bp, const char *str) 554 { 555 int n, ret; 556 557 n = strlen(str); 558 ret = acpt_write(bp, str, n); 559 return ret; 560 } 561 562 BIO *BIO_new_accept(const char *str) 563 { 564 BIO *ret; 565 566 ret = BIO_new(BIO_s_accept()); 567 if (ret == NULL) 568 return NULL; 569 if (BIO_set_accept_name(ret, str) > 0) 570 return ret; 571 BIO_free(ret); 572 return NULL; 573 } 574 575 #endif 576