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