Deprecate old style BIO callback calls
[openssl.git] / crypto / bio / bss_acpt.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 #define OPENSSL_SUPPRESS_DEPRECATED
11
12 #include <stdio.h>
13 #include <errno.h>
14 #include "bio_local.h"
15
16 #ifndef OPENSSL_NO_SOCK
17
18 typedef struct bio_accept_st {
19     int state;
20     int accept_family;
21     int bind_mode;     /* Socket mode for BIO_listen */
22     int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
23     char *param_addr;
24     char *param_serv;
25
26     int accept_sock;
27
28     BIO_ADDRINFO *addr_first;
29     const BIO_ADDRINFO *addr_iter;
30     BIO_ADDR cache_accepting_addr;   /* Useful if we asked for port 0 */
31     char *cache_accepting_name, *cache_accepting_serv;
32     BIO_ADDR cache_peer_addr;
33     char *cache_peer_name, *cache_peer_serv;
34
35     BIO *bio_chain;
36 } BIO_ACCEPT;
37
38 static int acpt_write(BIO *h, const char *buf, int num);
39 static int acpt_read(BIO *h, char *buf, int size);
40 static int acpt_puts(BIO *h, const char *str);
41 static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2);
42 static int acpt_new(BIO *h);
43 static int acpt_free(BIO *data);
44 static int acpt_state(BIO *b, BIO_ACCEPT *c);
45 static void acpt_close_socket(BIO *data);
46 static BIO_ACCEPT *BIO_ACCEPT_new(void);
47 static void BIO_ACCEPT_free(BIO_ACCEPT *a);
48
49 # define ACPT_S_BEFORE                   1
50 # define ACPT_S_GET_ADDR                 2
51 # define ACPT_S_CREATE_SOCKET            3
52 # define ACPT_S_LISTEN                   4
53 # define ACPT_S_ACCEPT                   5
54 # define ACPT_S_OK                       6
55
56 static const BIO_METHOD methods_acceptp = {
57     BIO_TYPE_ACCEPT,
58     "socket accept",
59     /* TODO: Convert to new style write function */
60     bwrite_conv,
61     acpt_write,
62     /* TODO: Convert to new style read function */
63     bread_conv,
64     acpt_read,
65     acpt_puts,
66     NULL,                       /* connect_gets,         */
67     acpt_ctrl,
68     acpt_new,
69     acpt_free,
70     NULL,                       /* connect_callback_ctrl */
71 };
72
73 const BIO_METHOD *BIO_s_accept(void)
74 {
75     return &methods_acceptp;
76 }
77
78 static int acpt_new(BIO *bi)
79 {
80     BIO_ACCEPT *ba;
81
82     bi->init = 0;
83     bi->num = (int)INVALID_SOCKET;
84     bi->flags = 0;
85     if ((ba = BIO_ACCEPT_new()) == NULL)
86         return 0;
87     bi->ptr = (char *)ba;
88     ba->state = ACPT_S_BEFORE;
89     bi->shutdown = 1;
90     return 1;
91 }
92
93 static BIO_ACCEPT *BIO_ACCEPT_new(void)
94 {
95     BIO_ACCEPT *ret;
96
97     if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
98         ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE);
99         return NULL;
100     }
101     ret->accept_family = BIO_FAMILY_IPANY;
102     ret->accept_sock = (int)INVALID_SOCKET;
103     return ret;
104 }
105
106 static void BIO_ACCEPT_free(BIO_ACCEPT *a)
107 {
108     if (a == NULL)
109         return;
110     OPENSSL_free(a->param_addr);
111     OPENSSL_free(a->param_serv);
112     BIO_ADDRINFO_free(a->addr_first);
113     OPENSSL_free(a->cache_accepting_name);
114     OPENSSL_free(a->cache_accepting_serv);
115     OPENSSL_free(a->cache_peer_name);
116     OPENSSL_free(a->cache_peer_serv);
117     BIO_free(a->bio_chain);
118     OPENSSL_free(a);
119 }
120
121 static void acpt_close_socket(BIO *bio)
122 {
123     BIO_ACCEPT *c;
124
125     c = (BIO_ACCEPT *)bio->ptr;
126     if (c->accept_sock != (int)INVALID_SOCKET) {
127         shutdown(c->accept_sock, 2);
128         closesocket(c->accept_sock);
129         c->accept_sock = (int)INVALID_SOCKET;
130         bio->num = (int)INVALID_SOCKET;
131     }
132 }
133
134 static int acpt_free(BIO *a)
135 {
136     BIO_ACCEPT *data;
137
138     if (a == NULL)
139         return 0;
140     data = (BIO_ACCEPT *)a->ptr;
141
142     if (a->shutdown) {
143         acpt_close_socket(a);
144         BIO_ACCEPT_free(data);
145         a->ptr = NULL;
146         a->flags = 0;
147         a->init = 0;
148     }
149     return 1;
150 }
151
152 static int acpt_state(BIO *b, BIO_ACCEPT *c)
153 {
154     BIO *bio = NULL, *dbio;
155     int s = -1, ret = -1;
156
157     for (;;) {
158         switch (c->state) {
159         case ACPT_S_BEFORE:
160             if (c->param_addr == NULL && c->param_serv == NULL) {
161                 ERR_raise_data(ERR_LIB_BIO,
162                                BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED,
163                                "hostname=%s, service=%s",
164                                c->param_addr, c->param_serv);
165                 goto exit_loop;
166             }
167
168             /* Because we're starting a new bind, any cached name and serv
169              * are now obsolete and need to be cleaned out.
170              * QUESTION: should this be done in acpt_close_socket() instead?
171              */
172             OPENSSL_free(c->cache_accepting_name);
173             c->cache_accepting_name = NULL;
174             OPENSSL_free(c->cache_accepting_serv);
175             c->cache_accepting_serv = NULL;
176             OPENSSL_free(c->cache_peer_name);
177             c->cache_peer_name = NULL;
178             OPENSSL_free(c->cache_peer_serv);
179             c->cache_peer_serv = NULL;
180
181             c->state = ACPT_S_GET_ADDR;
182             break;
183
184         case ACPT_S_GET_ADDR:
185             {
186                 int family = AF_UNSPEC;
187                 switch (c->accept_family) {
188                 case BIO_FAMILY_IPV6:
189                     if (1) { /* This is a trick we use to avoid bit rot.
190                               * at least the "else" part will always be
191                               * compiled.
192                               */
193 #ifdef AF_INET6
194                         family = AF_INET6;
195                     } else {
196 #endif
197                         ERR_raise(ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY);
198                         goto exit_loop;
199                     }
200                     break;
201                 case BIO_FAMILY_IPV4:
202                     family = AF_INET;
203                     break;
204                 case BIO_FAMILY_IPANY:
205                     family = AF_UNSPEC;
206                     break;
207                 default:
208                     ERR_raise(ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY);
209                     goto exit_loop;
210                 }
211                 if (BIO_lookup(c->param_addr, c->param_serv, BIO_LOOKUP_SERVER,
212                                family, SOCK_STREAM, &c->addr_first) == 0)
213                     goto exit_loop;
214             }
215             if (c->addr_first == NULL) {
216                 ERR_raise(ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING);
217                 goto exit_loop;
218             }
219             /* We're currently not iterating, but set this as preparation
220              * for possible future development in that regard
221              */
222             c->addr_iter = c->addr_first;
223             c->state = ACPT_S_CREATE_SOCKET;
224             break;
225
226         case ACPT_S_CREATE_SOCKET:
227             s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
228                            BIO_ADDRINFO_socktype(c->addr_iter),
229                            BIO_ADDRINFO_protocol(c->addr_iter), 0);
230             if (s == (int)INVALID_SOCKET) {
231                 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
232                                "calling socket(%s, %s)",
233                                 c->param_addr, c->param_serv);
234                 ERR_raise(ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
235                 goto exit_loop;
236             }
237             c->accept_sock = s;
238             b->num = s;
239             c->state = ACPT_S_LISTEN;
240             s = -1;
241             break;
242
243         case ACPT_S_LISTEN:
244             {
245                 if (!BIO_listen(c->accept_sock,
246                                 BIO_ADDRINFO_address(c->addr_iter),
247                                 c->bind_mode)) {
248                     BIO_closesocket(c->accept_sock);
249                     goto exit_loop;
250                 }
251             }
252
253             {
254                 union BIO_sock_info_u info;
255
256                 info.addr = &c->cache_accepting_addr;
257                 if (!BIO_sock_info(c->accept_sock, BIO_SOCK_INFO_ADDRESS,
258                                    &info)) {
259                     BIO_closesocket(c->accept_sock);
260                     goto exit_loop;
261                 }
262             }
263
264             c->cache_accepting_name =
265                 BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
266             c->cache_accepting_serv =
267                 BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
268             c->state = ACPT_S_ACCEPT;
269             s = -1;
270             ret = 1;
271             goto end;
272
273         case ACPT_S_ACCEPT:
274             if (b->next_bio != NULL) {
275                 c->state = ACPT_S_OK;
276                 break;
277             }
278             BIO_clear_retry_flags(b);
279             b->retry_reason = 0;
280
281             OPENSSL_free(c->cache_peer_name);
282             c->cache_peer_name = NULL;
283             OPENSSL_free(c->cache_peer_serv);
284             c->cache_peer_serv = NULL;
285
286             s = BIO_accept_ex(c->accept_sock, &c->cache_peer_addr,
287                               c->accepted_mode);
288
289             /* If the returned socket is invalid, this might still be
290              * retryable
291              */
292             if (s < 0) {
293                 if (BIO_sock_should_retry(s)) {
294                     BIO_set_retry_special(b);
295                     b->retry_reason = BIO_RR_ACCEPT;
296                     goto end;
297                 }
298             }
299
300             /* If it wasn't retryable, we fail */
301             if (s < 0) {
302                 ret = s;
303                 goto exit_loop;
304             }
305
306             bio = BIO_new_socket(s, BIO_CLOSE);
307             if (bio == NULL)
308                 goto exit_loop;
309
310             BIO_set_callback_ex(bio, BIO_get_callback_ex(b));
311 #ifndef OPENSSL_NO_DEPRECATED_3_0
312             BIO_set_callback(bio, BIO_get_callback(b));
313 #endif
314             BIO_set_callback_arg(bio, BIO_get_callback_arg(b));
315             /*
316              * If the accept BIO has an bio_chain, we dup it and put the new
317              * socket at the end.
318              */
319             if (c->bio_chain != NULL) {
320                 if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL)
321                     goto exit_loop;
322                 if (!BIO_push(dbio, bio))
323                     goto exit_loop;
324                 bio = dbio;
325             }
326             if (BIO_push(b, bio) == NULL)
327                 goto exit_loop;
328
329             c->cache_peer_name =
330                 BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
331             c->cache_peer_serv =
332                 BIO_ADDR_service_string(&c->cache_peer_addr, 1);
333             c->state = ACPT_S_OK;
334             bio = NULL;
335             ret = 1;
336             goto end;
337
338         case ACPT_S_OK:
339             if (b->next_bio == NULL) {
340                 c->state = ACPT_S_ACCEPT;
341                 break;
342             }
343             ret = 1;
344             goto end;
345
346         default:
347             ret = 0;
348             goto end;
349         }
350     }
351
352   exit_loop:
353     if (bio != NULL)
354         BIO_free(bio);
355     else if (s >= 0)
356         BIO_closesocket(s);
357   end:
358     return ret;
359 }
360
361 static int acpt_read(BIO *b, char *out, int outl)
362 {
363     int ret = 0;
364     BIO_ACCEPT *data;
365
366     BIO_clear_retry_flags(b);
367     data = (BIO_ACCEPT *)b->ptr;
368
369     while (b->next_bio == NULL) {
370         ret = acpt_state(b, data);
371         if (ret <= 0)
372             return ret;
373     }
374
375     ret = BIO_read(b->next_bio, out, outl);
376     BIO_copy_next_retry(b);
377     return ret;
378 }
379
380 static int acpt_write(BIO *b, const char *in, int inl)
381 {
382     int ret;
383     BIO_ACCEPT *data;
384
385     BIO_clear_retry_flags(b);
386     data = (BIO_ACCEPT *)b->ptr;
387
388     while (b->next_bio == NULL) {
389         ret = acpt_state(b, data);
390         if (ret <= 0)
391             return ret;
392     }
393
394     ret = BIO_write(b->next_bio, in, inl);
395     BIO_copy_next_retry(b);
396     return ret;
397 }
398
399 static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
400 {
401     int *ip;
402     long ret = 1;
403     BIO_ACCEPT *data;
404     char **pp;
405
406     data = (BIO_ACCEPT *)b->ptr;
407
408     switch (cmd) {
409     case BIO_CTRL_RESET:
410         ret = 0;
411         data->state = ACPT_S_BEFORE;
412         acpt_close_socket(b);
413         BIO_ADDRINFO_free(data->addr_first);
414         data->addr_first = NULL;
415         b->flags = 0;
416         break;
417     case BIO_C_DO_STATE_MACHINE:
418         /* use this one to start the connection */
419         ret = (long)acpt_state(b, data);
420         break;
421     case BIO_C_SET_ACCEPT:
422         if (ptr != NULL) {
423             if (num == 0) {
424                 char *hold_serv = data->param_serv;
425                 /* We affect the hostname regardless.  However, the input
426                  * string might contain a host:service spec, so we must
427                  * parse it, which might or might not affect the service
428                  */
429                 OPENSSL_free(data->param_addr);
430                 data->param_addr = NULL;
431                 ret = BIO_parse_hostserv(ptr,
432                                          &data->param_addr,
433                                          &data->param_serv,
434                                          BIO_PARSE_PRIO_SERV);
435                 if (hold_serv != data->param_serv)
436                     OPENSSL_free(hold_serv);
437                 b->init = 1;
438             } else if (num == 1) {
439                 OPENSSL_free(data->param_serv);
440                 if ((data->param_serv = OPENSSL_strdup(ptr)) == NULL)
441                     ret = 0;
442                 else
443                     b->init = 1;
444             } else if (num == 2) {
445                 data->bind_mode |= BIO_SOCK_NONBLOCK;
446             } else if (num == 3) {
447                 BIO_free(data->bio_chain);
448                 data->bio_chain = (BIO *)ptr;
449             } else if (num == 4) {
450                 data->accept_family = *(int *)ptr;
451             }
452         } else {
453             if (num == 2) {
454                 data->bind_mode &= ~BIO_SOCK_NONBLOCK;
455             }
456         }
457         break;
458     case BIO_C_SET_NBIO:
459         if (num != 0)
460             data->accepted_mode |= BIO_SOCK_NONBLOCK;
461         else
462             data->accepted_mode &= ~BIO_SOCK_NONBLOCK;
463         break;
464     case BIO_C_SET_FD:
465         b->num = *((int *)ptr);
466         data->accept_sock = b->num;
467         data->state = ACPT_S_ACCEPT;
468         b->shutdown = (int)num;
469         b->init = 1;
470         break;
471     case BIO_C_GET_FD:
472         if (b->init) {
473             ip = (int *)ptr;
474             if (ip != NULL)
475                 *ip = data->accept_sock;
476             ret = data->accept_sock;
477         } else
478             ret = -1;
479         break;
480     case BIO_C_GET_ACCEPT:
481         if (b->init) {
482             if (num == 0 && ptr != NULL) {
483                 pp = (char **)ptr;
484                 *pp = data->cache_accepting_name;
485             } else if (num == 1 && ptr != NULL) {
486                 pp = (char **)ptr;
487                 *pp = data->cache_accepting_serv;
488             } else if (num == 2 && ptr != NULL) {
489                 pp = (char **)ptr;
490                 *pp = data->cache_peer_name;
491             } else if (num == 3 && ptr != NULL) {
492                 pp = (char **)ptr;
493                 *pp = data->cache_peer_serv;
494             } else if (num == 4) {
495                 switch (BIO_ADDRINFO_family(data->addr_iter)) {
496 #ifdef AF_INET6
497                 case AF_INET6:
498                     ret = BIO_FAMILY_IPV6;
499                     break;
500 #endif
501                 case AF_INET:
502                     ret = BIO_FAMILY_IPV4;
503                     break;
504                 case 0:
505                     ret = data->accept_family;
506                     break;
507                 default:
508                     ret = -1;
509                     break;
510                 }
511             } else
512                 ret = -1;
513         } else
514             ret = -1;
515         break;
516     case BIO_CTRL_GET_CLOSE:
517         ret = b->shutdown;
518         break;
519     case BIO_CTRL_SET_CLOSE:
520         b->shutdown = (int)num;
521         break;
522     case BIO_CTRL_PENDING:
523     case BIO_CTRL_WPENDING:
524         ret = 0;
525         break;
526     case BIO_CTRL_FLUSH:
527         break;
528     case BIO_C_SET_BIND_MODE:
529         data->bind_mode = (int)num;
530         break;
531     case BIO_C_GET_BIND_MODE:
532         ret = (long)data->bind_mode;
533         break;
534     case BIO_CTRL_DUP:
535         break;
536     case BIO_CTRL_EOF:
537         if (b->next_bio == NULL)
538             ret = 0;
539         else
540             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
541         break;
542     default:
543         ret = 0;
544         break;
545     }
546     return ret;
547 }
548
549 static int acpt_puts(BIO *bp, const char *str)
550 {
551     int n, ret;
552
553     n = strlen(str);
554     ret = acpt_write(bp, str, n);
555     return ret;
556 }
557
558 BIO *BIO_new_accept(const char *str)
559 {
560     BIO *ret;
561
562     ret = BIO_new(BIO_s_accept());
563     if (ret == NULL)
564         return NULL;
565     if (BIO_set_accept_name(ret, str))
566         return ret;
567     BIO_free(ret);
568     return NULL;
569 }
570
571 #endif