Ejemplo n.º 1
0
Pin::Pin() {
  gpg_error_t res;
  pid_t pid;
  int flags;
  const char *argv[2];

  gpg_err_init();
  res = assuan_new (&ctx);
  if(res)
    throw runtime_error(strprintf("pinentry initialisation: %s", gpg_strerror(res)));

  assuan_set_assuan_log_prefix("Pin: ");

  // needed esp. for ncurses
  lang = strprintf("OPTION lc-ctype=%s",getenv("LANG"));
  tty = strprintf("OPTION ttyname=%s",getenv("TTY"));

  flags = 0x0;
  argv[0] = "bitcoind"; // fake argv
  argv[1] = NULL;
  res = assuan_pipe_connect (ctx, SECURE_EXEC_PATH"/pinentry",
			     argv, NULL, NULL, NULL, flags);
  if(res)
    throw runtime_error(strprintf("pinentry pipe forking: %s", gpg_strerror(res)));

  pid = assuan_get_pid(ctx);
  if(pid == ASSUAN_INVALID_PID)
    throw runtime_error(strprintf("pinentry not running: %s", gpg_strerror(res)));

  cmd(tty.c_str());
  cmd(lang.c_str());
}
Ejemplo n.º 2
0
/* This function may be called to print infromation pertaining to the
   current state of this module to the log. */
void
agent_query_dump_state (void)
{
  log_info ("agent_query_dump_state: entry_lock=");
  dump_mutex_state (&entry_lock);
  log_printf ("\n");
  log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n",
            entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid);
}
Ejemplo n.º 3
0
/* Close a popup window. */
void
agent_popup_message_stop (ctrl_t ctrl)
{
  int rc;
  pid_t pid;

  (void)ctrl;

  if (!popup_tid || !entry_ctx)
    {
      log_debug ("agent_popup_message_stop called with no active popup\n");
      return;
    }

  pid = assuan_get_pid (entry_ctx);
  if (pid == (pid_t)(-1))
    ; /* No pid available can't send a kill. */
  else if (popup_finished)
    ; /* Already finished and ready for joining. */
#ifdef HAVE_W32_SYSTEM
  /* Older versions of assuan set PID to 0 on Windows to indicate an
     invalid value.  */
  else if (pid != (pid_t) INVALID_HANDLE_VALUE
	   && pid != 0)
    {
      HANDLE process = (HANDLE) pid;

      /* Arbitrary error code.  */
      TerminateProcess (process, 1);
    }
#else
  else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
    { /* The daemon already died.  No need to send a kill.  However
         because we already waited for the process, we need to tell
         assuan that it should not wait again (done by
         unlock_pinentry). */
      if (rc == pid)
        assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1);
    }
  else if (pid > 0)
    kill (pid, SIGINT);
#endif

  /* Now wait for the thread to terminate. */
  rc = npth_join (popup_tid, NULL);
  if (rc)
    log_debug ("agent_popup_message_stop: pth_join failed: %s\n",
               strerror (rc));
  /* Thread IDs are opaque, but we try our best here by resetting it
     to the same content that a static global variable has.  */
  memset (&popup_tid, '\0', sizeof (popup_tid));
  entry_owner = NULL;

  /* Now we can close the connection. */
  unlock_pinentry (0);
}
Ejemplo n.º 4
0
/* This function may be called to print infromation pertaining to the
   current state of this module to the log. */
