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