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