void
agent_scd_dump_state (void)
{
  log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
            primary_scd_ctx,
            (long)assuan_get_pid (primary_scd_ctx),
            primary_scd_ctx_reusable);
  if (socket_name)
    log_info ("agent_scd_dump_state: socket='%s'\n", socket_name);
}
Ejemplo n.º 5
0
/* Client main.  If true is returned, a disconnect has not been done. */
static int
client (assuan_context_t ctx, const char *fname)
{
  int rc;
  FILE *fp;
  int i;

  log_info ("client started. Servers's pid is %ld\n",
            (long)assuan_get_pid (ctx));

  for (i=0; i < 6; i++)
    {
      fp = fopen (fname, "r");
      if (!fp)
        {
          log_error ("failed to open `%s': %s\n", fname,
                     strerror (errno));
          return -1;
        }
      
      rc = assuan_sendfd (ctx, fileno (fp));
      if (rc)
        {
          log_error ("assuan_sendfd failed: %s\n", gpg_strerror (rc));
          return -1;
        }
      fclose (fp);

      rc = assuan_transact (ctx, "INPUT FD", NULL, NULL, NULL, NULL,
                            NULL, NULL);
      if (rc)
        {
          log_error ("sending INPUT FD failed: %s\n", gpg_strerror (rc));
          return -1;
        }

      rc = assuan_transact (ctx, "ECHO", NULL, NULL, NULL, NULL, NULL, NULL);
      if (rc)
        {
          log_error ("sending ECHO failed: %s\n", gpg_strerror (rc));
          return -1;
        }
    }

  /* Give us some time to check with lsof that all descriptors are closed. */
/*   sleep (10); */

  assuan_release (ctx);
  return 0;
}
Ejemplo n.º 6
0
static void
server (void)
{
  int rc;
  assuan_context_t ctx;

  log_info ("server started\n");

  rc = assuan_new (&ctx);
  if (rc)
    log_fatal ("assuan_new failed: %s\n", gpg_strerror (rc));

  rc = assuan_init_pipe_server (ctx, NULL);
  if (rc)
    log_fatal ("assuan_init_pipe_server failed: %s\n", gpg_strerror (rc));

  rc = register_commands (ctx);
  if (rc)
    log_fatal ("register_commands failed: %s\n", gpg_strerror(rc));

  assuan_set_log_stream (ctx, stderr);

  for (;;) 
    {
      rc = assuan_accept (ctx);
      if (rc)
        {
          if (rc != -1)
            log_error ("assuan_accept failed: %s\n", gpg_strerror (rc));
          break;
        }
      
      log_info ("client connected.  Client's pid is %ld\n",
                (long)assuan_get_pid (ctx));

      rc = assuan_process (ctx);
      if (rc)
        log_error ("assuan_process failed: %s\n", gpg_strerror (rc));
    }
  
  assuan_release (ctx);
}
Ejemplo n.º 7
0
/* This function may be called to print infromation pertaining to the
   current state of this module to the log. */
void
agent_query_dump_state (void)
{
  log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%lx\n",
            entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid);
}
Ejemplo n.º 8
0
/* Check whether the Scdaemon is still alive and clean it up if not. */
void
agent_scd_check_aliveness (void)
{
  pid_t pid;
#ifdef HAVE_W32_SYSTEM
  DWORD rc;
#else
  int rc;
#endif
  struct timespec abstime;
  int err;

  if (!primary_scd_ctx)
    return; /* No scdaemon running. */

  /* This is not a critical function so we use a short timeout while
     acquiring the lock.  */
  npth_clock_gettime (&abstime);
  abstime.tv_sec += 1;
  err = npth_mutex_timedlock (&start_scd_lock, &abstime);
  if (err)
    {
      if (err == ETIMEDOUT)
        {
          if (opt.verbose > 1)
            log_info ("failed to acquire the start_scd lock while"
                      " doing an aliveness check: %s\n", strerror (err));
        }
      else
        log_error ("failed to acquire the start_scd lock while"
                   " doing an aliveness check: %s\n", strerror (err));
      return;
    }

  if (primary_scd_ctx)
    {
      pid = assuan_get_pid (primary_scd_ctx);
#ifdef HAVE_W32_SYSTEM
      /* If we have a PID we disconnect if either GetExitProcessCode
         fails or if ir returns the exit code of the scdaemon.  259 is
         the error code for STILL_ALIVE.  */
      if (pid != (pid_t)(void*)(-1) && pid
          && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259))
#else
      if (pid != (pid_t)(-1) && pid
          && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
#endif
        {
          /* Okay, scdaemon died.  Disconnect the primary connection
             now but take care that it won't do another wait. Also
             cleanup all other connections and release their
             resources.  The next use will start a new daemon then.
             Due to the use of the START_SCD_LOCAL we are sure that
             none of these context are actually in use. */
          struct scd_local_s *sl;

          assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
          assuan_release (primary_scd_ctx);

          for (sl=scd_local_list; sl; sl = sl->next_local)
            {
              if (sl->ctx)
                {
                  if (sl->ctx != primary_scd_ctx)
                    assuan_release (sl->ctx);
                  sl->ctx = NULL;
                }
            }

          primary_scd_ctx = NULL;
          primary_scd_ctx_reusable = 0;

          xfree (socket_name);
          socket_name = NULL;
        }
    }

  err = npth_mutex_unlock (&start_scd_lock);
  if (err)
    log_error ("failed to release the start_scd lock while"
               " doing the aliveness check: %s\n", strerror (err));
}