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 data->param_serv = BUF_strdup(ptr); 438 b->init = 1; 439 } else if (num == 2) { 440 data->bind_mode |= BIO_SOCK_NONBLOCK; 441 } else if (num == 3) { 442 BIO_free(data->bio_chain); 443 data->bio_chain = (BIO *)ptr; 444 } else if (num == 4) { 445 data->accept_family = *(int *)ptr; 446 } 447 } else { 448 if (num == 2) { 449 data->bind_mode &= ~BIO_SOCK_NONBLOCK; 450 } 451 } 452 break; 453 case BIO_C_SET_NBIO: 454 if (num != 0) 455 data->accepted_mode |= BIO_SOCK_NONBLOCK; 456 else 457 data->accepted_mode &= ~BIO_SOCK_NONBLOCK; 458 break; 459 case BIO_C_SET_FD: 460 b->num = *((int *)ptr); 461 data->accept_sock = b->num; 462 data->state = ACPT_S_ACCEPT; 463 b->shutdown = (int)num; 464 b->init = 1; 465 break; 466 case BIO_C_GET_FD: 467 if (b->init) { 468 ip = (int *)ptr; 469 if (ip != NULL) 470 *ip = data->accept_sock; 471 ret = data->accept_sock; 472 } else 473 ret = -1; 474 break; 475 case BIO_C_GET_ACCEPT: 476 if (b->init) { 477 if (num == 0 && ptr != NULL) { 478 pp = (char **)ptr; 479 *pp = data->cache_accepting_name; 480 } else if (num == 1 && ptr != NULL) { 481 pp = (char **)ptr; 482 *pp = data->cache_accepting_serv; 483 } else if (num == 2 && ptr != NULL) { 484 pp = (char **)ptr; 485 *pp = data->cache_peer_name; 486 } else if (num == 3 && ptr != NULL) { 487 pp = (char **)ptr; 488 *pp = data->cache_peer_serv; 489 } else if (num == 4) { 490 switch (BIO_ADDRINFO_family(data->addr_iter)) { 491 #ifdef AF_INET6 492 case AF_INET6: 493 ret = BIO_FAMILY_IPV6; 494 break; 495 #endif 496 case AF_INET: 497 ret = BIO_FAMILY_IPV4; 498 break; 499 case 0: 500 ret = data->accept_family; 501 break; 502 default: 503 ret = -1; 504 break; 505 } 506 } else 507 ret = -1; 508 } else 509 ret = -1; 510 break; 511 case BIO_CTRL_GET_CLOSE: 512 ret = b->shutdown; 513 break; 514 case BIO_CTRL_SET_CLOSE: 515 b->shutdown = (int)num; 516 break; 517 case BIO_CTRL_PENDING: 518 case BIO_CTRL_WPENDING: 519 ret = 0; 520 break; 521 case BIO_CTRL_FLUSH: 522 break; 523 case BIO_C_SET_BIND_MODE: 524 data->bind_mode = (int)num; 525 break; 526 case BIO_C_GET_BIND_MODE: 527 ret = (long)data->bind_mode; 528 break; 529 case BIO_CTRL_DUP: 530 break; 531 case BIO_CTRL_EOF: 532 if (b->next_bio == NULL) 533 ret = 0; 534 else 535 ret = BIO_ctrl(b->next_bio, cmd, num, ptr); 536 break; 537 default: 538 ret = 0; 539 break; 540 } 541 return ret; 542 } 543 544 static int acpt_puts(BIO *bp, const char *str) 545 { 546 int n, ret; 547 548 n = strlen(str); 549 ret = acpt_write(bp, str, n); 550 return ret; 551 } 552 553 BIO *BIO_new_accept(const char *str) 554 { 555 BIO *ret; 556 557 ret = BIO_new(BIO_s_accept()); 558 if (ret == NULL) 559 return NULL; 560 if (BIO_set_accept_name(ret, str)) 561 return ret; 562 BIO_free(ret); 563 return NULL; 564 } 565 566 #endif 567