Fix err checking and mem leaks of BIO_set_conn_port and BIO_set_conn_address
[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                 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);
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                         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;
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                 BIOerr(BIO_F_CONN_STATE, 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                 BIOerr(BIO_F_CONN_STATE, 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                 BIOerr(BIO_F_CONN_STATE, 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             BIOerr(BIO_F_CONN_STATE, 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         BIOerr(BIO_F_BIO_CONNECT_NEW, 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 #  ifdef __FreeBSD__
381     struct tls_enable *crypto_info;
382 #  else
383     struct tls12_crypto_info_aes_gcm_128 *crypto_info;
384 #  endif
385 # endif
386
387     data = (BIO_CONNECT *)b->ptr;
388
389     switch (cmd) {
390     case BIO_CTRL_RESET:
391         ret = 0;
392         data->state = BIO_CONN_S_BEFORE;
393         conn_close_socket(b);
394         BIO_ADDRINFO_free(data->addr_first);
395         data->addr_first = NULL;
396         b->flags = 0;
397         break;
398     case BIO_C_DO_STATE_MACHINE:
399         /* use this one to start the connection */
400         if (data->state != BIO_CONN_S_OK)
401             ret = (long)conn_state(b, data);
402         else
403             ret = 1;
404         break;
405     case BIO_C_GET_CONNECT:
406         if (ptr != NULL) {
407             pptr = (const char **)ptr;
408             if (num == 0) {
409                 *pptr = data->param_hostname;
410             } else if (num == 1) {
411                 *pptr = data->param_service;
412             } else if (num == 2) {
413                 *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
414             } else if (num == 3) {
415                 switch (BIO_ADDRINFO_family(data->addr_iter)) {
416 # ifdef AF_INET6
417                 case AF_INET6:
418                     ret = BIO_FAMILY_IPV6;
419                     break;
420 # endif
421                 case AF_INET:
422                     ret = BIO_FAMILY_IPV4;
423                     break;
424                 case 0:
425                     ret = data->connect_family;
426                     break;
427                 default:
428                     ret = -1;
429                     break;
430                 }
431             } else {
432                 ret = 0;
433             }
434         } else {
435             ret = 0;
436         }
437         break;
438     case BIO_C_SET_CONNECT:
439         if (ptr != NULL) {
440             b->init = 1;
441             if (num == 0) { /* BIO_set_conn_hostname */
442                 char *hold_service = data->param_service;
443                 /* We affect the hostname regardless.  However, the input
444                  * string might contain a host:service spec, so we must
445                  * parse it, which might or might not affect the service
446                  */
447
448                 OPENSSL_free(data->param_hostname);
449                 data->param_hostname = NULL;
450                 ret = BIO_parse_hostserv(ptr,
451                                          &data->param_hostname,
452                                          &data->param_service,
453                                          BIO_PARSE_PRIO_HOST);
454                 if (hold_service != data->param_service)
455                     OPENSSL_free(hold_service);
456             } else if (num == 1) { /* BIO_set_conn_port */
457                 OPENSSL_free(data->param_service);
458                 if ((data->param_service = OPENSSL_strdup(ptr)) == NULL)
459                     ret = 0;
460             } else if (num == 2) { /* BIO_set_conn_address */
461                 const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
462                 char *host = BIO_ADDR_hostname_string(addr, 1);
463                 char *service = BIO_ADDR_service_string(addr, 1);
464
465                 ret = host != NULL && service != NULL;
466                 if (ret) {
467                     OPENSSL_free(data->param_hostname);
468                     data->param_hostname = host;
469                     OPENSSL_free(data->param_service);
470                     data->param_service = service;
471                     BIO_ADDRINFO_free(data->addr_first);
472                     data->addr_first = NULL;
473                     data->addr_iter = NULL;
474                 } else {
475                     OPENSSL_free(host);
476                     OPENSSL_free(service);
477                 }
478             } else if (num == 3) { /* BIO_set_conn_ip_family */
479                 data->connect_family = *(int *)ptr;
480             } else {
481                 ret = 0;
482             }
483         }
484         break;
485     case BIO_C_SET_NBIO:
486         if (num != 0)
487             data->connect_mode |= BIO_SOCK_NONBLOCK;
488         else
489             data->connect_mode &= ~BIO_SOCK_NONBLOCK;
490         break;
491     case BIO_C_SET_CONNECT_MODE:
492         data->connect_mode = (int)num;
493         break;
494     case BIO_C_GET_FD:
495         if (b->init) {
496             ip = (int *)ptr;
497             if (ip != NULL)
498                 *ip = b->num;
499             ret = b->num;
500         } else
501             ret = -1;
502         break;
503     case BIO_CTRL_GET_CLOSE:
504         ret = b->shutdown;
505         break;
506     case BIO_CTRL_SET_CLOSE:
507         b->shutdown = (int)num;
508         break;
509     case BIO_CTRL_PENDING:
510     case BIO_CTRL_WPENDING:
511         ret = 0;
512         break;
513     case BIO_CTRL_FLUSH:
514         break;
515     case BIO_CTRL_DUP:
516         {
517             dbio = (BIO *)ptr;
518             if (data->param_hostname)
519                 BIO_set_conn_hostname(dbio, data->param_hostname);
520             if (data->param_service)
521                 BIO_set_conn_port(dbio, data->param_service);
522             BIO_set_conn_ip_family(dbio, data->connect_family);
523             BIO_set_conn_mode(dbio, data->connect_mode);
524             /*
525              * FIXME: the cast of the function seems unlikely to be a good
526              * idea
527              */
528             (void)BIO_set_info_callback(dbio, data->info_callback);
529         }
530         break;
531     case BIO_CTRL_SET_CALLBACK:
532         ret = 0; /* use callback ctrl */
533         break;
534     case BIO_CTRL_GET_CALLBACK:
535         {
536             BIO_info_cb **fptr;
537
538             fptr = (BIO_info_cb **)ptr;
539             *fptr = data->info_callback;
540         }
541         break;
542     case BIO_CTRL_EOF:
543         ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
544         break;
545 # ifndef OPENSSL_NO_KTLS
546     case BIO_CTRL_SET_KTLS:
547 #  ifdef __FreeBSD__
548         crypto_info = (struct tls_enable *)ptr;
549 #  else
550         crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr;
551 #  endif
552         ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num);
553         if (ret)
554             BIO_set_ktls_flag(b, num);
555         break;
556     case BIO_CTRL_GET_KTLS_SEND:
557         return BIO_should_ktls_flag(b, 1);
558     case BIO_CTRL_GET_KTLS_RECV:
559         return BIO_should_ktls_flag(b, 0);
560     case BIO_CTRL_SET_KTLS_TX_SEND_CTRL_MSG:
561         BIO_set_ktls_ctrl_msg_flag(b);
562         data->record_type = num;
563         ret = 0;
564         break;
565     case BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG:
566         BIO_clear_ktls_ctrl_msg_flag(b);
567         ret = 0;
568         break;
569 # endif
570     default:
571         ret = 0;
572         break;
573     }
574     return ret;
575 }
576
577 static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
578 {
579     long ret = 1;
580     BIO_CONNECT *data;
581
582     data = (BIO_CONNECT *)b->ptr;
583
584     switch (cmd) {
585     case BIO_CTRL_SET_CALLBACK:
586         {
587             data->info_callback = fp;
588         }
589         break;
590     default:
591         ret = 0;
592         break;
593     }
594     return ret;
595 }
596
597 static int conn_puts(BIO *bp, const char *str)
598 {
599     int n, ret;
600
601     n = strlen(str);
602     ret = conn_write(bp, str, n);
603     return ret;
604 }
605
606 BIO *BIO_new_connect(const char *str)
607 {
608     BIO *ret;
609
610     ret = BIO_new(BIO_s_connect());
611     if (ret == NULL)
612         return NULL;
613     if (BIO_set_conn_hostname(ret, str))
614         return ret;
615     BIO_free(ret);
616     return NULL;
617 }
618
619 #endif