2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
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.
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.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Network Utility Routines
24 * Adapted and enhanced for Bacula, originally written
25 * for inclusion in the Apcupsd package
35 #define INADDR_NONE -1
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)
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)
50 #ifndef HAVE_GETADDRINFO
51 static pthread_mutex_t ip_mutex = PTHREAD_MUTEX_INITIALIZER;
55 * Read a nbytes from the network.
56 * It is possible that the total bytes require in several
60 int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
67 return (tls_bsock_readn(bsock, ptr, nbytes));
74 nread = socketRead(bsock->m_fd, ptr, nleft);
75 if (bsock->is_timed_out() || bsock->is_terminated()) {
81 * We simulate errno on Windows for a socket
82 * error in order to handle errors correctly.
84 if (nread == SOCKET_ERROR) {
85 DWORD err = WSAGetLastError();
87 if (err == WSAEINTR) {
89 } else if (err == WSAEWOULDBLOCK) {
92 errno = EIO; /* some other error */
101 if (errno == EAGAIN) {
102 bmicrosleep(0, 20000); /* try again in 20ms */
107 return -1; /* error, or EOF */
111 if (bsock->use_bwlimit()) {
112 bsock->control_bwlimit(nread);
115 return nbytes - nleft; /* return >= 0 */
119 * Write nbytes to the network.
120 * It may require several writes.
123 int32_t write_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes)
125 int32_t nleft, nwritten;
127 if (bsock->is_spooling()) {
128 nwritten = fwrite(ptr, 1, nbytes, bsock->m_spool_fd);
129 if (nwritten != nbytes) {
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;
144 return (tls_bsock_writen(bsock, ptr, nbytes));
146 #endif /* HAVE_TLS */
152 nwritten = socketWrite(bsock->m_fd, ptr, nleft);
153 if (bsock->is_timed_out() || bsock->is_terminated()) {
159 * We simulate errno on Windows for a socket
160 * error in order to handle errors correctly.
162 if (nwritten == SOCKET_ERROR) {
163 DWORD err = WSAGetLastError();
165 if (err == WSAEINTR) {
167 } else if (err == WSAEWOULDBLOCK) {
170 errno = EIO; /* some other error */
175 } while (nwritten == -1 && errno == EINTR);
177 * If connection is non-blocking, we will get EAGAIN, so
178 * use select() to keep from consuming all the CPU
181 if (nwritten == -1 && errno == EAGAIN) {
186 FD_SET((unsigned)bsock->m_fd, &fdset);
189 select(bsock->m_fd + 1, NULL, &fdset, NULL, &tv);
193 return -1; /* error */
197 if (bsock->use_bwlimit()) {
198 bsock->control_bwlimit(nwritten);
201 return nbytes - nleft;
205 * Establish a TLS connection -- server side
206 * Returns: true on success
210 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
213 JCR *jcr = bsock->jcr();
215 tls = new_tls_connection(ctx, bsock->m_fd);
217 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
223 /* Initiate TLS Negotiation */
224 if (!tls_bsock_accept(bsock)) {
225 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
230 if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
231 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
232 " Peer certificate did not match a required commonName\n"),
237 Dmsg0(50, "TLS server negotiation established.\n");
241 free_tls_connection(tls);
247 * Establish a TLS connection -- client side
248 * Returns: true on success
251 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list)
254 JCR *jcr = bsock->jcr();
256 tls = new_tls_connection(ctx, bsock->m_fd);
258 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
264 /* Initiate TLS Negotiation */
265 if (!tls_bsock_connect(bsock)) {
269 /* If there's an Allowed CN verify list, use that to validate the remote
270 * certificate's CN. Otherwise, we use standard host/CN matching. */
272 if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) {
273 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed."
274 " Peer certificate did not match a required commonName\n"),
278 } else if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) {
279 /* If host is 127.0.0.1, try localhost */
280 if (strcmp(bsock->host(), "127.0.0.1") != 0 ||
281 !tls_postconnect_verify_host(jcr, tls, "localhost")) {
282 Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host name \"%s\" did not match presented certificate\n"),
287 Dmsg0(50, "TLS client negotiation established.\n");
291 free_tls_connection(tls);
297 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
299 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
303 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
305 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
309 #endif /* HAVE_TLS */
311 #ifndef NETDB_INTERNAL
312 #define NETDB_INTERNAL -1 /* See errno. */
314 #ifndef NETDB_SUCCESS
315 #define NETDB_SUCCESS 0 /* No problem. */
317 #ifndef HOST_NOT_FOUND
318 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
321 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
324 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
327 #define NO_DATA 4 /* Valid name, no data record of requested type. */
330 static IPADDR *add_any(int family)
332 IPADDR *addr = New(IPADDR(family));
333 addr->set_type(IPADDR::R_MULTIPLE);
334 addr->set_addr_any();
338 #if defined(HAVE_GETADDRINFO)
340 * getaddrinfo.c - Simple example of using getaddrinfo(3) function.
342 * Michal Ludvig <michal@logix.cz> (c) 2002, 2003
343 * http://www.logix.cz/michal/devel/
345 * License: public domain.
347 const char *resolv_host(int family, const char *host, dlist *addr_list)
350 struct addrinfo hints, *res, *rp;
355 memset (&hints, 0, sizeof(hints));
356 hints.ai_family = family;
357 hints.ai_socktype = SOCK_STREAM;
358 //hints.ai_flags |= AI_CANONNAME;
360 errcode = getaddrinfo (host, NULL, &hints, &res);
361 if (errcode != 0) return gai_strerror(errcode);
363 for (rp=res; res; res=res->ai_next) {
364 //inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100);
365 switch (res->ai_family) {
367 ipaddr = New(IPADDR(rp->ai_addr->sa_family));
368 ipaddr->set_type(IPADDR::R_MULTIPLE);
369 ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
370 ipaddr->set_addr4((in_addr *)ptr);
372 #if defined(HAVE_IPV6)
374 ipaddr = New(IPADDR(rp->ai_addr->sa_family));
375 ipaddr->set_type(IPADDR::R_MULTIPLE);
376 ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
377 ipaddr->set_addr6((in6_addr *)ptr);
383 //inet_ntop (res->ai_family, ptr, addrstr, 100);
384 //Pmsg3(000, "IPv%d address: %s (%s)\n", res->ai_family == PF_INET6 ? 6 : 4,
385 // addrstr, res->ai_canonname);
386 addr_list->append(ipaddr);
395 * Get human readable error for gethostbyname()
397 static const char *gethost_strerror()
403 msg = be.bstrerror();
406 msg = _("No problem.");
409 msg = _("Authoritative answer for host not found.");
412 msg = _("Non-authoritative for host not found, or ServerFail.");
415 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
418 msg = _("Valid name, no data record of resquested type.");
421 msg = _("Unknown error.");
427 * Note: this is the old way of resolving a host
428 * that does not use the new getaddrinfo() above.
430 static const char *resolv_host(int family, const char *host, dlist * addr_list)
435 P(ip_mutex); /* gethostbyname() is not thread safe */
436 #ifdef HAVE_GETHOSTBYNAME2
437 if ((hp = gethostbyname2(host, family)) == NULL) {
439 if ((hp = gethostbyname(host)) == NULL) {
441 /* may be the strerror give not the right result -:( */
442 errmsg = gethost_strerror();
447 for (p = hp->h_addr_list; *p != 0; p++) {
448 IPADDR *addr = New(IPADDR(hp->h_addrtype));
449 addr->set_type(IPADDR::R_MULTIPLE);
450 if (addr->get_family() == AF_INET) {
451 addr->set_addr4((struct in_addr*)*p);
455 addr->set_addr6((struct in6_addr*)*p);
458 addr_list->append(addr);
467 * i host = 0 means INADDR_ANY only for IPv4
469 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
471 struct in_addr inaddr;
475 struct in6_addr inaddr6;
478 dlist *addr_list = New(dlist(addr, &addr->link));
479 if (!host || host[0] == '\0') {
481 addr_list->append(add_any(family));
483 addr_list->append(add_any(AF_INET));
485 addr_list->append(add_any(AF_INET6));
488 } else if (inet_aton(host, &inaddr)) { /* MA Bug 4 */
489 addr = New(IPADDR(AF_INET));
490 addr->set_type(IPADDR::R_MULTIPLE);
491 addr->set_addr4(&inaddr);
492 addr_list->append(addr);
494 } else if (inet_pton(AF_INET6, host, &inaddr6) == 1) {
495 addr = New(IPADDR(AF_INET6));
496 addr->set_type(IPADDR::R_MULTIPLE);
497 addr->set_addr6(&inaddr6);
498 addr_list->append(addr);
502 errmsg = resolv_host(family, host, addr_list);
505 free_addresses(addr_list);
510 /* We try to resolv host for ipv6 and ipv4, the connection procedure
511 * will try to reach the host for each protocols. We report only "Host
512 * not found" ipv4 message (no need to have ipv6 and ipv4 messages).
514 resolv_host(AF_INET6, host, addr_list);
516 errmsg = resolv_host(AF_INET, host, addr_list);
518 if (addr_list->size() == 0) {
520 free_addresses(addr_list);
529 * Convert a network "signal" code into
530 * human readable ASCII.
532 const char *bnet_sig_to_ascii(int32_t msglen)
537 return "BNET_EOD"; /* end of data stream */
539 return "BNET_EOD_POLL";
541 return "BNET_STATUS";
543 return "BNET_TERMINATE"; /* terminate connection */
547 return "BNET_HEARTBEAT";
548 case BNET_HB_RESPONSE:
549 return "BNET_HB_RESPONSE";
550 case BNET_SUB_PROMPT:
551 return "BNET_SUB_PROMPT";
552 case BNET_TEXT_INPUT:
553 return "BNET_TEXT_INPUT";
555 bsnprintf(buf, sizeof(buf), _("Unknown sig %d"), (int)msglen);
560 /* Initialize internal socket structure.
561 * This probably should be done in net_open
563 BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
564 struct sockaddr *client_addr)
566 Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
567 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
568 memset(bsock, 0, sizeof(BSOCK));
569 bsock->m_fd = sockfd;
572 bsock->m_blocking = 1;
573 bsock->pout_msg_no = &bsock->out_msg_no;
574 bsock->msg = get_pool_memory(PM_BSOCK);
575 bsock->errmsg = get_pool_memory(PM_MESSAGE);
576 bsock->set_who(bstrdup(who));
577 bsock->set_host(bstrdup(host));
578 bsock->set_port(port);
579 memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
580 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
581 bsock->timeout = BSOCK_TIMEOUT;
586 BSOCK *dup_bsock(BSOCK *osock)
588 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
589 osock->set_locking();
590 memcpy(bsock, osock, sizeof(BSOCK));
591 bsock->msg = get_pool_memory(PM_BSOCK);
592 bsock->errmsg = get_pool_memory(PM_MESSAGE);
594 bsock->set_who(bstrdup(osock->who()));
597 bsock->set_host(bstrdup(osock->host()));
599 if (osock->src_addr) {
600 bsock->src_addr = New( IPADDR( *(osock->src_addr)) );
606 int set_socket_errno(int sockstat)
610 * For Windows, we must simulate Unix errno on a socket
611 * error in order to handle errors correctly.
613 if (sockstat == SOCKET_ERROR) {
615 DWORD err = WSAGetLastError();
616 if (err == WSAEINTR) {
619 } else if (err == WSAEWOULDBLOCK) {
623 errno = b_errno_win32 | b_errno_WSA;
625 Dmsg2(20, "Socket error: err=%d %s\n", err, be.bstrerror(err));
628 if (sockstat == SOCKET_ERROR) {
629 /* Handle errrors from prior connections as EAGAIN */