1 /* 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 #include <stdio.h> 11 #include <errno.h> 12 #include "bio_local.h" 13 14 #ifndef OPENSSL_NO_SOCK 15 16 typedef struct bio_accept_st { 17 int state; 18 int accept_family; 19 int bind_mode; /* Socket mode for BIO_listen */ 20 int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */ 21 char *param_addr; 22 char *param_serv; 23 24 int accept_sock; 25 26 BIO_ADDRINFO *addr_first; 27 const BIO_ADDRINFO *addr_iter; 28 BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */ 29 char *cache_accepting_name, *cache_accepting_serv; 30 BIO_ADDR cache_peer_addr; 31 char *cache_peer_name, *cache_peer_serv; 32 33 BIO *bio_chain; 34 } BIO_ACCEPT; 35 36 static int acpt_write(BIO *h, const char *buf, int num); 37 static int acpt_read(BIO *h, char *buf, int size); 38 static int acpt_puts(BIO *h, const char *str); 39 static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2); 40 static int acpt_new(BIO *h); 41 static int acpt_free(BIO *data); 42 static int acpt_state(BIO *b, BIO_ACCEPT *c); 43 static void acpt_close_socket(BIO *data); 44 static BIO_ACCEPT *BIO_ACCEPT_new(void); 45 static void BIO_ACCEPT_free(BIO_ACCEPT *a); 46 47 # define ACPT_S_BEFORE 1 48 # define ACPT_S_GET_ADDR 2 49 # define ACPT_S_CREATE_SOCKET 3 50 # define ACPT_S_LISTEN 4 51 # define ACPT_S_ACCEPT 5 52 # define ACPT_S_OK 6 53 54 static const BIO_METHOD methods_acceptp = { 55 BIO_TYPE_ACCEPT, 56 "socket accept", 57 /* TODO: Convert to new style write function */ 58 bwrite_conv, 59 acpt_write, 60 /* TODO: Convert to new style read function */ 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 BIOerr(BIO_F_BIO_ACCEPT_NEW, 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 BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED); 160 ERR_add_error_data(4, 161 "hostname=", c->param_addr, 162 " service=", 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 BIOerr(BIO_F_ACPT_STATE, 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 BIOerr(BIO_F_ACPT_STATE, 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 BIOerr(BIO_F_ACPT_STATE, BIO_R_LOOKUP_RETURNED_NOTHING); 215 goto exit_loop; 216 } 217 /* We're currently not iterating, but set this as preparation 218 * for possible future development in that regard 219 */ 220 c->addr_iter = c->addr_first; 221 c->state = ACPT_S_CREATE_SOCKET; 222 break; 223 224 case ACPT_S_CREATE_SOCKET: 225 s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter), 226 BIO_ADDRINFO_socktype(c->addr_iter), 227 BIO_ADDRINFO_protocol(c->addr_iter), 0); 228 if (s == (int)INVALID_SOCKET) { 229 SYSerr(SYS_F_SOCKET, get_last_socket_error()); 230 ERR_add_error_data(4, 231 "hostname=", c->param_addr, 232 " service=", c->param_serv); 233 BIOerr(BIO_F_ACPT_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); 234 goto exit_loop; 235 } 236 c->accept_sock = s; 237 b->num = s; 238 c->state = ACPT_S_LISTEN; 239 s = -1; 240 break; 241 242 case ACPT_S_LISTEN: 243 { 244 if (!BIO_listen(c->accept_sock, 245 BIO_ADDRINFO_address(c->addr_iter), 246 c->bind_mode)) { 247 BIO_closesocket(c->accept_sock); 248 goto exit_loop; 249 } 250 } 251 252 { 253 union BIO_sock_info_u info; 254 255 info.addr = &c->cache_accepting_addr; 256 if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS, 257 &info)) { 258 BIO_closesocket(c->accept_sock); 259 goto exit_loop; 260 } 261 } 262 263 c->cache_accepting_name = 264 BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1); 265 c->cache_accepting_serv = 266 BIO_ADDR_service_string(&c->cache_accepting_addr, 1); 267 c->state = ACPT_S_ACCEPT; 268 s = -1; 269 ret = 1; 270 goto end; 271 272 case ACPT_S_ACCEPT: 273 if (b->next_bio != NULL) { 274 c->state = ACPT_S_OK; 275 break; 276 } 277 BIO_clear_retry_flags(b); 278 b->retry_reason = 0; 279 280 OPENSSL_free(c->cache_peer_name); 281 c->cache_peer_name = NULL; 282 OPENSSL_free(c->cache_peer_serv); 283 c->cache_peer_serv = NULL; 284 285 s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr, 286 c->accepted_mode); 287 288 /* If the returned socket is invalid, this might still be 289 * retryable 290 */ 291 if (s < 0) { 292 if (BIO_sock_should_retry(s)) { 293 BIO_set_retry_special(b); 294 b->retry_reason = BIO_RR_ACCEPT; 295 goto end; 296 } 297 } 298 299 /* If it wasn't retryable, we fail */ 300 if (s < 0) { 301 ret = s; 302 goto exit_loop; 303 } 304 305 bio = BIO_new_socket(s, BIO_CLOSE); 306 if (bio == NULL) 307 goto exit_loop; 308 309 BIO_set_callback(bio, BIO_get_callback(b)); 310 BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); 311 312 /* 313 * If the accept BIO has an bio_chain, we dup it and put the new 314 * socket at the end. 315 */ 316 if (c->bio_chain != NULL) { 317 if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) 318 goto exit_loop; 319 if (!BIO_push(dbio, bio)) 320 goto exit_loop; 321 bio = dbio; 322 } 323 if (BIO_push(b, bio) == NULL) 324 goto exit_loop; 325 326 c->cache_peer_name = 327 BIO_ADDR_hostname_string(&c->cache_peer_addr, 1); 328 c->cache_peer_serv = 329 BIO_ADDR_service_string(&c->cache_peer_addr, 1); 330 c->state = ACPT_S_OK; 331 bio = NULL; 332 ret = 1; 333 goto end; 334 335 case ACPT_S_OK: 336 if (b->next_bio == NULL) { 337 c->state = ACPT_S_ACCEPT; 338 break; 339 } 340 ret = 1; 341 goto end; 342 343 default: 344 ret = 0; 345 goto end; 346 } 347 } 348 349 exit_loop: 350 if (bio != NULL) 351 BIO_free(bio); 352 else if (s >= 0) 353 BIO_closesocket(s); 354 end: 355 return ret; 356 } 357 358 static int acpt_read(BIO *b, char *out, int outl) 359 { 360 int ret = 0; 361 BIO_ACCEPT *data; 362 363 BIO_clear_retry_flags(b); 364 data = (BIO_ACCEPT *)b->ptr; 365 366 while (b->next_bio == NULL) { 367 ret = acpt_state(b, data); 368 if (ret <= 0) 369 return ret; 370 } 371 372 ret = BIO_read(b->next_bio, out, outl); 373 BIO_copy_next_retry(b); 374 return ret; 375 } 376 377 static int acpt_write(BIO *b, const char *in, int inl) 378 { 379 int ret; 380 BIO_ACCEPT *data; 381 382 BIO_clear_retry_flags(b); 383 data = (BIO_ACCEPT *)b->ptr; 384 385 while (b->next_bio == NULL) { 386 ret = acpt_state(b, data); 387 if (ret <= 0) 388 return ret; 389 } 390 391 ret = BIO_write(b->next_bio, in, inl); 392 BIO_copy_next_retry(b); 393 return ret; 394 } 395 396 static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) 397 { 398 int *ip; 399 long ret = 1; 400 BIO_ACCEPT *data; 401 char **pp; 402 403 data = (BIO_ACCEPT *)b->ptr; 404 405 switch (cmd) { 406 case BIO_CTRL_RESET: 407 ret = 0; 408 data->state = ACPT_S_BEFORE; 409 acpt_close_socket(b); 410 BIO_ADDRINFO_free(data->addr_first); 411 data->addr_first = NULL; 412 b->flags = 0; 413 break; 414 case BIO_C_DO_STATE_MACHINE: 415 /* use this one to start the connection */ 416 ret = (long)acpt_state(b, data); 417 break; 418 case BIO_C_SET_ACCEPT: 419 if (ptr != NULL) { 420 if (num == 0) { 421 char *hold_serv = data->param_serv; 422 /* We affect the hostname regardless. However, the input 423 * string might contain a host:service spec, so we must 424 * parse it, which might or might not affect the service 425 */ 426 OPENSSL_free(data->param_addr); 427 data->param_addr = NULL; 428 ret = BIO_parse_hostserv(ptr, 429 &data->param_addr, 430 &data->param_serv, 431 BIO_PARSE_PRIO_SERV); 432 if (hold_serv != data->param_serv) 433 OPENSSL_free(hold_serv); 434 b->init = 1; 435 } else if (num == 1) { 436 OPENSSL_free(data->param_serv); 437 if ((data->param_serv = OPENSSL_strdup(ptr)) == NULL) 438 ret = 0; 439 else 440 b->init = 1; 441 } else if (num == 2) { 442 data->bind_mode |= BIO_SOCK_NONBLOCK; 443 } else if (num == 3) { 444 BIO_free(data->bio_chain); 445 data->bio_chain = (BIO *)ptr; 446 } else if (num == 4) { 447 data->accept_family = *(int *)ptr; 448 } 449 } else { 450 if (num == 2) { 451 data->bind_mode &= ~BIO_SOCK_NONBLOCK; 452 } 453 } 454 break; 455 case BIO_C_SET_NBIO: 456 if (num != 0) 457 data->accepted_mode |= BIO_SOCK_NONBLOCK; 458 else 459 data->accepted_mode &= ~BIO_SOCK_NONBLOCK; 460 break; 461 case BIO_C_SET_FD: 462 b->num = *((int *)ptr); 463 data->accept_sock = b->num; 464 data->state = ACPT_S_ACCEPT; 465 b->shutdown = (int)num; 466 b->init = 1; 467 break; 468 case BIO_C_GET_FD: 469 if (b->init) { 470 ip = (int *)ptr; 471 if (ip != NULL) 472 *ip = data->accept_sock; 473 ret = data->accept_sock; 474 } else 475 ret = -1; 476 break; 477 case BIO_C_GET_ACCEPT: 478 if (b->init) { 479 if (num == 0 && ptr != NULL) { 480 pp = (char **)ptr; 481 *pp = data->cache_accepting_name; 482 } else if (num == 1 && ptr != NULL) { 483 pp = (char **)ptr; 484 *pp = data->cache_accepting_serv; 485 } else if (num == 2 && ptr != NULL) { 486 pp = (char **)ptr; 487 *pp = data->cache_peer_name; 488 } else if (num == 3 && ptr != NULL) { 489 pp = (char **)ptr; 490 *pp = data->cache_peer_serv; 491 } else if (num == 4) { 492 switch (BIO_ADDRINFO_family(data->addr_iter)) { 493 #ifdef AF_INET6 494 case AF_INET6: 495 ret = BIO_FAMILY_IPV6; 496 break; 497 #endif 498 case AF_INET: 499 ret = BIO_FAMILY_IPV4; 500 break; 501 case 0: 502 ret = data->accept_family; 503 break; 504 default: 505 ret = -1; 506 break; 507 } 508 } else 509 ret = -1; 510 } else 511 ret = -1; 512 break; 513 case BIO_CTRL_GET_CLOSE: 514 ret = b->shutdown; 515 break; 516 case BIO_CTRL_SET_CLOSE: 517 b->shutdown = (int)num; 518 break; 519 case BIO_CTRL_PENDING: 520 case BIO_CTRL_WPENDING: 521 ret = 0; 522 break; 523 case BIO_CTRL_FLUSH: 524 break; 525 case BIO_C_SET_BIND_MODE: 526 data->bind_mode = (int)num; 527 break; 528 case BIO_C_GET_BIND_MODE: 529 ret = (long)data->bind_mode; 530 break; 531 case BIO_CTRL_DUP: 532 break; 533 case BIO_CTRL_EOF: 534 if (b->next_bio == NULL) 535 ret = 0; 536 else 537 ret = BIO_ctrl(b->next_bio, cmd, num, ptr); 538 break; 539 default: 540 ret = 0; 541 break; 542 } 543 return ret; 544 } 545 546 static int acpt_puts(BIO *bp, const char *str) 547 { 548 int n, ret; 549 550 n = strlen(str); 551 ret = acpt_write(bp, str, n); 552 return ret; 553 } 554 555 BIO *BIO_new_accept(const char *str) 556 { 557 BIO *ret; 558 559 ret = BIO_new(BIO_s_accept()); 560 if (ret == NULL) 561 return NULL; 562 if (BIO_set_accept_name(ret, str)) 563 return ret; 564 BIO_free(ret); 565 return NULL; 566 } 567 568 #endif 569