gpg-connect-agent: Make it easier to connect to the dirmngr.
[gnupg.git] / keyserver / gpgkeys_kdns.c
index 522f1c8..14651f9 100644 (file)
@@ -1,5 +1,5 @@
 /* gpgkeys_kdns.c - Fetch a key via the GnuPG specific KDNS scheme.
- * Copyright (C) 2008 g10 Code GmbH
+ * Copyright (C) 2008 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -29,6 +29,9 @@
 #include <assert.h>
 #ifdef HAVE_ADNS_H
 # include <adns.h>
+# ifndef HAVE_ADNS_FREE
+#  define adns_free free
+# endif
 #endif
 
 #define INCLUDED_BY_MAIN_MODULE 1
@@ -63,7 +66,8 @@ static const char *kdns_root;
 /* The replacement string for the at sign.  */
 static const char *kdns_at_repl;
 
-
+/* Flag indicating that a TCP connection should be used.  */
+static int kdns_usevc;
 
 
 \f
@@ -83,7 +87,7 @@ get_key (adns_state adns_ctx, char *address)
   domain = strrchr (address, '@');
   if (!domain || domain == address || !domain[1])
     {
-      fprintf (console, PGM": invalid mail address `%s'\n", address);
+      fprintf (console, PGM": invalid mail address '%s'\n", address);
       ret = KEYSERVER_GENERAL_ERROR;
       goto leave;
     }
@@ -101,20 +105,19 @@ get_key (adns_state adns_ctx, char *address)
 
   fprintf (output,"NAME %s BEGIN\n", address);
   if (opt->verbose > 2)
-    fprintf(console, PGM": looking up `%s'\n", name);
-
+    fprintf(console, PGM": looking up '%s'\n", name);
 
   if ( adns_synchronous (adns_ctx, name, (adns_r_unknown | my_adns_r_cert),
-                         adns_qf_quoteok_query,
+                         adns_qf_quoteok_query|(kdns_usevc?adns_qf_usevc:0),
                          &answer) )
     {
       fprintf (console, PGM": DNS query failed: %s\n", strerror (errno));
       ret = KEYSERVER_KEY_NOT_FOUND;
       goto leave;
     }
-  if (answer->status != adns_s_ok) 
+  if (answer->status != adns_s_ok)
     {
-      fprintf (console, PGM": DNS query returned: %s (%s)\n", 
+      fprintf (console, PGM": DNS query returned: %s (%s)\n",
                adns_strerror (answer->status),
                adns_errabbrev (answer->status));
       ret = KEYSERVER_KEY_NOT_FOUND;
@@ -138,7 +141,7 @@ get_key (adns_state adns_ctx, char *address)
     }
   if ( datalen < 5 )
     {
-      fprintf (console, PGM": error: truncated CERT record\n"); 
+      fprintf (console, PGM": error: truncated CERT record\n");
       ret = KEYSERVER_KEY_NOT_FOUND;
       goto leave;
     }
@@ -152,7 +155,7 @@ get_key (adns_state adns_ctx, char *address)
       if ( datalen < 11 )
         {
           /* Gpg checks for a minium length of 11, thus we do the same.  */
-          fprintf (console, PGM": error: OpenPGP data to short\n"); 
+          fprintf (console, PGM": error: OpenPGP data to short\n");
           ret = KEYSERVER_KEY_NOT_FOUND;
           goto leave;
         }
@@ -163,11 +166,11 @@ get_key (adns_state adns_ctx, char *address)
       break;
 
     default:
-      fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1])); 
+      fprintf (console, PGM": CERT type %d ignored\n", (data[0] <<8|data[1]));
       ret = KEYSERVER_KEY_NOT_FOUND;
       goto leave;
     }
-  
+
   ret = 0; /* All fine.  */
 
  leave:
@@ -175,30 +178,31 @@ get_key (adns_state adns_ctx, char *address)
     fprintf (output, "\nNAME %s FAILED %d\n", address, ret);
   else
     fprintf (output, "\nNAME %s END\n", address);
-  free (answer);  /* (Right, this is free and not xfree.) */
+  adns_free (answer);
   xfree (name);
   return ret;
 }
 
 
 /* Print some help.  */
