1 /* 2 * Copyright 1995-2018 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_lcl.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 ret = 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 (ret == (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 = ret; 237 b->num = ret; 238 c->state = ACPT_S_LISTEN; 239 break; 240 241 case ACPT_S_LISTEN: 242 { 243 if (!BIO_listen(c->accept_sock, 244 BIO_ADDRINFO_address(c->addr_iter), 245 c->bind_mode)) { 246 BIO_closesocket(c->accept_sock); 247 goto exit_loop; 248 } 249 } 250 251 { 252 union BIO_sock_info_u info; 253 254 info.addr = &c->cache_accepting_addr; 255 if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS, 256 &info)) { 257 BIO_closesocket(c->accept_sock); 258 goto exit_loop; 259 } 260 } 261 262 c->cache_accepting_name = 263 BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1); 264 c->cache_accepting_serv = 265 BIO_ADDR_service_string(&c->cache_accepting_addr, 1); 266 c->state = ACPT_S_ACCEPT; 267 s = -1; 268 ret = 1; 269 goto end; 270 271 case ACPT_S_ACCEPT: 272 if (b->next_bio != NULL) { 273 c->state = ACPT_S_OK; 274 break; 275 } 276 BIO_clear_retry_flags(b); 277 b->retry_reason = 0; 278 279 OPENSSL_free(c->cache_peer_name); 280 c->cache_peer_name = NULL; 281 OPENSSL_free(c->cache_peer_serv); 282 c->cache_peer_serv = NULL; 283 284 s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr, 285 c->accepted_mode); 286 287 /* If the returned socket is invalid, this might still be 288 * retryable 289 */ 290 if (s < 0) { 291 if (BIO_sock_should_retry(s)) { 292 BIO_set_retry_special(b); 293 b->retry_reason = BIO_RR_ACCEPT; 294 goto end; 295 } 296 } 297 298 /* If it wasn't retryable, we fail */ 299 if (s < 0) { 300 ret = s; 301 goto exit_loop; 302 } 303 304 bio = BIO_new_socket(s, BIO_CLOSE); 305 if (bio == NULL) 306 goto exit_loop; 307 308 BIO_set_callback(bio, BIO_get_callback(b)); 309 BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); 310 311 /* 312 * If the accept BIO has an bio_chain, we dup it and put the new 313 * socket at the end. 314 */ 315 if (c->bio_chain != NULL) { 316 if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) 317 goto exit_loop; 318 if (!BIO_push(dbio, bio)) 319 goto exit_loop; 320 bio = dbio; 321 } 322 if (BIO_push(b, bio) == NULL) 323 goto exit_loop; 324 325 c->cache_peer_name = 326 BIO_ADDR_hostname_string(&c->cache_peer_addr, 1); 327 c->cache_peer_serv = 328 BIO_ADDR_service_string(&c->cache_peer_addr, 1); 329 c->state = ACPT_S_OK; 330 bio = NULL; 331 ret = 1; 332 goto end; 333 334 case ACPT_S_OK: 335 if (b->next_bio == NULL) { 336 c->state = ACPT_S_ACCEPT; 337 break; 338 } 339 ret = 1; 340 goto end; 341 342 default: 343 ret = 0; 344 goto end; 345 } 346 } 347 348 exit_loop: 349 if (bio != NULL) 350 BIO_free(bio); 351 else if (s >= 0) 352 BIO_closesocket(s); 353 end: 354 return ret; 355 } 356 357 static int acpt_read(BIO *b, char *out, int outl) 358 { 359 int ret = 0; 360 BIO_ACCEPT *data; 361 362 BIO_clear_retry_flags(b); 363 data = (BIO_ACCEPT *)b->ptr; 364 365 while (b->next_bio == NULL) { 366 ret = acpt_state(b, data); 367 if (ret <= 0) 368 return ret; 369 } 370 371 ret = BIO_read(b->next_bio, out, outl); 372 BIO_copy_next_retry(b); 373 return ret; 374 } 375 376 static int acpt_write(BIO *b, const char *in, int inl) 377 { 378 int ret; 379 BIO_ACCEPT *data; 380 381 BIO_clear_retry_flags(b); 382 data = (BIO_ACCEPT *)b->ptr; 383 384 while (b->next_bio == NULL) { 385 ret = acpt_state(b, data); 386 if (ret <= 0) 387 return ret; 388 } 389 390 ret = BIO_write(b->next_bio, in, inl); 391 BIO_copy_next_retry(b); 392 return ret; 393 } 394 395 static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) 396 { 397 int *ip; 398 long ret = 1; 399 BIO_ACCEPT *data; 400 char **pp; 401 402 data = (BIO_ACCEPT *)b->ptr; 403 404 switch (cmd) { 405 case BIO_CTRL_RESET: 406 ret = 0; 407 data->state = ACPT_S_BEFORE; 408 acpt_close_socket(b); 409 BIO_ADDRINFO_free(data->addr_first); 410 data->addr_first = NULL; 411 b->flags = 0; 412 break; 413 case BIO_C_DO_STATE_MACHINE: 414 /* use this one to start the connection */ 415 ret = (long)acpt_state(b, data); 416 break; 417 case BIO_C_SET_ACCEPT: 418 if (ptr != NULL) { 419 if (num == 0) { 420 char *hold_serv = data->param_serv; 421 /* We affect the hostname regardless. However, the input 422 * string might contain a host:service spec, so we must 423 * parse it, which might or might not affect the service 424 */ 425 OPENSSL_free(data->param_addr); 426 data->param_addr = NULL; 427 ret = BIO_parse_hostserv(ptr, 428 &data->param_addr, 429 &data->param_serv, 430 BIO_PARSE_PRIO_SERV); 431 if (hold_serv != data->param_serv) 432 OPENSSL_free(hold_serv); 433 b->init = 1; 434 } else if (num == 1) { 435 OPENSSL_free(data->param_serv); 436 data->param_serv = BUF_strdup(ptr); 437 b->init = 1; 438 } else if (num == 2) { 439 data->bind_mode |= BIO_SOCK_NONBLOCK; 440 } else if (num == 3) { 441 BIO_free(data->bio_chain); 442 data->bio_chain = (BIO *)ptr; 443 } else if (num == 4) { 444 data->accept_family = *(int *)ptr; 445 } 446 } else { 447 if (num == 2) { 448 data->bind_mode &= ~BIO_SOCK_NONBLOCK; 449 } 450 } 451 break; 452 case BIO_C_SET_NBIO: 453 if (num != 0) 454 data->accepted_mode |= BIO_SOCK_NONBLOCK; 455 else 456 data->accepted_mode &= ~BIO_SOCK_NONBLOCK; 457 break; 458 case BIO_C_SET_FD: 459 b->num = *((int *)ptr); 460 data->accept_sock = b->num; 461 data->state = ACPT_S_ACCEPT; 462 b->shutdown = (int)num; 463 b->init = 1; 464 break; 465 case BIO_C_GET_FD: 466 if (b->init) { 467 ip = (int *)ptr; 468 if (ip != NULL) 469 *ip = data->accept_sock; 470 ret = data->accept_sock; 471 } else 472 ret = -1; 473 break; 474 case BIO_C_GET_ACCEPT: 475 if (b->init) { 476 if (num == 0 && ptr != NULL) { 477 pp = (char **)ptr; 478 *pp = data->cache_accepting_name; 479 } else if (num == 1 && ptr != NULL) { 480 pp = (char **)ptr; 481 *pp = data->cache_accepting_serv; 482 } else if (num == 2 && ptr != NULL) { 483 pp = (char **)ptr; 484 *pp = data->cache_peer_name; 485 } else if (num == 3 && ptr != NULL) { 486 pp = (char **)ptr; 487 *pp = data->cache_peer_serv; 488 } else if (num == 4) { 489 switch (BIO_ADDRINFO_family(data->addr_iter)) { 490 #ifdef AF_INET6 491 case AF_INET6: 492 ret = BIO_FAMILY_IPV6; 493 break; 494 #endif 495 case AF_INET: 496 ret = BIO_FAMILY_IPV4; 497 break; 498 case 0: 499 ret = data->accept_family; 500 break; 501 default: 502 ret = -1; 503 break; 504 } 505 } else 506 ret = -1; 507 } else 508 ret = -1; 509 break; 510 case BIO_CTRL_GET_CLOSE: 511 ret = b->shutdown; 512 break; 513 case BIO_CTRL_SET_CLOSE: 514 b->shutdown = (int)num; 515 break; 516 case BIO_CTRL_PENDING: 517 case BIO_CTRL_WPENDING: 518 ret = 0; 519 break; 520 case BIO_CTRL_FLUSH: 521 break; 522 case BIO_C_SET_BIND_MODE: 523 data->bind_mode = (int)num; 524 break; 525 case BIO_C_GET_BIND_MODE: 526 ret = (long)data->bind_mode; 527 break; 528 case BIO_CTRL_DUP: 529 break; 530 531 default: 532 ret = 0; 533 break; 534 } 535 return ret; 536 } 537 538 static int acpt_puts(BIO *bp, const char *str) 539 { 540 int n, ret; 541 542 n = strlen(str); 543 ret = acpt_write(bp, str, n); 544 return ret; 545 } 546 547 BIO *BIO_new_accept(const char *str) 548 { 549 BIO *ret; 550 551 ret = BIO_new(BIO_s_accept()); 552 if (ret == NULL) 553 return NULL; 554 if (BIO_set_accept_name(ret, str)) 555 return ret; 556 BIO_free(ret); 557 return NULL; 558 } 559 560 #endif 561