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 13 #include "bio_local.h" 14 15 #ifndef OPENSSL_NO_SOCK 16 17 typedef struct bio_connect_st { 18 int state; 19 int connect_family; 20 char *param_hostname; 21 char *param_service; 22 int connect_mode; 23 24 BIO_ADDRINFO *addr_first; 25 const BIO_ADDRINFO *addr_iter; 26 /* 27 * int socket; this will be kept in bio->num so that it is compatible 28 * with the bss_sock bio 29 */ 30 /* 31 * called when the connection is initially made callback(BIO,state,ret); 32 * The callback should return 'ret'. state is for compatibility with the 33 * ssl info_callback 34 */ 35 BIO_info_cb *info_callback; 36 } BIO_CONNECT; 37 38 static int conn_write(BIO *h, const char *buf, int num); 39 static int conn_read(BIO *h, char *buf, int size); 40 static int conn_puts(BIO *h, const char *str); 41 static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); 42 static int conn_new(BIO *h); 43 static int conn_free(BIO *data); 44 static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *); 45 46 static int conn_state(BIO *b, BIO_CONNECT *c); 47 static void conn_close_socket(BIO *data); 48 BIO_CONNECT *BIO_CONNECT_new(void); 49 void BIO_CONNECT_free(BIO_CONNECT *a); 50 51 #define BIO_CONN_S_BEFORE 1 52 #define BIO_CONN_S_GET_ADDR 2 53 #define BIO_CONN_S_CREATE_SOCKET 3 54 #define BIO_CONN_S_CONNECT 4 55 #define BIO_CONN_S_OK 5 56 #define BIO_CONN_S_BLOCKED_CONNECT 6 57 #define BIO_CONN_S_CONNECT_ERROR 7 58 59 static const BIO_METHOD methods_connectp = { 60 BIO_TYPE_CONNECT, 61 "socket connect", 62 /* TODO: Convert to new style write function */ 63 bwrite_conv, 64 conn_write, 65 /* TODO: Convert to new style read function */ 66 bread_conv, 67 conn_read, 68 conn_puts, 69 NULL, /* conn_gets, */ 70 conn_ctrl, 71 conn_new, 72 conn_free, 73 conn_callback_ctrl, 74 }; 75 76 static int conn_state(BIO *b, BIO_CONNECT *c) 77 { 78 int ret = -1, i; 79 BIO_info_cb *cb = NULL; 80 81 if (c->info_callback != NULL) 82 cb = c->info_callback; 83 84 for (;;) { 85 switch (c->state) { 86 case BIO_CONN_S_BEFORE: 87 if (c->param_hostname == NULL && c->param_service == NULL) { 88 BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED); 89 ERR_add_error_data(4, 90 "hostname=", c->param_hostname, 91 " service=", c->param_service); 92 goto exit_loop; 93 } 94 c->state = BIO_CONN_S_GET_ADDR; 95 break; 96 97 case BIO_CONN_S_GET_ADDR: 98 { 99 int family = AF_UNSPEC; 100 switch (c->connect_family) { 101 case BIO_FAMILY_IPV6: 102 if (1) { /* This is a trick we use to avoid bit rot. 103 * at least the "else" part will always be 104 * compiled. 105 */ 106 #ifdef AF_INET6 107 family = AF_INET6; 108 } else { 109 #endif 110 BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY); 111 goto exit_loop; 112 } 113 break; 114 case BIO_FAMILY_IPV4: 115 family = AF_INET; 116 break; 117 case BIO_FAMILY_IPANY: 118 family = AF_UNSPEC; 119 break; 120 default: 121 BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY); 122 goto exit_loop; 123 } 124 if (BIO_lookup(c->param_hostname, c->param_service, 125 BIO_LOOKUP_CLIENT, 126 family, SOCK_STREAM, &c->addr_first) == 0) 127 goto exit_loop; 128 } 129 if (c->addr_first == NULL) { 130 BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING); 131 goto exit_loop; 132 } 133 c->addr_iter = c->addr_first; 134 c->state = BIO_CONN_S_CREATE_SOCKET; 135 break; 136 137 case BIO_CONN_S_CREATE_SOCKET: 138 ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter), 139 BIO_ADDRINFO_socktype(c->addr_iter), 140 BIO_ADDRINFO_protocol(c->addr_iter), 0); 141 if (ret == (int)INVALID_SOCKET) { 142 SYSerr(SYS_F_SOCKET, get_last_socket_error()); 143 ERR_add_error_data(4, 144 "hostname=", c->param_hostname, 145 " service=", c->param_service); 146 BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); 147 goto exit_loop; 148 } 149 b->num = ret; 150 c->state = BIO_CONN_S_CONNECT; 151 break; 152 153 case BIO_CONN_S_CONNECT: 154 BIO_clear_retry_flags(b); 155 ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter), 156 BIO_SOCK_KEEPALIVE | c->connect_mode); 157 b->retry_reason = 0; 158 if (ret == 0) { 159 if (BIO_sock_should_retry(ret)) { 160 BIO_set_retry_special(b); 161 c->state = BIO_CONN_S_BLOCKED_CONNECT; 162 b->retry_reason = BIO_RR_CONNECT; 163 ERR_clear_error(); 164 } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) 165 != NULL) { 166 /* 167 * if there are more addresses to try, do that first 168 */ 169 BIO_closesocket(b->num); 170 c->state = BIO_CONN_S_CREATE_SOCKET; 171 ERR_clear_error(); 172 break; 173 } else { 174 SYSerr(SYS_F_CONNECT, get_last_socket_error()); 175 ERR_add_error_data(4, 176 "hostname=", c->param_hostname, 177 " service=", c->param_service); 178 c->state = BIO_CONN_S_CONNECT_ERROR; 179 break; 180 } 181 goto exit_loop; 182 } else { 183 c->state = BIO_CONN_S_OK; 184 } 185 break; 186 187 case BIO_CONN_S_BLOCKED_CONNECT: 188 i = BIO_sock_error(b->num); 189 if (i) { 190 BIO_clear_retry_flags(b); 191 SYSerr(SYS_F_CONNECT, i); 192 ERR_add_error_data(4, 193 "hostname=", c->param_hostname, 194 " service=", c->param_service); 195 BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); 196 ret = 0; 197 goto exit_loop; 198 } else 199 c->state = BIO_CONN_S_OK; 200 break; 201 202 case BIO_CONN_S_CONNECT_ERROR: 203 BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); 204 ret = 0; 205 goto exit_loop; 206 207 case BIO_CONN_S_OK: 208 ret = 1; 209 goto exit_loop; 210 default: 211 /* abort(); */ 212 goto exit_loop; 213 } 214 215 if (cb != NULL) { 216 if ((ret = cb((BIO *)b, c->state, ret)) == 0) 217 goto end; 218 } 219 } 220 221 /* Loop does not exit */ 222 exit_loop: 223 if (cb != NULL) 224 ret = cb((BIO *)b, c->state, ret); 225 end: 226 return ret; 227 } 228 229 BIO_CONNECT *BIO_CONNECT_new(void) 230 { 231 BIO_CONNECT *ret; 232 233 if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) { 234 BIOerr(BIO_F_BIO_CONNECT_NEW, ERR_R_MALLOC_FAILURE); 235 return NULL; 236 } 237 ret->state = BIO_CONN_S_BEFORE; 238 ret->connect_family = BIO_FAMILY_IPANY; 239 return ret; 240 } 241 242 void BIO_CONNECT_free(BIO_CONNECT *a) 243 { 244 if (a == NULL) 245 return; 246 OPENSSL_free(a->param_hostname); 247 OPENSSL_free(a->param_service); 248 BIO_ADDRINFO_free(a->addr_first); 249 OPENSSL_free(a); 250 } 251 252 const BIO_METHOD *BIO_s_connect(void) 253 { 254 return &methods_connectp; 255 } 256 257 static int conn_new(BIO *bi) 258 { 259 bi->init = 0; 260 bi->num = (int)INVALID_SOCKET; 261 bi->flags = 0; 262 if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL) 263 return 0; 264 else 265 return 1; 266 } 267 268 static void conn_close_socket(BIO *bio) 269 { 270 BIO_CONNECT *c; 271 272 c = (BIO_CONNECT *)bio->ptr; 273 if (bio->num != (int)INVALID_SOCKET) { 274 /* Only do a shutdown if things were established */ 275 if (c->state == BIO_CONN_S_OK) 276 shutdown(bio->num, 2); 277 BIO_closesocket(bio->num); 278 bio->num = (int)INVALID_SOCKET; 279 } 280 } 281 282 static int conn_free(BIO *a) 283 { 284 BIO_CONNECT *data; 285 286 if (a == NULL) 287 return 0; 288 data = (BIO_CONNECT *)a->ptr; 289 290 if (a->shutdown) { 291 conn_close_socket(a); 292 BIO_CONNECT_free(data); 293 a->ptr = NULL; 294 a->flags = 0; 295 a->init = 0; 296 } 297 return 1; 298 } 299 300 static int conn_read(BIO *b, char *out, int outl) 301 { 302 int ret = 0; 303 BIO_CONNECT *data; 304 305 data = (BIO_CONNECT *)b->ptr; 306 if (data->state != BIO_CONN_S_OK) { 307 ret = conn_state(b, data); 308 if (ret <= 0) 309 return ret; 310 } 311 312 if (out != NULL) { 313 clear_socket_error(); 314 ret = readsocket(b->num, out, outl); 315 BIO_clear_retry_flags(b); 316 if (ret <= 0) { 317 if (BIO_sock_should_retry(ret)) 318 BIO_set_retry_read(b); 319 else if (ret == 0) 320 b->flags |= BIO_FLAGS_IN_EOF; 321 } 322 } 323 return ret; 324 } 325 326 static int conn_write(BIO *b, const char *in, int inl) 327 { 328 int ret; 329 BIO_CONNECT *data; 330 331 data = (BIO_CONNECT *)b->ptr; 332 if (data->state != BIO_CONN_S_OK) { 333 ret = conn_state(b, data); 334 if (ret <= 0) 335 return ret; 336 } 337 338 clear_socket_error(); 339 ret = writesocket(b->num, in, inl); 340 BIO_clear_retry_flags(b); 341 if (ret <= 0) { 342 if (BIO_sock_should_retry(ret)) 343 BIO_set_retry_write(b); 344 } 345 return ret; 346 } 347 348 static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) 349 { 350 BIO *dbio; 351 int *ip; 352 const char **pptr = NULL; 353 long ret = 1; 354 BIO_CONNECT *data; 355 356 data = (BIO_CONNECT *)b->ptr; 357 358 switch (cmd) { 359 case BIO_CTRL_RESET: 360 ret = 0; 361 data->state = BIO_CONN_S_BEFORE; 362 conn_close_socket(b); 363 BIO_ADDRINFO_free(data->addr_first); 364 data->addr_first = NULL; 365 b->flags = 0; 366 break; 367 case BIO_C_DO_STATE_MACHINE: 368 /* use this one to start the connection */ 369 if (data->state != BIO_CONN_S_OK) 370 ret = (long)conn_state(b, data); 371 else 372 ret = 1; 373 break; 374 case BIO_C_GET_CONNECT: 375 if (ptr != NULL) { 376 pptr = (const char **)ptr; 377 if (num == 0) { 378 *pptr = data->param_hostname; 379 } else if (num == 1) { 380 *pptr = data->param_service; 381 } else if (num == 2) { 382 *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter); 383 } else if (num == 3) { 384 switch (BIO_ADDRINFO_family(data->addr_iter)) { 385 # ifdef AF_INET6 386 case AF_INET6: 387 ret = BIO_FAMILY_IPV6; 388 break; 389 # endif 390 case AF_INET: 391 ret = BIO_FAMILY_IPV4; 392 break; 393 case 0: 394 ret = data->connect_family; 395 break; 396 default: 397 ret = -1; 398 break; 399 } 400 } else { 401 ret = 0; 402 } 403 } else { 404 ret = 0; 405 } 406 break; 407 case BIO_C_SET_CONNECT: 408 if (ptr != NULL) { 409 b->init = 1; 410 if (num == 0) { 411 char *hold_service = data->param_service; 412 /* We affect the hostname regardless. However, the input 413 * string might contain a host:service spec, so we must 414 * parse it, which might or might not affect the service 415 */ 416 OPENSSL_free(data->param_hostname); 417 data->param_hostname = NULL; 418 ret = BIO_parse_hostserv(ptr, 419 &data->param_hostname, 420 &data->param_service, 421 BIO_PARSE_PRIO_HOST); 422 if (hold_service != data->param_service) 423 OPENSSL_free(hold_service); 424 } else if (num == 1) { 425 OPENSSL_free(data->param_service); 426 data->param_service = BUF_strdup(ptr); 427 } else if (num == 2) { 428 const BIO_ADDR *addr = (const BIO_ADDR *)ptr; 429 if (ret) { 430 data->param_hostname = BIO_ADDR_hostname_string(addr, 1); 431 data->param_service = BIO_ADDR_service_string(addr, 1); 432 BIO_ADDRINFO_free(data->addr_first); 433 data->addr_first = NULL; 434 data->addr_iter = NULL; 435 } 436 } else if (num == 3) { 437 data->connect_family = *(int *)ptr; 438 } else { 439 ret = 0; 440 } 441 } 442 break; 443 case BIO_C_SET_NBIO: 444 if (num != 0) 445 data->connect_mode |= BIO_SOCK_NONBLOCK; 446 else 447 data->connect_mode &= ~BIO_SOCK_NONBLOCK; 448 break; 449 case BIO_C_SET_CONNECT_MODE: 450 data->connect_mode = (int)num; 451 break; 452 case BIO_C_GET_FD: 453 if (b->init) { 454 ip = (int *)ptr; 455 if (ip != NULL) 456 *ip = b->num; 457 ret = b->num; 458 } else 459 ret = -1; 460 break; 461 case BIO_CTRL_GET_CLOSE: 462 ret = b->shutdown; 463 break; 464 case BIO_CTRL_SET_CLOSE: 465 b->shutdown = (int)num; 466 break; 467 case BIO_CTRL_PENDING: 468 case BIO_CTRL_WPENDING: 469 ret = 0; 470 break; 471 case BIO_CTRL_FLUSH: 472 break; 473 case BIO_CTRL_DUP: 474 { 475 dbio = (BIO *)ptr; 476 if (data->param_hostname) 477 BIO_set_conn_hostname(dbio, data->param_hostname); 478 if (data->param_service) 479 BIO_set_conn_port(dbio, data->param_service); 480 BIO_set_conn_ip_family(dbio, data->connect_family); 481 BIO_set_conn_mode(dbio, data->connect_mode); 482 /* 483 * FIXME: the cast of the function seems unlikely to be a good 484 * idea 485 */ 486 (void)BIO_set_info_callback(dbio, data->info_callback); 487 } 488 break; 489 case BIO_CTRL_SET_CALLBACK: 490 ret = 0; /* use callback ctrl */ 491 break; 492 case BIO_CTRL_GET_CALLBACK: 493 { 494 BIO_info_cb **fptr; 495 496 fptr = (BIO_info_cb **)ptr; 497 *fptr = data->info_callback; 498 } 499 break; 500 case BIO_CTRL_EOF: 501 ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0; 502 break; 503 default: 504 ret = 0; 505 break; 506 } 507 return ret; 508 } 509 510 static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 511 { 512 long ret = 1; 513 BIO_CONNECT *data; 514 515 data = (BIO_CONNECT *)b->ptr; 516 517 switch (cmd) { 518 case BIO_CTRL_SET_CALLBACK: 519 { 520 data->info_callback = fp; 521 } 522 break; 523 default: 524 ret = 0; 525 break; 526 } 527 return ret; 528 } 529 530 static int conn_puts(BIO *bp, const char *str) 531 { 532 int n, ret; 533 534 n = strlen(str); 535 ret = conn_write(bp, str, n); 536 return ret; 537 } 538 539 BIO *BIO_new_connect(const char *str) 540 { 541 BIO *ret; 542 543 ret = BIO_new(BIO_s_connect()); 544 if (ret == NULL) 545 return NULL; 546 if (BIO_set_conn_hostname(ret, str)) 547 return ret; 548 BIO_free(ret); 549 return NULL; 550 } 551 552 #endif 553