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