sm: Fix certificate creation with key on card.
[gnupg.git] / dirmngr / dirmngr.c
index 5317c21..5b9e7a8 100644 (file)
@@ -17,6 +17,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0+
  */
 
 #include <config.h>
  */
 
 #include <config.h>
@@ -149,6 +151,7 @@ enum cmd_and_opt_values {
   oResolverTimeout,
   oConnectTimeout,
   oConnectQuickTimeout,
   oResolverTimeout,
   oConnectTimeout,
   oConnectQuickTimeout,
+  oListenBacklog,
   aTest
 };
 
   aTest
 };
 
@@ -254,6 +257,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"),
   ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"),
   ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"),
   ARGPARSE_s_i (oResolverTimeout, "resolver-timeout", "@"),
   ARGPARSE_s_i (oConnectTimeout, "connect-timeout", "@"),
   ARGPARSE_s_i (oConnectQuickTimeout, "connect-quick-timeout", "@"),
+  ARGPARSE_s_i (oListenBacklog, "listen-backlog", "@"),
 
   ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
                          "of all commands and options)\n")),
 
   ARGPARSE_group (302,N_("@\n(See the \"info\" manual for a complete listing "
                          "of all commands and options)\n")),
@@ -294,6 +298,10 @@ static const char *redir_socket_name;
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
 
    POSIX systems). */
 static assuan_sock_nonce_t socket_nonce;
 
+/* Value for the listen() backlog argument.
+ * Change at runtime with --listen-backlog.  */
+static int listen_backlog = 64;
+
 /* Only if this flag has been set will we remove the socket file.  */
 static int cleanup_socket;
 
 /* Only if this flag has been set will we remove the socket file.  */
 static int cleanup_socket;
 
@@ -330,7 +338,7 @@ static int active_connections;
  * thread to run background network tasks.  */
 static int network_activity_seen;
 
  * thread to run background network tasks.  */
 static int network_activity_seen;
 
-/* A list of filenames registred with --hkp-cacert.  */
+/* A list of filenames registered with --hkp-cacert.  */
 static strlist_t hkp_cacert_filenames;
 
 
 static strlist_t hkp_cacert_filenames;
 
 
