2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2018 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()/poll to keep from consuming all the CPU
181 if (nwritten == -1 && errno == EAGAIN) {
182 fd_wait_data(bsock->m_fd, WAIT_WRITE, 1, 0);
186 return -1; /* error */
190 if (bsock->use_bwlimit()) {
191 bsock->control_bwlimit(nwritten);
194 return nbytes - nleft;
198 * Establish a TLS connection -- server side
199 * Returns: true on success
203 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
206 JCR *jcr = bsock->jcr();
208 tls = new_tls_connection(ctx, bsock->m_fd);
210 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
216 /* Initiate TLS Negotiation */
217 if (!tls_bsock_accept(bsock)) {
218 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS Negotiation failed.\n"));
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"),
230 Dmsg0(50, "TLS server negotiation established.\n");
234 free_tls_connection(tls);
240 * Establish a TLS connection -- client side
241 * Returns: true on success
244 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK *bsock, alist *verify_list)
247 JCR *jcr = bsock->jcr();
249 tls = new_tls_connection(ctx, bsock->m_fd);
251 Qmsg0(bsock->jcr(), M_FATAL, 0, _("TLS connection initialization failed.\n"));
257 /* Initiate TLS Negotiation */
258 if (!tls_bsock_connect(bsock)) {
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. */
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"),
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"),
280 Dmsg0(50, "TLS client negotiation established.\n");
284 free_tls_connection(tls);
290 bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
292 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enabled but not configured.\n"));
296 bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list)
298 Jmsg(bsock->jcr(), M_ABORT, 0, _("TLS enable but not configured.\n"));
302 #endif /* HAVE_TLS */
304 #ifndef NETDB_INTERNAL
305 #define NETDB_INTERNAL -1 /* See errno. */
307 #ifndef NETDB_SUCCESS
308 #define NETDB_SUCCESS 0 /* No problem. */
310 #ifndef HOST_NOT_FOUND
311 #define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found. */
314 #define TRY_AGAIN 2 /* Non-Authoritative Host not found, or SERVERFAIL. */
317 #define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP. */
320 #define NO_DATA 4 /* Valid name, no data record of requested type. */
323 #if defined(HAVE_GETADDRINFO)
325 * getaddrinfo.c - Simple example of using getaddrinfo(3) function.
327 * Michal Ludvig <michal@logix.cz> (c) 2002, 2003
328 * http://www.logix.cz/michal/devel/
330 * License: public domain.
332 const char *resolv_host(int family, const char *host, dlist *addr_list)
335 struct addrinfo hints, *res, *rp;
340 memset (&hints, 0, sizeof(hints));
341 hints.ai_family = family;
342 hints.ai_socktype = SOCK_STREAM;
343 //hints.ai_flags |= AI_CANONNAME;
345 errcode = getaddrinfo (host, NULL, &hints, &res);
346 if (errcode != 0) return gai_strerror(errcode);
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) {
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);
357 #if defined(HAVE_IPV6)
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);
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);
380 * Get human readable error for gethostbyname()
382 static const char *gethost_strerror()
388 msg = be.bstrerror();
391 msg = _("No problem.");
394 msg = _("Authoritative answer for host not found.");
397 msg = _("Non-authoritative for host not found, or ServerFail.");
400 msg = _("Non-recoverable errors, FORMERR, REFUSED, or NOTIMP.");
403 msg = _("Valid name, no data record of resquested type.");
406 msg = _("Unknown error.");
412 * Note: this is the old way of resolving a host
413 * that does not use the new getaddrinfo() above.
415 static const char *resolv_host(int family, const char *host, dlist * addr_list)
420 P(ip_mutex); /* gethostbyname() is not thread safe */
421 #ifdef HAVE_GETHOSTBYNAME2
422 if ((hp = gethostbyname2(host, family)) == NULL) {
424 if ((hp = gethostbyname(host)) == NULL) {
426 /* may be the strerror give not the right result -:( */
427 errmsg = gethost_strerror();
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);
440 addr->set_addr6((struct in6_addr*)*p);
443 addr_list->append(addr);
451 static IPADDR *add_any(int family)
453 IPADDR *addr = New(IPADDR(family));
454 addr->set_type(IPADDR::R_MULTIPLE);
455 addr->set_addr_any();
460 * i host = 0 means INADDR_ANY only for IPv4
462 dlist *bnet_host2ipaddrs(const char *host, int family, const char **errstr)
464 struct in_addr inaddr;
468 struct in6_addr inaddr6;
471 dlist *addr_list = New(dlist(addr, &addr->link));
472 if (!host || host[0] == '\0') {
474 addr_list->append(add_any(family));
476 addr_list->append(add_any(AF_INET));
478 addr_list->append(add_any(AF_INET6));
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);
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);
495 errmsg = resolv_host(family, host, addr_list);
498 free_addresses(addr_list);
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).
507 resolv_host(AF_INET6, host, addr_list);
509 errmsg = resolv_host(AF_INET, host, addr_list);
511 if (addr_list->size() == 0) {
513 free_addresses(addr_list);
522 * Convert a network "signal" code into
523 * human readable ASCII.
525 const char *bnet_sig_to_ascii(int32_t msglen)
530 return "BNET_EOD"; /* End of data stream, new data may follow */
532 return "BNET_EOD_POLL"; /* End of data and poll all in one */
534 return "BNET_STATUS"; /* Send full status */
536 return "BNET_TERMINATE"; /* Conversation terminated, doing close() */
538 return "BNET_POLL"; /* Poll request, I'm hanging on a read */
540 return "BNET_HEARTBEAT"; /* Heartbeat Response requested */
541 case BNET_HB_RESPONSE:
542 return "BNET_HB_RESPONSE"; /* Only response permited to HB */
544 return "BNET_BTIME"; /* Send UTC btime */
546 return "BNET_BREAK"; /* Stop current command -- ctl-c */
547 case BNET_START_SELECT:
548 return "BNET_START_SELECT"; /* Start of a selection list */
549 case BNET_END_SELECT:
550 return "BNET_END_SELECT"; /* End of a select list */
551 case BNET_INVALID_CMD:
552 return "BNET_INVALID_CMD"; /* Invalid command sent */
553 case BNET_CMD_FAILED:
554 return "BNET_CMD_FAILED"; /* Command failed */
556 return "BNET_CMD_OK"; /* Command succeeded */
558 return "BNET_CMD_BEGIN"; /* Start command execution */
559 case BNET_MSGS_PENDING:
560 return "BNET_MSGS_PENDING"; /* Messages pending */
561 case BNET_MAIN_PROMPT:
562 return "BNET_MAIN_PROMPT"; /* Server ready and waiting */
563 case BNET_SELECT_INPUT:
564 return "BNET_SELECT_INPUT"; /* Return selection input */
565 case BNET_WARNING_MSG:
566 return "BNET_WARNING_MSG"; /* Warning message */
568 return "BNET_ERROR_MSG"; /* Error message -- command failed */
570 return "BNET_INFO_MSG"; /* Info message -- status line */
572 return "BNET_RUN_CMD"; /* Run command follows */
574 return "BNET_YESNO"; /* Request yes no response */
575 case BNET_START_RTREE:
576 return "BNET_START_RTREE"; /* Start restore tree mode */
578 return "BNET_END_RTREE"; /* End restore tree mode */
579 case BNET_SUB_PROMPT:
580 return "BNET_SUB_PROMPT"; /* Indicate we are at a subprompt */
581 case BNET_TEXT_INPUT:
582 return "BNET_TEXT_INPUT"; /* Get text input from user */
583 case BNET_EXT_TERMINATE:
584 return "BNET_EXT_TERMINATE"; /* A Terminate condition has been met and
585 already reported somewhere else */
587 return "BNET_FDCALLED"; /* The FD should keep the connection for a new job */
589 bsnprintf(buf, sizeof(buf), _("Unknown sig %d"), (int)msglen);
594 /* Initialize internal socket structure.
595 * This probably should be done in bsock.c
597 BSOCK *init_bsock(JCR *jcr, int sockfd, const char *who,
598 const char *host, int port, struct sockaddr *client_addr)
600 Dmsg4(100, "socket=%d who=%s host=%s port=%d\n", sockfd, who, host, port);
601 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
602 bmemzero(bsock, sizeof(BSOCK));
603 bsock->m_master=bsock; /* don't use set_master() here */
604 bsock->m_fd = sockfd;
607 bsock->m_blocking = 1;
608 bsock->pout_msg_no = &bsock->out_msg_no;
609 bsock->uninstall_send_hook_cb();
610 bsock->msg = get_pool_memory(PM_BSOCK);
611 bsock->cmsg = get_pool_memory(PM_BSOCK);
612 bsock->errmsg = get_pool_memory(PM_MESSAGE);
613 bsock->set_who(bstrdup(who));
614 bsock->set_host(bstrdup(host));
615 bsock->set_port(port);
616 bmemzero(&bsock->peer_addr, sizeof(bsock->peer_addr));
617 memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
618 bsock->timeout = BSOCK_TIMEOUT;
623 BSOCK *dup_bsock(BSOCK *osock)
625 BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
626 osock->set_locking();
627 memcpy(bsock, osock, sizeof(BSOCK));
628 bsock->msg = get_pool_memory(PM_BSOCK);
629 bsock->cmsg = get_pool_memory(PM_BSOCK);
630 bsock->errmsg = get_pool_memory(PM_MESSAGE);
632 bsock->set_who(bstrdup(osock->who()));
635 bsock->set_host(bstrdup(osock->host()));
637 if (osock->src_addr) {
638 bsock->src_addr = New( IPADDR( *(osock->src_addr)) );
641 bsock->set_master(osock);
645 int set_socket_errno(int sockstat)
649 * For Windows, we must simulate Unix errno on a socket
650 * error in order to handle errors correctly.
652 if (sockstat == SOCKET_ERROR) {
654 DWORD err = WSAGetLastError();
655 if (err == WSAEINTR) {
658 } else if (err == WSAEWOULDBLOCK) {
662 errno = b_errno_win32 | b_errno_WSA;
664 Dmsg2(20, "Socket error: err=%d %s\n", err, be.bstrerror(err));
667 if (sockstat == SOCKET_ERROR) {
668 /* Handle errrors from prior connections as EAGAIN */