]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bnet.c
be59e422a2b81a9e97cf8ee2aaddd71136c2a792
[bacula/bacula] / bacula / src / lib / bnet.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * Network Utility Routines
21  *
22  *  by Kern Sibbald
23  *
24  * Adapted and enhanced for Bacula, originally written
25  * for inclusion in the Apcupsd package
26  *
27  */
28
29
30 #include "bacula.h"
31 #include "jcr.h"
32 #include <netdb.h>
33
34 #ifndef   INADDR_NONE
35 #define   INADDR_NONE    -1
36 #endif
37
38 #ifdef HAVE_WIN32
39 #undef inet_pton
40 #define inet_pton binet_pton
41 #define socketRead(fd, buf, len)  recv(fd, buf, len, 0)
42 #define socketWrite(fd, buf, len) send(fd, buf, len, 0)
43 #define socketClose(fd)           closesocket(fd)
44 #else
45 #define socketRead(fd, buf, len)  read(fd, buf, len)
46 #define socketWrite(fd, buf, len) write(fd, buf, len)
47 #define socketClose(fd)           close(fd)
48 #endif
49
50 #ifndef HAVE_GETADDRINFO
51 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
52 #endif
53
54 /*
55  * Read a nbytes from the network.
56  * It is possible that the total bytes require in several
57  * read requests
58  */
59
60 int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
61 {
62    int32_t nleft, nread;
63
64 #ifdef HAVE_TLS
65    if (bsock->tls) {
66       /* TLS enabled */
67       return (tls_bsock_readn(bsock, ptr, nbytes));
68    }
69 #endif /* HAVE_TLS */
70
71    nleft = nbytes;
72    while (nleft > 0) {
73       errno = 0;
74       nread = socketRead(bsock->m_fd, ptr, nleft);
75       if (bsock->is_timed_out() || bsock->is_terminated()) {
76          return -1;
77       }
78
79 #ifdef HAVE_WIN32
80       /*
81        * We simulate errno on Windows for a socket
82        *  error in order to handle errors correctly.
83        */
84       if (nread == SOCKET_ERROR) {
85         DWORD err = WSAGetLastError();
86         nread = -1;
87         if (err == WSAEINTR) {
88            errno = EINTR;
89         } else if (err == WSAEWOULDBLOCK) {
90            errno = EAGAIN;
91         } else {
92            errno = EIO;            /* some other error */
93         }
94      }
95 #endif
96
97       if (nread == -1) {
98          if (errno == EINTR) {
99             continue;
100          }
101          if (errno == EAGAIN) {
102             bmicrosleep(0, 20000);  /* try again in 20ms */
103             continue;
104          }
105       }
106       if (nread <= 0) {
107          return -1;                /* error, or EOF */
108       }
109       nleft -= nread;
110       ptr += nread;
111       if (bsock->use_bwlimit()) {
112          bsock->control_bwlimit(nread);
113       }
114    }
115    return nbytes - nleft;          /* return >= 0 */
116 }
117
118 /*
119  * Write nbytes to the network.
120  * It may require several writes.
121  */
122
123 int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
124 {
125    int32_t nleft, nwritten;
126
127    if (bsock->is_spooling()) {
128       nwritten = fwrite(ptr, 1, nbytes, bsock->m_spool_fd);
129       if (nwritten != nbytes) {
130          berrno be;
131          bsock->b_errno = errno;
132          Qmsg3(bsock->jcr(), M_FATAL, 0, _("Attr spool write error. wrote=%d wanted=%d bytes. ERR=%s\n"),
133                nbytes, nwritten, be.bstrerror());
134          Dmsg2(400, "nwritten=%d nbytes=%d.\n", nwritten, nbytes);
135          errno = bsock->b_errno;
136          return -1;
137       }
138       return nbytes;
139    }
140
141 #ifdef HAVE_TLS
142    if (bsock->tls) {
143       /* TLS enabled */
144       return (tls_bsock_writen(bsock, ptr, nbytes));
145    }
146 #endif /* HAVE_TLS */
147
148    nleft = nbytes;
149    while (nleft > 0) {
150       do {
151          errno = 0;
152          nwritten = socketWrite(bsock->m_fd, ptr, nleft);
153          if (bsock->is_timed_out() || bsock->is_terminated()) {
154             return -1;
155          }
156
157 #ifdef HAVE_WIN32
158          /*
159           * We simulate errno on Windows for a socket
160           *  error in order to handle errors correctly.
161           */
162          if (nwritten == SOCKET_ERROR) {
163             DWORD err = WSAGetLastError();
164             nwritten = -1;
165             if (err == WSAEINTR) {
166                errno = EINTR;
167             } else if (err == WSAEWOULDBLOCK) {
168                errno = EAGAIN;
169             } else {
170                errno = EIO;        /* some other error */
171             }
172          }
173 #endif
174
175       } while (nwritten == -1 && errno == EINTR);
176       /*
177        * If connection is non-blocking, we will get EAGAIN, so
178        * use select()/poll to keep from consuming all the CPU
179        * and try again.
180        */
181       if (nwritten == -1 && errno == EAGAIN) {
182          fd_wait_data(bsock->m_fd, WAIT_WRITE, 1, 0);
183          continue;
184       }
185       if (nwritten <= 0) {
186          return -1;                /* error */
187       }
188       nleft -= nwritten;
189       ptr += nwritten;
190       if (bsock->use_bwlimit()) {
191          bsock->control_bwlimit(nwritten);
192       }
193    }
194    return nbytes - nleft;
195 }
196
197 /*
198  * Establish a TLS connection -- server side
199  *  Returns: true  on success
200  *           false on failure
201  */
202 #ifdef HAVE_TLS
203 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
204 {
205    TLS_CONNECTION *tls;
206    JCR *jcr = bsock->jcr();
207
208    tls = new_tls_connection(ctx, bsock->m_fd);
209    if (!tls) {
210       Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
211       return false;
212    }
213
214    bsock->tls = tls;
215
216    /* Initiate TLS Negotiation */
217    if (!tls_bsock_accept(bsock)) {
218       Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
219       goto err;
220    }
221
222    if (verify_list) {
223       if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
224          Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
225                                          " Peer certificate did not match a required commonName\n"),
226                                          bsock->host());
227          goto err;
228       }
229    }
230    Dmsg0(50, "TLS server negotiation established.\n");
231    return true;
232
233 err:
234    free_tls_connection(tls);
235    bsock->tls = NULL;
236    return false;
237 }
238
239 /*
240  * Establish a TLS connection -- client side
241  * Returns: true  on success
242  *          false on failure
243  */
244 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list)
245 {
246    TLS_CONNECTION *tls;
247    JCR *jcr = bsock->jcr();
248
249    tls  = new_tls_connection(ctx, bsock->m_fd);
250    if (!tls) {
251       Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
252       return false;
253    }
254
255    bsock->tls = tls;
256
257    /* Initiate TLS Negotiation */
258    if (!tls_bsock_connect(bsock)) {
259       goto err;
260    }
261
262    /* If there's an Allowed CN verify list, use that to validate the remote
263     * certificate's CN. Otherwise, we use standard host/CN matching. */
264    if (verify_list) {
265       if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
266          Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
267                                          " Peer certificate did not match a required commonName\n"),
268                                          bsock->host());
269          goto err;
270       }
271    } else if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) {
272       /* If host is 127.0.0.1, try localhost */
273       if (strcmp(bsock->host(), "127.0.0.1") != 0 ||
274              !tls_postconnect_verify_host(jcr, tls, "localhost")) {
275          Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"),
276                bsock->host());
277          goto err;
278       }
279    }
280    Dmsg0(50, "TLS client negotiation established.\n");
281    return true;
282
283 err:
284    free_tls_connection(tls);
285    bsock->tls = NULL;
286    return false;
287 }
288 #else
289
290 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
291 {
292    Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
293    return false;
294 }
295
296 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
297 {
298    Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
299    return false;
300 }
301
302 #endif /* HAVE_TLS */
303
304 #ifndef NETDB_INTERNAL
305 #define NETDB_INTERNAL  -1         /* See errno. */
306 #endif
307 #ifndef NETDB_SUCCESS
308 #define NETDB_SUCCESS   0          /* No problem. */
309 #endif
310 #ifndef HOST_NOT_FOUND
311 #define HOST_NOT_FOUND  1          /* Authoritative Answer Host not found. */
312 #endif
313 #ifndef TRY_AGAIN
314 #define TRY_AGAIN       2          /* Non-Authoritative Host not found, or SERVERFAIL. */
315 #endif
316 #ifndef NO_RECOVERY
317 #define NO_RECOVERY     3          /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
318 #endif
319 #ifndef NO_DATA
320 #define NO_DATA         4          /* Valid name, no data record of requested type. */
321 #endif
322
323 #if defined(HAVE_GETADDRINFO)
324 /* 
325  * getaddrinfo.c - Simple example of using getaddrinfo(3) function.
326  * 
327  * Michal Ludvig <michal@logix.cz> (c) 2002, 2003
328  * http://www.logix.cz/michal/devel/
329  *
330  * License: public domain.
331  */
332 const char *resolv_host(int family, const char *host, dlist *addr_list) 
333
334    IPADDR *ipaddr;
335    struct addrinfo hints, *res, *rp;
336    int errcode;
337    //char addrstr[100];
338    void *ptr;
339
340    memset (&hints, 0, sizeof(hints));
341    hints.ai_family = family; 
342    hints.ai_socktype = SOCK_STREAM; 
343    //hints.ai_flags |= AI_CANONNAME;
344
345    errcode = getaddrinfo (host, NULL, &hints, &res);
346    if (errcode != 0) return gai_strerror(errcode);
347
348    for (rp=res; res; res=res->ai_next) {
349       //inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);
350       switch (res->ai_family) {
351       case AF_INET: 
352          ipaddr = New(IPADDR(rp->ai_addr->sa_family));
353          ipaddr->set_type(IPADDR::R_MULTIPLE);
354          ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
355          ipaddr->set_addr4((in_addr *)ptr);
356          break; 
357 #if defined(HAVE_IPV6)
358       case AF_INET6: 
359          ipaddr = New(IPADDR(rp->ai_addr->sa_family));
360          ipaddr->set_type(IPADDR::R_MULTIPLE);
361          ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
362          ipaddr->set_addr6((in6_addr *)ptr);
363          break; 
364 #endif 
365       default: 
366          continue; 
367       } 
368       //inet_ntop (res->ai_family, ptr, addrstr, 100);
369       //Pmsg3(000, "IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4,
370       //         addrstr, res->ai_canonname);
371       addr_list->append(ipaddr);
372    } 
373    freeaddrinfo(rp);
374    return NULL; 
375
376
377 #else 
378
379 /*
380  * Get human readable error for gethostbyname()
381  */
382 static const char *gethost_strerror()
383 {
384    const char *msg;
385    berrno be;
386    switch (h_errno) {
387    case NETDB_INTERNAL:
388       msg = be.bstrerror();
389       break;
390    case NETDB_SUCCESS:
391       msg = _("No problem.");
392       break;
393    case HOST_NOT_FOUND:
394       msg = _("Authoritative answer for host not found.");
395       break;
396    case TRY_AGAIN:
397       msg = _("Non-authoritative for host not found, or ServerFail.");
398       break;
399    case NO_RECOVERY:
400       msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
401       break;
402    case NO_DATA:
403       msg = _("Valid name, no data record of resquested type.");
404       break;
405    default:
406       msg = _("Unknown error.");
407    }
408    return msg;
409 }
410
411 /*
412  * Note: this is the old way of resolving a host
413  *  that does not use the new getaddrinfo() above.
414  */
415 static const char *resolv_host(int family, const char *host, dlist * addr_list)
416 {
417    struct hostent *hp;
418    const char *errmsg;
419
420    P(ip_mutex);                       /* gethostbyname() is not thread safe */
421 #ifdef HAVE_GETHOSTBYNAME2
422    if ((hp = gethostbyname2(host, family)) == NULL) {
423 #else
424    if ((hp = gethostbyname(host)) == NULL) {
425 #endif
426       /* may be the strerror give not the right result -:( */
427       errmsg = gethost_strerror();
428       V(ip_mutex);
429       return errmsg;
430    } else {
431       char **p;
432       for (p = hp->h_addr_list; *p != 0; p++) {
433          IPADDR *addr =  New(IPADDR(hp->h_addrtype));
434          addr->set_type(IPADDR::R_MULTIPLE);
435          if (addr->get_family() == AF_INET) {
436              addr->set_addr4((struct in_addr*)*p);
437          }
438 #ifdef HAVE_IPV6
439          else {
440              addr->set_addr6((struct in6_addr*)*p);
441          }
442 #endif
443          addr_list->append(addr);
444       }
445       V(ip_mutex);
446    }
447    return NULL;
448 }
449 #endif
450
451 static IPADDR *add_any(int family)
452 {
453    IPADDR *addr = New(IPADDR(family));
454    addr->set_type(IPADDR::R_MULTIPLE);
455    addr->set_addr_any();
456    return addr;
457 }
458
459 /*
460  * i host = 0 means INADDR_ANY only for IPv4
461  */
462 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
463 {
464    struct in_addr inaddr;
465    IPADDR *addr = 0;
466    const char *errmsg;
467 #ifdef HAVE_IPV6
468    struct in6_addr inaddr6;
469 #endif
470
471    dlist *addr_list = New(dlist(addr, &addr->link));
472    if (!host || host[0] == '\0') {
473       if (family != 0) {
474          addr_list->append(add_any(family));
475       } else {
476          addr_list->append(add_any(AF_INET));
477 #ifdef HAVE_IPV6
478          addr_list->append(add_any(AF_INET6));
479 #endif
480       }
481    } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
482       addr = New(IPADDR(AF_INET));
483       addr->set_type(IPADDR::R_MULTIPLE);
484       addr->set_addr4(&inaddr);
485       addr_list->append(addr);
486 #ifdef HAVE_IPV6
487    } else if (inet_pton(AF_INET6, host, &inaddr6) == 1) { 
488       addr = New(IPADDR(AF_INET6));
489       addr->set_type(IPADDR::R_MULTIPLE);
490       addr->set_addr6(&inaddr6);
491       addr_list->append(addr);
492 #endif
493    } else { 
494       if (family != 0) {
495          errmsg = resolv_host(family, host, addr_list);
496          if (errmsg) {
497             *errstr = errmsg;
498             free_addresses(addr_list);
499             return 0;
500          }
501       } else {
502 #ifdef HAVE_IPV6
503          /* We try to resolv host for ipv6 and ipv4, the connection procedure
504           * will try to reach the host for each protocols. We report only "Host
505           * not found" ipv4 message (no need to have ipv6 and ipv4 messages).
506           */
507          resolv_host(AF_INET6, host, addr_list);
508 #endif
509          errmsg = resolv_host(AF_INET, host, addr_list);
510
511          if (addr_list->size() == 0) {
512             *errstr = errmsg;
513             free_addresses(addr_list);
514             return 0;
515          }
516       }
517    }
518    return addr_list;
519 }
520
521 /*
522  * Convert a network "signal" code into
523  * human readable ASCII.
524  */
525 const char *bnet_sig_to_ascii(int32_t msglen)
526 {
527    static char buf[30];
528    switch (msglen) {
529    case BNET_EOD:
530       return "BNET_EOD";           /* end of data stream */
531    case BNET_EOD_POLL:
532       return "BNET_EOD_POLL";
533    case BNET_STATUS:
534       return "BNET_STATUS";
535    case BNET_TERMINATE:
536       return "BNET_TERMINATE";     /* terminate connection */
537    case BNET_POLL:
538       return "BNET_POLL";
539    case BNET_HEARTBEAT:
540       return "BNET_HEARTBEAT";
541    case BNET_HB_RESPONSE:
542       return "BNET_HB_RESPONSE";
543    case BNET_SUB_PROMPT:
544       return "BNET_SUB_PROMPT";
545    case BNET_TEXT_INPUT:
546       return "BNET_TEXT_INPUT";
547    case BNET_FDCALLED:
548       return "BNET_FDCALLED";
549    case BNET_CMD_OK:
550       return "BNET_CMD_OK";
551    case BNET_CMD_BEGIN:
552       return "BNET_CMD_BEGIN";
553    case BNET_MAIN_PROMPT:
554       return "BNET_MAIN_PROMPT";
555    case BNET_ERROR_MSG:
556       return "BNET_ERROR_MSG";
557    default:
558       bsnprintf(buf, sizeof(buf), _("Unknown sig %d"), (int)msglen);
559       return buf;
560    }
561 }
562
563 /* Initialize internal socket structure.
564  *  This probably should be done in bsock.c
565  */
566 BSOCK *init_bsock(JCR *jcr, int sockfd, const char *who,
567                    const char *host, int port, struct sockaddr *client_addr)
568 {
569    Dmsg4(100, "socket=%d who=%s host=%s port=%d\n", sockfd, who, host, port);
570    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
571    bmemzero(bsock, sizeof(BSOCK));
572    bsock->m_master=bsock; /* don't use set_master() here */
573    bsock->m_fd = sockfd;
574    bsock->tls = NULL;
575    bsock->errors = 0;
576    bsock->m_blocking = 1;
577    bsock->pout_msg_no = &bsock->out_msg_no;
578    bsock->uninstall_send_hook_cb();
579    bsock->msg = get_pool_memory(PM_BSOCK);
580    bsock->cmsg = get_pool_memory(PM_BSOCK);
581    bsock->errmsg = get_pool_memory(PM_MESSAGE);
582    bsock->set_who(bstrdup(who));
583    bsock->set_host(bstrdup(host));
584    bsock->set_port(port);
585    bmemzero(&bsock->peer_addr, sizeof(bsock->peer_addr));
586    memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
587    bsock->timeout = BSOCK_TIMEOUT;
588    bsock->set_jcr(jcr);
589    return bsock;
590 }
591
592 BSOCK *dup_bsock(BSOCK *osock)
593 {
594    BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
595    osock->set_locking();
596    memcpy(bsock, osock, sizeof(BSOCK));
597    bsock->msg = get_pool_memory(PM_BSOCK);
598    bsock->cmsg = get_pool_memory(PM_BSOCK);
599    bsock->errmsg = get_pool_memory(PM_MESSAGE);
600    if (osock->who()) {
601       bsock->set_who(bstrdup(osock->who()));
602    }
603    if (osock->host()) {
604       bsock->set_host(bstrdup(osock->host()));
605    }
606    if (osock->src_addr) {
607       bsock->src_addr = New( IPADDR( *(osock->src_addr)) );
608    }
609    bsock->set_duped();
610    bsock->set_master(osock);
611    return bsock;
612 }
613
614 int set_socket_errno(int sockstat)
615 {
616 #ifdef HAVE_WIN32
617    /*
618     * For Windows, we must simulate Unix errno on a socket
619     *  error in order to handle errors correctly.
620     */
621    if (sockstat == SOCKET_ERROR) {
622       berrno be;
623       DWORD err = WSAGetLastError();
624       if (err == WSAEINTR) {
625          errno = EINTR;
626          return sockstat;
627       } else if (err == WSAEWOULDBLOCK) {
628          errno = EAGAIN;
629          return sockstat;
630       } else {
631          errno = b_errno_win32 | b_errno_WSA;
632       }
633       Dmsg2(20, "Socket error: err=%d %s\n", err, be.bstrerror(err));
634    }
635 #else
636    if (sockstat == SOCKET_ERROR) {
637       /* Handle errrors from prior connections as EAGAIN */
638       switch (errno) {
639          case ENETDOWN:
640 #ifdef EPROTO
641          case EPROTO:
642 #endif
643 #ifdef ENONET
644          case ENONET:
645 #endif
646          case ENOPROTOOPT:
647          case EHOSTDOWN:
648          case EHOSTUNREACH:
649          case EOPNOTSUPP:
650          case ENETUNREACH:
651             errno = EAGAIN;
652             break;
653          default:
654             break;
655       }
656    }
657 #endif
658    return sockstat;
659 }