-static void 
+static void
 show_help (FILE *fp)
 {
-  fputs (PGM" (GnuPG) " VERSION"\n\n", fp);
+  fputs (PGM" ("GNUPG_NAME") " VERSION"\n\n", fp);
   fputs (" -h\thelp\n"
          " -V\tversion\n"
          " -o\toutput to this file\n"
          "\n", fp);
   fputs ("This keyserver helper accepts URLs of the form:\n"
-         "  kdns://[NAMESERVER]/[ROOT][?at=[STRING]]\n"
+         "  kdns://[NAMESERVER]/[ROOT][?at=STRING]\n"
          "with\n"
          "  NAMESERVER  used for queries (default: system standard)\n"
          "  ROOT        a DNS name appended to the query (default: none)\n"
-         "  STRING      A string to replace the '@' (default: \".\")\n"
+         "  STRING      a string to replace the '@' (default: \".\")\n"
+         "If a long answer is expected add the parameter \"usevc=1\".\n"
          "\n", fp);
   fputs ("Example:  A query for \"hacker@gnupg.org\" with\n"
-         "  kdns://10.0.0.1/example.net?at=_key?\n"
+         "  kdns://10.0.0.1/example.net?at=_key&usevc=1\n"
          "setup as --auto-key-lookup does a CERT record query\n"
          "with type PGP on the nameserver 10.0.0.1 for\n"
          "  hacker._key_.gnupg.org.example.net\n"
@@ -229,7 +233,7 @@ main (int argc, char *argv[])
   /* Kludge to implement standard GNU options.  */
   if (argc > 1 && !strcmp (argv[1], "--version"))
     {
-      fputs (PGM" (GnuPG) " VERSION"\n", stdout);
+      fputs (PGM" ("GNUPG_NAME") " VERSION"\n", stdout);
       return 0;
     }
   else if (argc > 1 && !strcmp (argv[1], "--help"))
@@ -250,7 +254,7 @@ main (int argc, char *argv[])
           output = fopen (optarg,"w");
           if (!output)
             {
-              fprintf (console, PGM": cannot open output file `%s': %s\n",
+              fprintf (console, PGM": cannot open output file '%s': %s\n",
                        optarg, strerror(errno) );
               return KEYSERVER_INTERNAL_ERROR;
             }
@@ -268,7 +272,7 @@ main (int argc, char *argv[])
       input = fopen (argv[optind], "r");
       if (!input)
        {
-         fprintf (console, PGM": cannot open input file `%s': %s\n",
+         fprintf (console, PGM": cannot open input file '%s': %s\n",
                    argv[optind], strerror(errno) );
          return KEYSERVER_INTERNAL_ERROR;
        }
@@ -279,7 +283,7 @@ main (int argc, char *argv[])
 
   if (!output)
     output = stdout;
-  
+
   opt = init_ks_options();
   if(!opt)
     return KEYSERVER_NO_MEMORY;
@@ -288,10 +292,10 @@ main (int argc, char *argv[])
   while ( fgets(line,MAX_LINE,input) )
     {
       int err;
-      
+
       if(line[0]=='\n')
        break;
-      
+
       err = parse_ks_options (line, opt);
       if (err > 0)
        {
@@ -308,8 +312,11 @@ main (int argc, char *argv[])
       return KEYSERVER_INTERNAL_ERROR;
     }
 
-  fprintf (console, PGM": HOST=%s\n", opt->host? opt->host:"(none)");
-  fprintf (console, PGM": PATH=%s\n", opt->path? opt->path:"(none)");
+  if (opt->verbose)
+    {
+      fprintf (console, PGM": HOST=%s\n", opt->host? opt->host:"(none)");
+      fprintf (console, PGM": PATH=%s\n", opt->path? opt->path:"(none)");
+    }
   if (opt->path && *opt->path == '/')
     {
       char *p, *pend;
@@ -319,17 +326,15 @@ main (int argc, char *argv[])
       if (p)
         {
           *p++ = 0;
-          do 
+          do
             {
               pend = strchr (p, '&');
               if (pend)
                 *pend++ = 0;
               if (!strncmp (p, "at=", 3))
-                {
-                  /* Found.  */
-                  kdns_at_repl = p+3;
-                  break;
-                }
+                kdns_at_repl = p+3;
+              else if (!strncmp (p, "usevc=", 6))
+                kdns_usevc = !!atoi (p+6);
             }
           while ((p = pend));
         }
@@ -341,9 +346,13 @@ main (int argc, char *argv[])
     }
   if (!strcmp (kdns_at_repl, "."))
     kdns_at_repl = "";
-  fprintf (console, PGM": kdns_root=%s\n", kdns_root);
-  fprintf (console, PGM": kdns_at=%s\n", kdns_at_repl);
 
+  if (opt->verbose)
+    {
+      fprintf (console, PGM": kdns_root=%s\n", kdns_root);
+      fprintf (console, PGM": kdns_at=%s\n", kdns_at_repl);
+      fprintf (console, PGM": kdns_usevc=%d\n", kdns_usevc);
+    }
 
   if (opt->debug)
     my_adns_initflags |= adns_if_debug;
@@ -362,7 +371,7 @@ main (int argc, char *argv[])
                strerror (errno));
       goto leave;
     }
-  
+
   if (opt->action == KS_GETNAME)
     {
       while ( fgets (line,MAX_LINE,input) )
@@ -370,11 +379,11 @@ main (int argc, char *argv[])
           if (line[0]=='\n' || !line[0] )
             break;
           line[strlen(line)-1] = 0;  /* Trim the trailing LF. */
-          
+
           akey = xtrymalloc (sizeof *akey);
           if (!akey)
             {
-              fprintf (console, 
+              fprintf (console,
                        PGM": out of memory while building key list\n");
               ret = KEYSERVER_NO_MEMORY;
               goto leave;
@@ -393,7 +402,7 @@ main (int argc, char *argv[])
                "key retrieval by name\n");
       goto leave;
     }
-  
+
   /* Send the response */
   fprintf (output, "VERSION %d\n", KEYSERVER_PROTO_VERSION);
   fprintf (output, "PROGRAM %s\n\n", VERSION);
@@ -404,13 +413,13 @@ main (int argc, char *argv[])
         fprintf (console, "User:\t\t%s\n", opt->opaque);
       fprintf (console, "Command:\tGET\n");
     }
-  
+
   for (akey = keylist; akey; akey = akey->next)
     {
       set_timeout (opt->timeout);
       if ( get_key (adns_ctx, akey->str) )
         failed++;
-    }      
+    }
   if (!failed)
     ret = KEYSERVER_OK;