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