@@ -403,7 +411,7 @@ my_strusage( int level )
 
 /* Callback from libksba to hash a provided buffer.  Our current
    implementation does only allow SHA-1 for hashing. This may be
 
 /* Callback from libksba to hash a provided buffer.  Our current
    implementation does only allow SHA-1 for hashing. This may be
-   extended by mapping the name, testing for algorithm availibility
+   extended by mapping the name, testing for algorithm availability
    and adjust the length checks accordingly. */
 static gpg_error_t
 my_ksba_hash_buffer (void *arg, const char *oid,
    and adjust the length checks accordingly. */
 static gpg_error_t
 my_ksba_hash_buffer (void *arg, const char *oid,
@@ -512,7 +520,7 @@ set_tor_mode (void)
 {
   if (dirmngr_use_tor ())
     {
 {
   if (dirmngr_use_tor ())
     {
-      /* Enable Tor mode and when called again force a new curcuit
+      /* Enable Tor mode and when called again force a new circuit
        * (e.g. on SIGHUP).  */
       enable_dns_tormode (1);
       if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
        * (e.g. on SIGHUP).  */
       enable_dns_tormode (1);
       if (assuan_sock_set_flag (ASSUAN_INVALID_FD, "tor-mode", 1))
@@ -744,7 +752,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
 }
 
 
 }
 
 
-/* This fucntion is called after option parsing to adjust some values
+/* This function is called after option parsing to adjust some values
  * and call option setup functions.  */
 static void
 post_option_parsing (void)
  * and call option setup functions.  */
 static void
 post_option_parsing (void)
@@ -779,12 +787,12 @@ my_ntbtls_log_handler (void *opaque, int level, const char *fmt, va_list argv)
   (void)opaque;
 
   if (level == -1)
   (void)opaque;
 
   if (level == -1)
-    log_logv_with_prefix (GPGRT_LOG_INFO, "ntbtls: ", fmt, argv);
+    log_logv_prefix (GPGRT_LOGLVL_INFO, "ntbtls: ", fmt, argv);
   else
     {
       char prefix[10+20];
       snprintf (prefix, sizeof prefix, "ntbtls(%d): ", level);
   else
     {
       char prefix[10+20];
       snprintf (prefix, sizeof prefix, "ntbtls(%d): ", level);
-      log_logv_with_prefix (GPGRT_LOG_DEBUG, prefix, fmt, argv);
+      log_logv_prefix (GPGRT_LOGLVL_DEBUG, prefix, fmt, argv);
     }
 }
 #endif
     }
 }
 #endif
@@ -794,6 +802,7 @@ static void
 thread_init (void)
 {
   npth_init ();
 thread_init (void)
 {
   npth_init ();
+  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
 
   /* Now with NPth running we can set the logging callback.  Our
   gpgrt_set_syscall_clamp (npth_unprotect, npth_protect);
 
   /* Now with NPth running we can set the logging callback.  Our
@@ -869,7 +878,6 @@ main (int argc, char **argv)
   assuan_set_malloc_hooks (&malloc_hooks);
   assuan_set_assuan_log_prefix (log_get_prefix (NULL));
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
   assuan_set_malloc_hooks (&malloc_hooks);
   assuan_set_assuan_log_prefix (log_get_prefix (NULL));
   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-  assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
   assuan_sock_init ();
   setup_libassuan_logging (&opt.debug, dirmngr_assuan_log_monitor);
 
   assuan_sock_init ();
   setup_libassuan_logging (&opt.debug, dirmngr_assuan_log_monitor);
 
@@ -1017,6 +1025,10 @@ main (int argc, char **argv)
 
         case oSocketName: socket_name = pargs.r.ret_str; break;
 
 
         case oSocketName: socket_name = pargs.r.ret_str; break;
 
+        case oListenBacklog:
+          listen_backlog = pargs.r.ret_int;
+          break;
+
         default : pargs.err = configfp? 1:2; break;
        }
     }
         default : pargs.err = configfp? 1:2; break;
        }
     }
@@ -1131,8 +1143,9 @@ main (int argc, char **argv)
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
+      ks_hkp_init ();
       http_register_netactivity_cb (netactivity_action);
       http_register_netactivity_cb (netactivity_action);
-      start_command_handler (ASSUAN_INVALID_FD);
+      start_command_handler (ASSUAN_INVALID_FD, 0);
       shutdown_reaper ();
     }
 #ifndef HAVE_W32_SYSTEM
       shutdown_reaper ();
     }
 #ifndef HAVE_W32_SYSTEM
@@ -1166,6 +1179,7 @@ main (int argc, char **argv)
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
+      ks_hkp_init ();
       http_register_netactivity_cb (netactivity_action);
       handle_connections (3);
       shutdown_reaper ();
       http_register_netactivity_cb (netactivity_action);
       handle_connections (3);
       shutdown_reaper ();
@@ -1191,6 +1205,14 @@ main (int argc, char **argv)
           current_logfile = xstrdup (logfile);
         }
 
           current_logfile = xstrdup (logfile);
         }
 
+      if (debug_wait)
+        {
+          log_debug ("waiting for debugger - my pid is %u .....\n",
+                     (unsigned int)getpid());
+          gnupg_sleep (debug_wait);
+          log_debug ("... okay\n");
+        }
+
 #ifndef HAVE_W32_SYSTEM
       if (strchr (socket_name, ':'))
         {
 #ifndef HAVE_W32_SYSTEM
       if (strchr (socket_name, ':'))
         {
@@ -1261,9 +1283,10 @@ main (int argc, char **argv)
         log_error (_("can't set permissions of '%s': %s\n"),
                    serv_addr.sun_path, strerror (errno));
 
         log_error (_("can't set permissions of '%s': %s\n"),
                    serv_addr.sun_path, strerror (errno));
 
-      if (listen (FD2INT (fd), 5) == -1)
+      if (listen (FD2INT (fd), listen_backlog) == -1)
         {
         {
-          log_error (_("listen() failed: %s\n"), strerror (errno));
+          log_error ("listen(fd,%d) failed: %s\n",
+                     listen_backlog, strerror (errno));
           assuan_sock_close (fd);
           dirmngr_exit (1);
         }
           assuan_sock_close (fd);
           dirmngr_exit (1);
         }
@@ -1378,6 +1401,7 @@ main (int argc, char **argv)
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
+      ks_hkp_init ();
       http_register_netactivity_cb (netactivity_action);
       handle_connections (fd);
       shutdown_reaper ();
       http_register_netactivity_cb (netactivity_action);
       handle_connections (fd);
       shutdown_reaper ();
@@ -1400,6 +1424,7 @@ main (int argc, char **argv)
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
+      ks_hkp_init ();
       if (!argc)
         rc = crl_cache_load (&ctrlbuf, NULL);
       else
       if (!argc)
         rc = crl_cache_load (&ctrlbuf, NULL);
       else
@@ -1423,6 +1448,7 @@ main (int argc, char **argv)
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
       thread_init ();
       cert_cache_init (hkp_cacert_filenames);
       crl_cache_init ();
+      ks_hkp_init ();
       rc = crl_fetch (&ctrlbuf, argv[0], &reader);
       if (rc)
         log_error (_("fetching CRL from '%s' failed: %s\n"),
       rc = crl_fetch (&ctrlbuf, argv[0], &reader);
       if (rc)
         log_error (_("fetching CRL from '%s' failed: %s\n"),
@@ -1871,6 +1897,7 @@ handle_signal (int signo)
 
     case SIGUSR1:
       cert_cache_print_stats ();
 
     case SIGUSR1:
       cert_cache_print_stats ();
+      domaininfo_print_stats ();
       break;
 
     case SIGUSR2:
       break;
 
     case SIGUSR2:
@@ -1936,7 +1963,10 @@ housekeeping_thread (void *arg)
       network_activity_seen = 0;
       if (opt.allow_version_check)
         dirmngr_load_swdb (&ctrlbuf, 0);
       network_activity_seen = 0;
       if (opt.allow_version_check)
         dirmngr_load_swdb (&ctrlbuf, 0);
+      workqueue_run_global_tasks (&ctrlbuf, 1);
     }
     }
+  else
+    workqueue_run_global_tasks (&ctrlbuf, 0);
 
   dirmngr_deinit_default_ctrl (&ctrlbuf);
 
 
   dirmngr_deinit_default_ctrl (&ctrlbuf);
 
@@ -2031,6 +2061,8 @@ check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
 static void *
 start_connection_thread (void *arg)
 {
 static void *
 start_connection_thread (void *arg)
 {
+  static unsigned int last_session_id;
+  unsigned int session_id;
   union int_and_ptr_u argval;
   gnupg_fd_t fd;
 
   union int_and_ptr_u argval;
   gnupg_fd_t fd;
 
@@ -2052,12 +2084,17 @@ start_connection_thread (void *arg)
   if (opt.verbose)
     log_info (_("handler for fd %d started\n"), FD2INT (fd));
 
   if (opt.verbose)
     log_info (_("handler for fd %d started\n"), FD2INT (fd));
 
-  start_command_handler (fd);
+  session_id = ++last_session_id;
+  if (!session_id)
+    session_id = ++last_session_id;
+  start_command_handler (fd, session_id);
 
   if (opt.verbose)
     log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
   active_connections--;
 
 
   if (opt.verbose)
     log_info (_("handler for fd %d terminated\n"), FD2INT (fd));
   active_connections--;
 
+  workqueue_run_post_session_tasks (session_id);
+
 #ifndef HAVE_W32_SYSTEM
   argval.afd = ASSUAN_INVALID_FD;
   npth_setspecific (my_tlskey_current_fd, argval.aptr);
 #ifndef HAVE_W32_SYSTEM
   argval.afd = ASSUAN_INVALID_FD;
   npth_setspecific (my_tlskey_current_fd, argval.aptr);
@@ -2211,7 +2248,8 @@ handle_connections (assuan_fd_t listen_fd)
       npth_timersub (&abstime, &curtime, &timeout);
 
 #ifndef HAVE_W32_SYSTEM
       npth_timersub (&abstime, &curtime, &timeout);
 
 #ifndef HAVE_W32_SYSTEM
-      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
+      ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout,
+                          npth_sigev_sigmask());
       saved_errno = errno;
 
       while (npth_sigev_get_pending(&signo))
       saved_errno = errno;
 
       while (npth_sigev_get_pending(&signo))