libdns: Hack to skip negation term.
authorGaetan Bisson <bisson@archlinux.org>
Mon, 23 Jan 2017 11:46:35 +0000 (12:46 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 23 Jan 2017 11:46:35 +0000 (12:46 +0100)
* dirmngr/dns.c (dns_nssconf_loadfile): Skip negation terms in
nsswitch.conf parser.
--

This small patch was submitted along with this comment:

  We've been having issues over at Arch Linux with the new libdns
  code.  Our /etc/nsswitch.conf contains the following line:

    hosts: files mymachines resolve [!UNAVAIL=return] dns myhostname

  And it turns out dirmngr fails to parse the negation statement (the
  bang in !UNAVAIL). This results in gnupg not being able to resolve
  any name.

  Looking at dirmngr/dns.c it was unclear to me how to properly handle
  such negations. The dns_anyconf_scan calls used in
  dns_nssconf_loadfile do not allow to store a negation bit easily...

  In the meantime, I wrote the attached patch which ignores those
  statements altogether. It makes libdns work as expected for us.

Commit log written by wk

dirmngr/dns.c

index 016ff44..869e7ed 100644 (file)
@@ -6071,7 +6071,15 @@ int dns_nssconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) {
                        if ('[' == dns_anyconf_peek(fp)) {
                                dns_anyconf_skip("[ \t", fp);
 
-                               while (dns_anyconf_scan(&cf, "%w_", fp, &error)) {
+                               for (;;) {
+                                       if ('!' == dns_anyconf_peek(fp)) {
+                                               dns_anyconf_skip("! \t", fp);
+                                               /* FIXME: negating statuses; currently not implemented */
+                                               dns_anyconf_skip("^#;]\n", fp); /* skip to end of criteria */
+                                               break;
+                                       }
+
+                                       if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) break;
                                        dns_anyconf_skip("= \t", fp);
                                        if (!dns_anyconf_scan(&cf, "%w_", fp, &error)) {
                                                dns_anyconf_pop(&cf); /* discard status */