Teach more BIOs how to handle BIO_CTRL_EOF
[openssl.git] / crypto / bio / bss_conn.c
1 /*
2  * Copyright 1995-2018 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
15 #ifndef OPENSSL_NO_SOCK
16
17 typedef struct bio_connect_st {
18     int state;
19     int connect_family;
20     char *param_hostname;
21     char *param_service;
22     int connect_mode;
23
24     BIO_ADDRINFO *addr_first;
25     const BIO_ADDRINFO *addr_iter;
26     /*
27      * int socket; this will be kept in bio->num so that it is compatible
28      * with the bss_sock bio
29      */
30     /*
31      * called when the connection is initially made callback(BIO,state,ret);
32      * The callback should return 'ret'.  state is for compatibility with the
33      * ssl info_callback
34      */
35     BIO_info_cb *info_callback;
36 } BIO_CONNECT;
37
38 static int conn_write(BIO *h, const char *buf, int num);
39 static int conn_read(BIO *h, char *buf, int size);
40 static int conn_puts(BIO *h, const char *str);
41 static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
42 static int conn_new(BIO *h);
43 static int conn_free(BIO *data);
44 static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
45
46 static int conn_state(BIO *b, BIO_CONNECT *c);
47 static void conn_close_socket(BIO *data);
48 BIO_CONNECT *BIO_CONNECT_new(void);
49 void BIO_CONNECT_free(BIO_CONNECT *a);
50
51 #define BIO_CONN_S_BEFORE                1
52 #define BIO_CONN_S_GET_ADDR              2
53 #define BIO_CONN_S_CREATE_SOCKET         3
54 #define BIO_CONN_S_CONNECT               4
55 #define BIO_CONN_S_OK                    5
56 #define BIO_CONN_S_BLOCKED_CONNECT       6
57 #define BIO_CONN_S_CONNECT_ERROR         7
58
59 static const BIO_METHOD methods_connectp = {
60     BIO_TYPE_CONNECT,
61     "socket connect",
62     /* TODO: Convert to new style write function */
63     bwrite_conv,
64     conn_write,
65     /* TODO: Convert to new style read function */
66     bread_conv,
67     conn_read,
68     conn_puts,
69     NULL,                       /* conn_gets, */
70     conn_ctrl,
71     conn_new,
72     conn_free,
73     conn_callback_ctrl,
74 };
75
76 static int conn_state(BIO *b, BIO_CONNECT *c)
77 {
78     int ret = -1, i;
79     BIO_info_cb *cb = NULL;
80
81     if (c->info_callback != NULL)
82         cb = c->info_callback;
83
84     for (;;) {
85         switch (c->state) {
86         case BIO_CONN_S_BEFORE:
87             if (c->param_hostname == NULL && c->param_service == NULL) {
88                 BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED);
89                 ERR_add_error_data(4,
90                                    "hostname=", c->param_hostname,
91                                    " service=", c->param_service);
92                 goto exit_loop;
93             }
94             c->state = BIO_CONN_S_GET_ADDR;
95             break;
96
97         case BIO_CONN_S_GET_ADDR:
98             {
99                 int family = AF_UNSPEC;
100                 switch (c->connect_family) {
101                 case BIO_FAMILY_IPV6:
102                     if (1) { /* This is a trick we use to avoid bit rot.
103                               * at least the "else" part will always be
104                               * compiled.
105                               */
106 #ifdef AF_INET6
107                         family = AF_INET6;
108                     } else {
109 #endif
110                         BIOerr(BIO_F_CONN_STATE, BIO_R_UNAVAILABLE_IP_FAMILY);
111                         goto exit_loop;
112                     }
113                     break;
114                 case BIO_FAMILY_IPV4:
115                     family = AF_INET;
116                     break;
117                 case BIO_FAMILY_IPANY:
118                     family = AF_UNSPEC;
119                     break;
120                 default:
121                     BIOerr(BIO_F_CONN_STATE, BIO_R_UNSUPPORTED_IP_FAMILY);
122                     goto exit_loop;
123                 }
124                 if (BIO_lookup(c->param_hostname, c->param_service,
125                                BIO_LOOKUP_CLIENT,
126                                family, SOCK_STREAM, &c->addr_first) == 0)
127                     goto exit_loop;
128             }
129             if (c->addr_first == NULL) {
130                 BIOerr(BIO_F_CONN_STATE, BIO_R_LOOKUP_RETURNED_NOTHING);
131                 goto exit_loop;
132             }
133             c->addr_iter = c->addr_first;
134             c->state = BIO_CONN_S_CREATE_SOCKET;
135             break;
136
137         case BIO_CONN_S_CREATE_SOCKET:
138             ret = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
139                              BIO_ADDRINFO_socktype(c->addr_iter),
140                              BIO_ADDRINFO_protocol(c->addr_iter), 0);
141             if (ret == (int)INVALID_SOCKET) {
142                 ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
143                                "calling socket(%s, %s)",
144                                c->param_hostname, c->param_service);
145                 BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
146                 goto exit_loop;
147             }
148             b->num = ret;
149             c->state = BIO_CONN_S_CONNECT;
150             break;
151
152         case BIO_CONN_S_CONNECT:
153             BIO_clear_retry_flags(b);
154             ret = BIO_connect(b->num, BIO_ADDRINFO_address(c->addr_iter),
155                               BIO_SOCK_KEEPALIVE | c->connect_mode);
156             b->retry_reason = 0;
157             if (ret == 0) {
158                 if (BIO_sock_should_retry(ret)) {
159                     BIO_set_retry_special(b);
160                     c->state = BIO_CONN_S_BLOCKED_CONNECT;
161                     b->retry_reason = BIO_RR_CONNECT;
162                     ERR_clear_error();
163                 } else if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter))
164                            != NULL) {
165                     /*
166                      * if there are more addresses to try, do that first
167                      */
168                     BIO_closesocket(b->num);
169                     c->state = BIO_CONN_S_CREATE_SOCKET;
170                     ERR_clear_error();
171                     break;
172                 } else {
173                     ERR_raise_data(ERR_LIB_SYS, get_last_socket_error(),
174                                    "calling connect(%s, %s)",
175                                     c->param_hostname, c->param_service);
176                     c->state = BIO_CONN_S_CONNECT_ERROR;
177                     break;
178                 }
179                 goto exit_loop;
180             } else {
181                 c->state = BIO_CONN_S_OK;
182             }
183             break;
184
185         case BIO_CONN_S_BLOCKED_CONNECT:
186             i = BIO_sock_error(b->num);
187             if (i) {
188                 BIO_clear_retry_flags(b);
189                 ERR_raise_data(ERR_LIB_SYS, i,
190                                "calling connect(%s, %s)",
191                                 c->param_hostname, c->param_service);
192                 BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR);
193                 ret = 0;
194                 goto exit_loop;
195             } else
196                 c->state = BIO_CONN_S_OK;
197             break;
198
199         case BIO_CONN_S_CONNECT_ERROR:
200             BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR);
201             ret = 0;
202             goto exit_loop;
203
204         case BIO_CONN_S_OK:
205             ret = 1;
206             goto exit_loop;
207         default:
208             /* abort(); */
209             goto exit_loop;
210         }
211
212         if (cb != NULL) {
213             if ((ret = cb((BIO *)b, c->state, ret)) == 0)
214                 goto end;
215         }
216     }
217
218     /* Loop does not exit */
219  exit_loop:
220     if (cb != NULL)
221         ret = cb((BIO *)b, c->state, ret);
222  end:
223     return ret;
224 }
225
226 BIO_CONNECT *BIO_CONNECT_new(void)
227 {
228     BIO_CONNECT *ret;
229
230     if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {
231         BIOerr(BIO_F_BIO_CONNECT_NEW, ERR_R_MALLOC_FAILURE);
232         return NULL;
233     }
234     ret->state = BIO_CONN_S_BEFORE;
235     ret->connect_family = BIO_FAMILY_IPANY;
236     return ret;
237 }
238
239 void BIO_CONNECT_free(BIO_CONNECT *a)
240 {
241     if (a == NULL)
242         return;
243     OPENSSL_free(a->param_hostname);
244     OPENSSL_free(a->param_service);
245     BIO_ADDRINFO_free(a->addr_first);
246     OPENSSL_free(a);
247 }
248
249 const BIO_METHOD *BIO_s_connect(void)
250 {
251     return &methods_connectp;
252 }
253
254 static int conn_new(BIO *bi)
255 {
256     bi->init = 0;
257     bi->num = (int)INVALID_SOCKET;
258     bi->flags = 0;
259     if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL)
260         return 0;
261     else
262         return 1;
263 }
264
265 static void conn_close_socket(BIO *bio)
266 {
267     BIO_CONNECT *c;
268
269     c = (BIO_CONNECT *)bio->ptr;
270     if (bio->num != (int)INVALID_SOCKET) {
271         /* Only do a shutdown if things were established */
272         if (c->state == BIO_CONN_S_OK)
273             shutdown(bio->num, 2);
274         BIO_closesocket(bio->num);
275         bio->num = (int)INVALID_SOCKET;
276     }
277 }
278
279 static int conn_free(BIO *a)
280 {
281     BIO_CONNECT *data;
282
283     if (a == NULL)
284         return 0;
285     data = (BIO_CONNECT *)a->ptr;
286
287     if (a->shutdown) {
288         conn_close_socket(a);
289         BIO_CONNECT_free(data);
290         a->ptr = NULL;
291         a->flags = 0;
292         a->init = 0;
293     }
294     return 1;
295 }
296
297 static int conn_read(BIO *b, char *out, int outl)
298 {
299     int ret = 0;
300     BIO_CONNECT *data;
301
302     data = (BIO_CONNECT *)b->ptr;
303     if (data->state != BIO_CONN_S_OK) {
304         ret = conn_state(b, data);
305         if (ret <= 0)
306             return ret;
307     }
308
309     if (out != NULL) {
310         clear_socket_error();
311         ret = readsocket(b->num, out, outl);
312         BIO_clear_retry_flags(b);
313         if (ret <= 0) {
314             if (BIO_sock_should_retry(ret))
315                 BIO_set_retry_read(b);
316             else if (ret == 0)
317                 b->flags |= BIO_FLAGS_IN_EOF;
318         }
319     }
320     return ret;
321 }
322
323 static int conn_write(BIO *b, const char *in, int inl)
324 {
325     int ret;
326     BIO_CONNECT *data;
327
328     data = (BIO_CONNECT *)b->ptr;
329     if (data->state != BIO_CONN_S_OK) {
330         ret = conn_state(b, data);
331         if (ret <= 0)
332             return ret;
333     }
334
335     clear_socket_error();
336     ret = writesocket(b->num, in, inl);
337     BIO_clear_retry_flags(b);
338     if (ret <= 0) {
339         if (BIO_sock_should_retry(ret))
340             BIO_set_retry_write(b);
341     }
342     return ret;
343 }
344
345 static long conn_ctrl(BIO *b, int cmd, long num, void *ptr)
346 {
347     BIO *dbio;
348     int *ip;
349     const char **pptr = NULL;
350     long ret = 1;
351     BIO_CONNECT *data;
352
353     data = (BIO_CONNECT *)b->ptr;
354
355     switch (cmd) {
356     case BIO_CTRL_RESET:
357         ret = 0;
358         data->state = BIO_CONN_S_BEFORE;
359         conn_close_socket(b);
360         BIO_ADDRINFO_free(data->addr_first);
361         data->addr_first = NULL;
362         b->flags = 0;
363         break;
364     case BIO_C_DO_STATE_MACHINE:
365         /* use this one to start the connection */
366         if (data->state != BIO_CONN_S_OK)
367             ret = (long)conn_state(b, data);
368         else
369             ret = 1;
370         break;
371     case BIO_C_GET_CONNECT:
372         if (ptr != NULL) {
373             pptr = (const char **)ptr;
374             if (num == 0) {
375                 *pptr = data->param_hostname;
376             } else if (num == 1) {
377                 *pptr = data->param_service;
378             } else if (num == 2) {
379                 *pptr = (const char *)BIO_ADDRINFO_address(data->addr_iter);
380             } else if (num == 3) {
381                 switch (BIO_ADDRINFO_family(data->addr_iter)) {
382 # ifdef AF_INET6
383                 case AF_INET6:
384                     ret = BIO_FAMILY_IPV6;
385                     break;
386 # endif
387                 case AF_INET:
388                     ret = BIO_FAMILY_IPV4;
389                     break;
390                 case 0:
391                     ret = data->connect_family;
392                     break;
393                 default:
394                     ret = -1;
395                     break;
396                 }
397             } else {
398                 ret = 0;
399             }
400         } else {
401             ret = 0;
402         }
403         break;
404     case BIO_C_SET_CONNECT:
405         if (ptr != NULL) {
406             b->init = 1;
407             if (num == 0) {
408                 char *hold_service = data->param_service;
409                 /* We affect the hostname regardless.  However, the input
410                  * string might contain a host:service spec, so we must
411                  * parse it, which might or might not affect the service
412                  */
413                 OPENSSL_free(data->param_hostname);
414                 data->param_hostname = NULL;
415                 ret = BIO_parse_hostserv(ptr,
416                                          &data->param_hostname,
417                                          &data->param_service,
418                                          BIO_PARSE_PRIO_HOST);
419                 if (hold_service != data->param_service)
420                     OPENSSL_free(hold_service);
421             } else if (num == 1) {
422                 OPENSSL_free(data->param_service);
423                 data->param_service = OPENSSL_strdup(ptr);
424             } else if (num == 2) {
425                 const BIO_ADDR *addr = (const BIO_ADDR *)ptr;
426                 if (ret) {
427                     data->param_hostname = BIO_ADDR_hostname_string(addr, 1);
428                     data->param_service = BIO_ADDR_service_string(addr, 1);
429                     BIO_ADDRINFO_free(data->addr_first);
430                     data->addr_first = NULL;
431                     data->addr_iter = NULL;
432                 }
433             } else if (num == 3) {
434                 data->connect_family = *(int *)ptr;
435             } else {
436                 ret = 0;
437             }
438         }
439         break;
440     case BIO_C_SET_NBIO:
441         if (num != 0)
442             data->connect_mode |= BIO_SOCK_NONBLOCK;
443         else
444             data->connect_mode &= ~BIO_SOCK_NONBLOCK;
445         break;
446     case BIO_C_SET_CONNECT_MODE:
447         data->connect_mode = (int)num;
448         break;
449     case BIO_C_GET_FD:
450         if (b->init) {
451             ip = (int *)ptr;
452             if (ip != NULL)
453                 *ip = b->num;
454             ret = b->num;
455         } else
456             ret = -1;
457         break;
458     case BIO_CTRL_GET_CLOSE:
459         ret = b->shutdown;
460         break;
461     case BIO_CTRL_SET_CLOSE:
462         b->shutdown = (int)num;
463         break;
464     case BIO_CTRL_PENDING:
465     case BIO_CTRL_WPENDING:
466         ret = 0;
467         break;
468     case BIO_CTRL_FLUSH:
469         break;
470     case BIO_CTRL_DUP:
471         {
472             dbio = (BIO *)ptr;
473             if (data->param_hostname)
474                 BIO_set_conn_hostname(dbio, data->param_hostname);
475             if (data->param_service)
476                 BIO_set_conn_port(dbio, data->param_service);
477             BIO_set_conn_ip_family(dbio, data->connect_family);
478             BIO_set_conn_mode(dbio, data->connect_mode);
479             /*
480              * FIXME: the cast of the function seems unlikely to be a good
481              * idea
482              */
483             (void)BIO_set_info_callback(dbio, data->info_callback);
484         }
485         break;
486     case BIO_CTRL_SET_CALLBACK:
487         ret = 0; /* use callback ctrl */
488         break;
489     case BIO_CTRL_GET_CALLBACK:
490         {
491             BIO_info_cb **fptr;
492
493             fptr = (BIO_info_cb **)ptr;
494             *fptr = data->info_callback;
495         }
496         break;
497     case BIO_CTRL_EOF:
498         ret = (b->flags & BIO_FLAGS_IN_EOF) != 0 ? 1 : 0;
499         break;
500     default:
501         ret = 0;
502         break;
503     }
504     return ret;
505 }
506
507 static long conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
508 {
509     long ret = 1;
510     BIO_CONNECT *data;
511
512     data = (BIO_CONNECT *)b->ptr;
513
514     switch (cmd) {
515     case BIO_CTRL_SET_CALLBACK:
516         {
517             data->info_callback = fp;
518         }
519         break;
520     default:
521         ret = 0;
522         break;
523     }
524     return ret;
525 }
526
527 static int conn_puts(BIO *bp, const char *str)
528 {
529     int n, ret;
530
531     n = strlen(str);
532     ret = conn_write(bp, str, n);
533     return ret;
534 }
535
536 BIO *BIO_new_connect(const char *str)
537 {
538     BIO *ret;
539
540     ret = BIO_new(BIO_s_connect());
541     if (ret == NULL)
542         return NULL;
543     if (BIO_set_conn_hostname(ret, str))
544         return ret;
545     BIO_free(ret);
546     return NULL;
547 }
548
549 #endif