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