]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/address_conf.c
Backport from BEE
[bacula/bacula] / bacula / src / lib / address_conf.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2004-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    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    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *   Configuration file parser for IP-Addresse ipv4 and ipv6
18  *
19  *     Written by Meno Abels, June MMIV
20  *
21  */
22
23
24 #include "bacula.h"
25 #ifdef HAVE_ARPA_NAMESER_H
26 #include <arpa/nameser.h>
27 #endif
28 #ifdef HAVE_RESOLV_H
29 //#include <resolv.h>
30 #endif
31
32 static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultport, int family,
33                 const char *hostname_str, const char *port_str, char *buf, int buflen);
34
35
36 IPADDR::IPADDR(const IPADDR &src) : type(src.type)
37 {
38   memcpy(&saddrbuf, &src.saddrbuf, sizeof(saddrbuf));
39   saddr  = &saddrbuf.dontuse;
40   saddr4 = &saddrbuf.dontuse4;
41 #ifdef HAVE_IPV6
42   saddr6 = &saddrbuf.dontuse6;
43 #endif
44 }
45
46 IPADDR::IPADDR(int af) : type(R_EMPTY)
47 {
48 #ifdef HAVE_IPV6
49   if (!(af == AF_INET6 || af == AF_INET)) {
50      Emsg1(M_ERROR_TERM, 0, _("Only ipv4 and ipv6 are supported (%d)\n"), af);
51   }
52 #else
53   if (af != AF_INET) {
54      Emsg1(M_ERROR_TERM, 0, _("Only ipv4 is supported (%d)\n"), af);
55   }
56 #endif
57   memset(&saddrbuf, 0, sizeof(saddrbuf));
58   saddr  = &saddrbuf.dontuse;
59   saddr4 = &saddrbuf.dontuse4;
60 #ifdef HAVE_IPV6
61   saddr6 = &saddrbuf.dontuse6;
62 #endif
63   saddr->sa_family = af;
64   if (af  == AF_INET) {
65      saddr4->sin_port = 0xffff;
66   }
67 #ifdef HAVE_IPV6
68   else {
69      saddr6->sin6_port = 0xffff;
70   }
71 #endif
72 #ifdef HAVE_SA_LEN
73 #ifdef HAVE_IPV6
74   saddr->sa_len = (af == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
75 #else
76   saddr->sa_len = sizeof(sockaddr_in);
77 #endif
78 #endif
79    set_addr_any();
80 }
81
82 void IPADDR::set_type(i_type o)
83 {
84    type = o;
85 }
86
87 IPADDR::i_type IPADDR::get_type() const
88 {
89    return type;
90 }
91
92 unsigned short IPADDR::get_port_net_order() const
93 {
94    unsigned short port = 0;
95    if (saddr->sa_family == AF_INET) {
96       port = saddr4->sin_port;
97    }
98 #ifdef HAVE_IPV6
99    else {
100       port = saddr6->sin6_port;
101    }
102 #endif
103     return port;
104 }
105
106 void IPADDR::set_port_net(unsigned short port)
107 {
108    if (saddr->sa_family == AF_INET) {
109       saddr4->sin_port = port;
110    }
111 #ifdef HAVE_IPV6
112    else {
113       saddr6->sin6_port = port;
114    }
115 #endif
116 }
117
118 int IPADDR::get_family() const
119 {
120     return saddr->sa_family;
121 }
122
123 /*
124  * Note, this returns the address of the socket structure
125  *  not the address of the socket address.
126  *  This socket address is a union of the different types
127  *  of sockets (IPv4, ...) available, so it is portable.
128  */
129 struct sockaddr *IPADDR::get_sockaddr()
130 {
131    return saddr;
132 }
133
134 int IPADDR::get_sockaddr_len()
135 {
136 #ifdef HAVE_IPV6
137    return saddr->sa_family == AF_INET ? sizeof(*saddr4) : sizeof(*saddr6);
138 #else
139    return sizeof(*saddr4);
140 #endif
141 }
142 void IPADDR::copy_addr(IPADDR *src)
143 {
144    if (saddr->sa_family == AF_INET) {
145       saddr4->sin_addr.s_addr = src->saddr4->sin_addr.s_addr;
146    }
147 #ifdef HAVE_IPV6
148    else if (saddr->sa_family == AF_INET6) {
149       saddr6->sin6_addr = src->saddr6->sin6_addr;
150    }
151 #endif
152 }
153
154 void IPADDR::set_addr_any()
155 {
156    if (saddr->sa_family == AF_INET) {
157       saddr4->sin_addr.s_addr = INADDR_ANY;
158    }
159 #ifdef HAVE_IPV6
160    else if (saddr->sa_family == AF_INET6) {
161      saddr6->sin6_addr = in6addr_any;
162    }
163 #endif
164 }
165
166 void IPADDR::set_addr4(struct in_addr *ip4)
167 {
168    if (saddr->sa_family != AF_INET) {
169       Emsg1(M_ERROR_TERM, 0, _("You tried to assign a ipv6 address to an ipv4(%d)\n"), saddr->sa_family);
170    }
171    saddr4->sin_addr = *ip4;
172 }
173
174 #ifdef HAVE_IPV6
175 void IPADDR::set_addr6(struct in6_addr *ip6)
176 {
177    if (saddr->sa_family != AF_INET6) {
178       Emsg1(M_ERROR_TERM, 0, _("You tried to assign an ipv4 address to an ipv6(%d)\n"), saddr->sa_family);
179    }
180    saddr6->sin6_addr = *ip6;
181 }
182 #endif
183
184 const char *IPADDR::get_address(char *outputbuf, int outlen)
185 {
186    outputbuf[0] = '\0';
187 #ifdef HAVE_INET_NTOP
188 # ifdef HAVE_IPV6
189    inet_ntop(saddr->sa_family, saddr->sa_family == AF_INET ?
190               (void*)&(saddr4->sin_addr) : (void*)&(saddr6->sin6_addr),
191               outputbuf, outlen);
192 # else
193    inet_ntop(saddr->sa_family, (void*)&(saddr4->sin_addr), outputbuf, outlen);
194 # endif
195 #else
196    bstrncpy(outputbuf, inet_ntoa(saddr4->sin_addr), outlen);
197 #endif
198    return outputbuf;
199 }
200
201 const char *IPADDR::build_address_str(char *buf, int blen)
202 {
203    char tmp[1024];
204    if (get_family() == AF_INET) {
205       bsnprintf(buf, blen, "%s:%hu ",
206                 get_address(tmp, sizeof(tmp) - 1), get_port_host_order());
207    } else {
208       bsnprintf(buf, blen, "[%s]:%hu ",
209                 get_address(tmp, sizeof(tmp) - 1), get_port_host_order());
210    }
211    return buf;
212 }
213
214 const char *build_addresses_str(dlist *addrs, char *buf, int blen)
215 {
216    if (!addrs || addrs->size() == 0) {
217       bstrncpy(buf, "", blen);
218       return buf;
219    }
220    char *work = buf;
221    IPADDR *p;
222    foreach_dlist(p, addrs) {
223       char tmp[1024];
224       int len = bsnprintf(work, blen, "%s", p->build_address_str(tmp, sizeof(tmp)));
225       if (len < 0)
226          break;
227       work += len;
228       blen -= len;
229    }
230    return buf;
231 }
232
233 const char *get_first_address(dlist *addrs, char *outputbuf, int outlen)
234 {
235    return ((IPADDR *)(addrs->first()))->get_address(outputbuf, outlen);
236 }
237
238 int get_first_port_net_order(dlist *addrs)
239 {
240    if (!addrs) {
241       return 0;
242    } else {
243       return ((IPADDR *)(addrs->first()))->get_port_net_order();
244    }
245 }
246
247 int get_first_port_host_order(dlist *addrs)
248 {
249    if (!addrs) {
250       return 0;
251    } else {
252       return ((IPADDR *)(addrs->first()))->get_port_host_order();
253    }
254 }
255
256 void init_default_addresses(dlist **addr_list, int port)
257 {
258    char buf[1024];
259    unsigned short sport = port;
260    if (!add_address(addr_list, IPADDR::R_DEFAULT, htons(sport), AF_INET, 0, 0, buf, sizeof(buf))) {
261       Emsg1(M_ERROR_TERM, 0, _("Can't add default IPv4 address (%s)\n"), buf);
262    }
263    Dmsg1(20, "Initaddr %s\n", build_addresses_str(*addr_list, buf, sizeof(buf)));
264
265 }
266
267 static int add_address(dlist **out, IPADDR::i_type type, unsigned short defaultport, int family,
268                 const char *hostname_str, const char *port_str, char *buf, int buflen)
269 {
270    IPADDR *iaddr;
271    IPADDR *jaddr;
272    dlist *hostaddrs;
273    unsigned short port;
274    IPADDR::i_type intype = type;
275
276    buf[0] = 0;
277    dlist *addrs = (dlist *)(*(out));
278    if (!addrs) {
279       IPADDR *tmp = 0;
280       addrs = *out = New(dlist(tmp, &tmp->link));
281    }
282
283    type = (type == IPADDR::R_SINGLE_PORT ||
284            type == IPADDR::R_SINGLE_ADDR) ? IPADDR::R_SINGLE : type;
285    if (type != IPADDR::R_DEFAULT) {
286       IPADDR *def = 0;
287       foreach_dlist(iaddr, addrs) {
288          if (iaddr->get_type() == IPADDR::R_DEFAULT) {
289             def = iaddr;
290          } else if (iaddr->get_type() != type) {
291             bsnprintf(buf, buflen,
292                       _("Old style addresses cannot be mixed with new style. Try removing Port=nnn."));
293             Dmsg1(20, "%s\n", buf);
294             return 0;
295          }
296       }
297       if (def) {
298          addrs->remove(def);
299          delete def;
300       }
301    }
302
303    if (!port_str || port_str[0] == '\0') {
304       port = defaultport;
305    } else {
306       int pnum = atol(port_str);
307       if (0 < pnum && pnum < 0xffff) {
308          port = htons(pnum);
309       } else {
310          struct servent *s = getservbyname(port_str, "tcp");
311          if (s) {
312             port = s->s_port;
313          } else {
314             bsnprintf(buf, buflen, _("Cannot resolve service(%s)"), port_str);
315             Dmsg1(20, "%s\n", buf);
316             return 0;
317          }
318       }
319    }
320
321    const char *myerrstr;
322    hostaddrs = bnet_host2ipaddrs(hostname_str, family, &myerrstr);
323    if (!hostaddrs) {
324       bsnprintf(buf, buflen, _("Cannot resolve hostname(%s) %s"), hostname_str,
325                 myerrstr);
326       Dmsg1(20, "%s\n", buf);
327       return 0;
328    }
329
330    if (intype == IPADDR::R_SINGLE_PORT || intype == IPADDR::R_SINGLE_ADDR) {
331       IPADDR *addr;
332       if (addrs->size()) {
333          addr = (IPADDR *)addrs->first();
334       } else {
335          addr = New(IPADDR(family));
336          addr->set_type(type);
337          addr->set_port_net(defaultport);
338          addr->set_addr_any();
339          addrs->append(addr);
340       }
341       if (intype == IPADDR::R_SINGLE_PORT) {
342          addr->set_port_net(port);
343       }
344       if (intype == IPADDR::R_SINGLE_ADDR) {
345          addr->copy_addr((IPADDR *)(hostaddrs->first()));
346       }
347    } else {
348       foreach_dlist(iaddr, hostaddrs) {
349          IPADDR *clone;
350          /* for duplicates */
351          foreach_dlist(jaddr, addrs) {
352             if (iaddr->get_sockaddr_len() == jaddr->get_sockaddr_len() &&
353                 !memcmp(iaddr->get_sockaddr(), jaddr->get_sockaddr(),
354                     iaddr->get_sockaddr_len()))
355                 {
356                goto skip;          /* no price */
357             }
358          }
359          clone = New(IPADDR(*iaddr));
360          clone->set_type(type);
361          clone->set_port_net(port);
362          addrs->append(clone);
363        skip:
364          continue;
365       }
366    }
367    free_addresses(hostaddrs);
368    return 1;
369 }
370
371 /*
372  *  Some IPv6 rules from Wikipedia:
373  *
374  *  For convenience, an IPv6 address may be abbreviated to shorter
375  *  notations by application of the following rules, where possible.
376  *
377  * 1.  One or more leading zeroes from any groups of hexadecimal
378  *     digits are removed; this is usually done to either all or none of
379  *     the leading zeroes.  For example, the group 0042 is converted to
380  *     42.
381  *
382  * 2.  Consecutive sections of zeroes are replaced with a double
383  *     colon (::).  The double colon may only be used once in an
384  *     address, as multiple use would render the address indeterminate.
385  *     RFC 5952 recommends that a double colon must not be used to
386  *     denote an omitted single section of zeroes.[39]
387  *
388  *   my tests
389  *   positiv
390  *   = { ip = { addr = 1.2.3.4; port = 1205; } ipv4 = { addr = 1.2.3.4; port = http; } }
391  *   = { ip = {
392  *         addr = 1.2.3.4; port = 1205; }
393  *     ipv4 = {
394  *         addr = 1.2.3.4; port = http; }
395  *     ipv6 = {
396  *       addr = 1.2.3.4;
397  *       port = 1205;
398  *     }
399  *     ip = {
400  *       addr = 1.2.3.4
401  *       port = 1205
402  *     }
403  *     ip = {
404  *       addr = 1.2.3.4
405  *     }
406  *     ip = {
407  *       addr = 2001:220:222::2
408  *     }
409  *     ip = {
410  *       addr = bluedot.thun.net
411  *     }
412  *   }
413  *
414  *   negativ
415  *   = { ip = { } }
416  *   = { ipv4 { addr = doof.nowaytoheavenxyz.uhu; } }
417  *   = { ipv4 { port = 4711 } }
418  */
419 void store_addresses(LEX * lc, RES_ITEM * item, int index, int pass)
420 {
421    int token;
422    enum { EMPTYLINE = 0, PORTLINE = 0x1, ADDRLINE = 0x2 } next_line = EMPTYLINE;
423    int exist;
424    char hostname_str[1024];
425    char port_str[128];
426    int family = 0;
427    char errmsg[1024];
428
429
430    token = lex_get_token(lc, T_SKIP_EOL);
431    if (token != T_BOB) {
432       scan_err1(lc, _("Expected a block to begin with { but got: %s"), lc->str);
433    }
434
435    token = lex_get_token(lc, T_SKIP_EOL);
436    if (token == T_EOB) {
437       scan_err0(lc, _("Empty addr block is not allowed"));
438    }
439    do {
440       if (!(token == T_UNQUOTED_STRING || token == T_IDENTIFIER)) {
441          scan_err1(lc, _("Expected a string but got: %s"), lc->str);
442       }
443       if (strcasecmp("ip", lc->str) == 0) {
444          family = AF_INET6;
445       } else if (strcasecmp("ipv4", lc->str) == 0) {
446          family = AF_INET;
447       }
448 #ifdef HAVE_IPV6
449       else if (strcasecmp("ipv6", lc->str) == 0) {
450          family = AF_INET6;
451       } else {
452          scan_err1(lc, _("Expected a string [ip|ipv4|ipv6] but got: %s"), lc->str);
453       }
454 #else
455       else {
456          scan_err1(lc, _("Expected a string [ip|ipv4] but got: %s"), lc->str);
457       }
458 #endif
459       token = lex_get_token(lc, T_SKIP_EOL);
460       if (token != T_EQUALS) {
461          scan_err1(lc, _("Expected an equal = but got: %s"), lc->str);
462       }
463       token = lex_get_token(lc, T_SKIP_EOL);
464       if (token != T_BOB) {
465          scan_err1(lc, _("Expected a block to begin with { but got: %s"), lc->str);
466       }
467       token = lex_get_token(lc, T_SKIP_EOL);
468       exist = EMPTYLINE;
469       port_str[0] = hostname_str[0] = '\0';
470       do {
471          if (token != T_IDENTIFIER) {
472             scan_err1(lc, _("Expected an identifier [addr|port] but got: %s"), lc->str);
473          }
474          if (strcasecmp("port", lc->str) == 0) {
475             next_line = PORTLINE;
476             if (exist & PORTLINE) {
477                scan_err0(lc, _("Only one port per address block"));
478             }
479             exist |= PORTLINE;
480          } else if (strcasecmp("addr", lc->str) == 0) {
481             next_line = ADDRLINE;
482             if (exist & ADDRLINE) {
483                scan_err0(lc, _("Only one addr per address block"));
484             }
485             exist |= ADDRLINE;
486          } else {
487             scan_err1(lc, _("Expected a identifier [addr|port] but got: %s"), lc->str);
488          }
489          token = lex_get_token(lc, T_SKIP_EOL);
490          if (token != T_EQUALS) {
491             scan_err1(lc, _("Expected a equal =, got: %s"), lc->str);
492          }
493          token = lex_get_token(lc, T_SKIP_EOL);
494          switch (next_line) {
495          case PORTLINE:
496             if (!
497                 (token == T_UNQUOTED_STRING || token == T_NUMBER ||
498                  token == T_IDENTIFIER)) {
499                scan_err1(lc, _("Expected a number or a string but got: %s"), lc->str);
500             }
501             bstrncpy(port_str, lc->str, sizeof(port_str));
502             break;
503          case ADDRLINE:
504             if (!(token == T_UNQUOTED_STRING || token == T_IDENTIFIER)) {
505                scan_err1(lc, _("Expected an IP number or a hostname but got: %s"),
506                          lc->str);
507             }
508             bstrncpy(hostname_str, lc->str, sizeof(hostname_str));
509             break;
510          case EMPTYLINE:
511             scan_err0(lc, _("State machine missmatch"));
512             break;
513          }
514          token = lex_get_token(lc, T_SKIP_EOL);
515       } while (token == T_IDENTIFIER);
516       if (token != T_EOB) {
517          scan_err1(lc, _("Expected a end of block with } but got: %s"), lc->str);
518       }
519
520       if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_MULTIPLE,
521                htons(item->default_value), family, hostname_str, port_str,
522                errmsg, sizeof(errmsg))) {
523          scan_err3(lc, _("Cannot add hostname(%s) and port(%s) to addrlist (%s)"),
524                    hostname_str, port_str, errmsg);
525       }
526       token = scan_to_next_not_eol(lc);
527    } while ((token == T_IDENTIFIER || token == T_UNQUOTED_STRING));
528    if (token != T_EOB) {
529       scan_err1(lc, _("Expected an end of block with } but got: %s"), lc->str);
530    }
531 }
532
533 void store_addresses_address(LEX * lc, RES_ITEM * item, int index, int pass)
534 {
535    char errmsg[1024];
536    int token = lex_get_token(lc, T_SKIP_EOL);
537    if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) {
538       scan_err1(lc, _("Expected an IP number or a hostname, got: %s"), lc->str);
539    }
540    if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_SINGLE_ADDR,
541                     htons(item->default_value), AF_INET, lc->str, 0,
542                     errmsg, sizeof(errmsg))) {
543       scan_err2(lc, _("Cannot add port (%s) to (%s)"), lc->str, errmsg);
544    }
545 }
546
547 void store_addresses_port(LEX * lc, RES_ITEM * item, int index, int pass)
548 {
549    char errmsg[1024];
550    int token = lex_get_token(lc, T_SKIP_EOL);
551    if (!(token == T_UNQUOTED_STRING || token == T_NUMBER || token == T_IDENTIFIER)) {
552       scan_err1(lc, _("Expected a port number or string, got: %s"), lc->str);
553    }
554    if (pass == 1 && !add_address((dlist **)(item->value), IPADDR::R_SINGLE_PORT,
555                     htons(item->default_value), AF_INET, 0, lc->str,
556                     errmsg, sizeof(errmsg))) {
557       scan_err2(lc, _("Cannot add port (%s) to (%s)"), lc->str, errmsg);
558    }
559 }
560
561 void free_addresses(dlist * addrs)
562 {
563    while (!addrs->empty()) {
564       IPADDR *ptr = (IPADDR*)addrs->first();
565       addrs->remove(ptr);
566       delete ptr;
567    }
568    delete addrs;
569 }
570
571 int sockaddr_get_port_net_order(const struct sockaddr *client_addr)
572 {
573    if (client_addr->sa_family == AF_INET) {
574       return ((struct sockaddr_in *)client_addr)->sin_port;
575    }
576 #ifdef HAVE_IPV6
577    else {
578       return ((struct sockaddr_in6 *)client_addr)->sin6_port;
579    }
580 #endif
581    return -1;
582 }
583
584 int sockaddr_get_port(const struct sockaddr *client_addr)
585 {
586    if (client_addr->sa_family == AF_INET) {
587       return ntohs(((struct sockaddr_in *)client_addr)->sin_port);
588    }
589 #ifdef HAVE_IPV6
590    else {
591       return ntohs(((struct sockaddr_in6 *)client_addr)->sin6_port);
592    }
593 #endif
594    return -1;
595 }
596
597
598 char *sockaddr_to_ascii(const struct sockaddr *sa, int socklen, char *buf, int buflen)
599 {
600 #ifdef HAVE_GETNAMEINFO
601   /* This is the more modern way of doing it */
602   char clienthost[NI_MAXHOST];
603   char clientservice[NI_MAXSERV];
604   int status;
605   status = getnameinfo(sa, socklen, clienthost, sizeof(clienthost),
606                        clientservice, sizeof(clientservice),
607                        NI_NUMERICHOST | NI_NUMERICSERV);
608   if (status == 0) {
609      /* Enclose IPv6 in [] */
610      if (strchr(clienthost, ':') != NULL) {
611         bsnprintf(buf, buflen, "[%s]", clienthost);
612      } else {
613         bstrncpy(buf, clienthost, buflen);
614      }
615   } else {
616      bstrncpy(buf, "Hostname not found", buflen);
617   }
618
619 #else
620 #ifdef HAVE_INET_NTOP
621    inet_ntop(sa->sa_family,
622 # ifdef HAVE_IPV6
623              sa->sa_family == AF_INET ?
624                  (void*)&(((struct sockaddr_in*)sa)->sin_addr) :
625                  (void*)&(((struct sockaddr_in6*)sa)->sin6_addr),
626 # else
627                  (void*)&(((struct sockaddr_in*)sa)->sin_addr),
628 # endif /* HAVE_IPV6 */
629              buf, buflen);
630 #else
631    bstrncpy(buf, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), buflen);
632 #endif
633 #endif
634    return buf;
635 }
636
637 /*
638  * Remove duplicate IP addresses.
639  */
640 void remove_duplicate_addresses(dlist *addr_list)
641 {
642    IPADDR *ipaddr, *next, *duplicate;
643    /*
644     * Remove any duplicate addresses.
645     */
646    for (ipaddr = (IPADDR *)addr_list->first(); ipaddr;
647         ipaddr = (IPADDR *)addr_list->next(ipaddr)) {
648       for (next = (IPADDR *)addr_list->next(ipaddr); next; ) {
649          duplicate = NULL;
650          if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() &&
651              memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(),
652                     ipaddr->get_sockaddr_len()) == 0) {
653             duplicate = next;
654          }
655          next = (IPADDR *)addr_list->next(next);
656          if (duplicate) {
657             addr_list->remove(duplicate);  /* remove from list */
658             delete duplicate;              /* free it */
659          }
660       }
661    }
662 }
663
664 #ifdef HAVE_OLD_SOCKOPT
665 int inet_aton(const char *cp, struct in_addr *inp)
666 {
667    struct in_addr inaddr;
668
669    if((inaddr.s_addr = inet_addr(cp)) != INADDR_NONE) {
670       inp->s_addr = inaddr.s_addr;
671       return 1;
672    }
673    return 0;
674 }
675 #endif