Ejemplo n.º 1
0
Archivo: cm-unknown.c Proyecto: gpg/gpa
/* Use the assuan machinery to read the ATR.  */
static void
reload_data (GpaCMUnknown *card)
{
  gpg_error_t err, operr;
  char command[100];
  gpgme_ctx_t gpgagent;
  membuf_t mb;
  char *buf;

  gpgagent = GPA_CM_OBJECT (card)->agent_ctx;
  g_return_if_fail (gpgagent);

  card->reloading++;

  init_membuf (&mb, 512);

  err = gpgme_op_assuan_transact_ext (gpgagent,
                                      "SCD APDU --dump-atr",
                                      scd_atr_data_cb, &mb,
                                      NULL, NULL, NULL, NULL, &operr);
  if (!err)
    err = operr;

  if (!err)
    {
      put_membuf (&mb, "", 1);
      buf = get_membuf (&mb, NULL);
      if (buf)
        {
          buf = g_strdup_printf ("\n%s\n%s",
                                 _("The ATR of the card is:"),
                                 buf);
          gtk_label_set_text (GTK_LABEL (card->label), buf);
          g_free (buf);
        }
      else
        gtk_label_set_text (GTK_LABEL (card->label), "");
    }
  else
    {
      g_free (get_membuf (&mb, NULL));

      if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
        ; /* Lost the card.  */
      else
        g_debug ("assuan command `%s' failed: %s <%s>\n",
                 command, gpg_strerror (err), gpg_strsource (err));
      gtk_label_set_text (GTK_LABEL (card->label), "");
    }
  card->reloading--;
}
Ejemplo n.º 2
0
Archivo: cm-dinsig.c Proyecto: gpg/gpa
/* Use the assuan machinery to load the bulk of the OpenPGP card data.  */
static void
reload_data (GpaCMDinsig *card)
{
  static struct {
    const char *name;
    int entry_id;
    void (*updfnc) (GpaCMDinsig *card, int entry_id, char *string);
  } attrtbl[] = {
    { "SERIALNO",    ENTRY_SERIALNO },
    { NULL }
  };
  int attridx;
  gpg_error_t err, operr;
  char command[100];
  struct scd_getattr_parm parm;
  gpgme_ctx_t gpgagent;

  gpgagent = GPA_CM_OBJECT (card)->agent_ctx;
  g_return_if_fail (gpgagent);

  card->reloading++;
  parm.card = card;
  for (attridx=0; attrtbl[attridx].name; attridx++)
    {
      parm.name     = attrtbl[attridx].name;
      parm.entry_id = attrtbl[attridx].entry_id;
      parm.updfnc   = attrtbl[attridx].updfnc;
      snprintf (command, sizeof command, "SCD GETATTR %s", parm.name);
      err = gpgme_op_assuan_transact_ext (gpgagent,
                                          command,
                                          NULL, NULL,
                                          NULL, NULL,
                                          scd_getattr_cb, &parm, &operr);
      if (!err)
        err = operr;

      if (err)
        {
          if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
            ; /* Lost the card.  */
          else
            {
              g_debug ("assuan command `%s' failed: %s <%s>\n",
                       command, gpg_strerror (err), gpg_strsource (err));
            }
          clear_card_data (card);
          break;
        }
    }
  card->reloading--;
}
Ejemplo n.º 3
0
Archivo: cardman.c Proyecto: gpg/gpa
/* Fill the app_selection box with the available applications.  */
static void
setup_app_selector (GpaCardManager *cardman)
{
  gpg_error_t err, operr;
  membuf_t mb;
  char *string;
  char *p, *p0, *p1;

  if (!cardman->gpgagent || !cardman->app_selector)
    return;

  init_membuf (&mb, 256);

  err = gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                      "SCD GETINFO app_list",
                                      setup_app_selector_data_cb, &mb,
                                      NULL, NULL, NULL, NULL, &operr);
  if (err || operr)
    {
      g_free (get_membuf (&mb, NULL));
      return;
    }
  /* Make sure the data is a string and get it. */
  put_membuf (&mb, "", 1);
  string = get_membuf (&mb, NULL);
  if (!string)
    return; /* Out of core.  */

  for (p=p0=string; *p; p++)
    {
      if (*p == '\n')
        {
          *p = 0;
          p1 = strchr (p0, ':');
          if (p1)
            *p1 = 0;
          gtk_combo_box_append_text
            (GTK_COMBO_BOX (cardman->app_selector), p0);
          if (p[1])
            p0 = p+1;
        }
    }

  g_free (string);
}
Ejemplo n.º 4
0
Archivo: cardman.c Proyecto: gpg/gpa
/* This function is called by the timeout ticker started by
   start_ticker.  It is used to poll scdaemon to detect a card status
   change.  */
static gboolean
ticker_cb (gpointer user_data)
{
  GpaCardManager *cardman = user_data;

  if (!cardman || !cardman->ticker_timeout_id || !cardman->gpgagent
      || cardman->in_card_reload)
    return TRUE;  /* Keep on ticking.  */

  /* Note that we are single threaded and thus there is no need to
     lock the assuan context.  */

  gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                "GETEVENTCOUNTER",
                                NULL, NULL,
                                NULL, NULL,
                                geteventcounter_status_cb, cardman, NULL);

  return TRUE;  /* Keep on ticking.  */
}
Ejemplo n.º 5
0
Archivo: cardman.c Proyecto: gpg/gpa
/* This function is called to triggers a key-generation.  */
static void
card_genkey (GpaCardManager *cardman)
{
  gpg_error_t err, operr;
  GpaGenKeyCardOperation *op;
  char *keyattr;

  if (cardman->cardtype != GPA_CM_OPENPGP_TYPE)
    return;  /* Not possible.  */
  if (!cardman->gpgagent)
    {
      g_debug ("Ooops: no assuan context");
      return;
    }

  /* Note: This test works only with GnuPG > 2.0.10 but that version
     is anyway required for the card manager to work correctly.  */
  err = gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                      "SCD GETINFO deny_admin",
                                      NULL, NULL, NULL, NULL, NULL, NULL,
                                      &operr);
  if (!err)
    err = operr;

  if (!err)
    {
      gpa_window_error ("Admin commands are disabled in scdamon.\n"
                        "Key generation is not possible.", NULL);
      return;
    }

  keyattr = (cardman->card_widget
             ? gpa_cm_openpgp_get_key_attributes (cardman->card_widget)
             : NULL);

  op = gpa_gen_key_card_operation_new (GTK_WIDGET (cardman), keyattr);
  g_signal_connect_swapped (G_OBJECT (op), "completed",
                            G_CALLBACK (card_genkey_completed), cardman);
  g_signal_connect (G_OBJECT (op), "completed",
		    G_CALLBACK (g_object_unref), NULL);
}
Ejemplo n.º 6
0
int 
main (int argc, char **argv)
{
  gpgme_error_t err;
  gpgme_error_t op_err;
  gpgme_ctx_t ctx;
  const char *command;

  gpgme_check_version (NULL);
#ifndef HAVE_W32_SYSTEM
  setlocale (LC_ALL, "");
  gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
  gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
#endif

  if (argc)
    {
      argc--;
      argv++;
    }
  command = argc? *argv : "NOP";
  

  err = gpgme_new (&ctx);
  fail_if_err (err);

  err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_ASSUAN);
  fail_if_err (err);

  err = gpgme_op_assuan_transact_ext (ctx, command, data_cb, NULL,
                                  inq_cb, NULL, status_cb, NULL, &op_err);
  fail_if_err (err || op_err);

  gpgme_release (ctx);

  return 0;
}
Ejemplo n.º 7
0
gpgme_error_t
gpgme_op_assuan_transact (gpgme_ctx_t ctx,
			  const char *command,
			  gpgme_assuan_data_cb_t data_cb,
			  void *data_cb_value,
			  gpgme_assuan_inquire_cb_t inq_cb,
			  void *inq_cb_value,
			  gpgme_assuan_status_cb_t status_cb,
			  void *status_cb_value)
{
  gpgme_error_t err;

  TRACE (DEBUG_CTX, "gpgme_op_assuan_transact", ctx);

  if (!ctx)
    return gpg_error (GPG_ERR_INV_VALUE);

  /* Users of the old-style session based interfaces need to look at
     the result structure.  */
  err = gpgme_op_assuan_transact_ext (ctx, command, data_cb, data_cb_value,
				      inq_cb, inq_cb_value,
				      status_cb, status_cb_value, NULL);
  return err;
}
Ejemplo n.º 8
0
Archivo: cardman.c Proyecto: gpg/gpa
/* This function is called to trigger a card-reload.  */
static void
card_reload (GpaCardManager *cardman)
{
  gpg_error_t err, operr;
  const char *application;
  char *command_buf = NULL;
  const char *command;
  const char *err_desc = NULL;
  char *err_desc_buffer = NULL;
  int auto_app;

  if (!cardman->gpgagent)
    return;  /* No support for GPGME_PROTOCOL_ASSUAN.  */

  /* Start the ticker if not yet done.  */
  start_ticker (cardman);
  if (!cardman->in_card_reload)
    {
      cardman->in_card_reload++;

      update_info_visibility (cardman);

      cardman->cardtype = G_TYPE_NONE;
      cardman->cardtypename = "Unknown";

      /* The first thing we need to do is to issue the SERIALNO
         command; this makes sure that scdaemon initalizes the card if
         that has not yet been done.  */
      command = "SCD SERIALNO";
      if (cardman->app_selector
          && (gtk_combo_box_get_active
              (GTK_COMBO_BOX (cardman->app_selector)) > 0)
          && (application = gtk_combo_box_get_active_text
              (GTK_COMBO_BOX (cardman->app_selector))))
        {
          command_buf = g_strdup_printf ("%s %s", command, application);
          command = command_buf;
          auto_app = 0;
        }
      else
        auto_app = 1;
      err = gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                          command,
                                          scd_data_cb, NULL,
                                          scd_inq_cb, NULL,
                                          scd_status_cb, cardman, &operr);
      if (!err)
        {
          err = operr;
          if (!auto_app
              && gpg_err_source (err) == GPG_ERR_SOURCE_SCD
              && gpg_err_code (err) == GPG_ERR_CONFLICT)
            {
              /* Not in auto select mode and the scdaemon told us
                 about a conflicting use.  We now do a restart and try
                 again to display an application selection conflict
                 error only if it is not due to our own connection to
                 the scdaemon.  */
              if (!gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                                 "SCD RESTART",
                                                 NULL, NULL, NULL, NULL,
                                                 NULL, NULL, &operr)
                  && !operr)
                {
                  err = gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                                      command,
                                                      scd_data_cb, NULL,
                                                      scd_inq_cb, NULL,
                                                      scd_status_cb, cardman,
                                                      &operr);
                  if (!err)
                    err = operr;
                }
            }
        }


      if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT
          || gpg_err_code (err) == GPG_ERR_CARD_REMOVED)
        {
          err_desc = _("No card found.");
        }
      else if (gpg_err_source (err) == GPG_ERR_SOURCE_SCD
               && gpg_err_code (err) == GPG_ERR_CONFLICT)
        {
          err_desc = auto_app
            ? _("The selected card application is currently not available.")
            : _("Another process is using a different card application "
                "than the selected one.\n\n"
                "You may change the application selection mode to "
                "\"Auto\" to select the active application.");
        }
      else if (!auto_app
               && gpg_err_source (err) == GPG_ERR_SOURCE_SCD
               && gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
        {
          err_desc =
            _("The selected card application is not available.");
        }
      else if (err)
        {
          g_debug ("assuan command `%s' failed: %s <%s>\n",
                   command, gpg_strerror (err), gpg_strsource (err));
          if (!gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                             "SCD SERIALNO undefined",
                                             NULL, NULL, NULL, NULL,
                                             NULL, NULL, &operr) && !operr)
            err = 0;
          else
            {
              err_desc = _("Error accessing the card.");
              statusbar_update (cardman, _("Error accessing card"));
            }
        }
      g_free (command_buf);


      if (!err)
        {
          /* Get the event counter to avoid a duplicate reload due to
             the ticker.  */
          gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                        "GETEVENTCOUNTER",
                                        NULL, NULL,
                                        NULL, NULL,
                                        scd_status_cb, cardman, NULL);

          /* Now we need to get the APPTYPE of the card so that the
             correct GpaCM* object can can act on the data.  */
          command = "SCD GETATTR APPTYPE";
          err = gpgme_op_assuan_transact_ext (cardman->gpgagent,
                                              command,
                                              scd_data_cb, NULL,
                                              scd_inq_cb, NULL,
                                              scd_status_cb, cardman, &operr);
          if (!err)
            err = operr;

          if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT
              || gpg_err_code (err) == GPG_ERR_CARD_REMOVED)
            statusbar_update (cardman, _("No card"));
          else if (err)
            {
              g_debug ("assuan command `%s' failed: %s <%s>\n",
                       command, gpg_strerror (err), gpg_strsource (err));
              statusbar_update (cardman, _("Error accessing card"));
            }
        }


      update_card_widget (cardman, err_desc);
      g_free (err_desc_buffer);
      err_desc_buffer = NULL;
      err_desc = NULL;
      update_title (cardman);

      update_info_visibility (cardman);
      /* We decrement our lock using a idle handler with lo priority.
         This gives us a better chance not to do a reload a second
         time on behalf of the file watcher or ticker.  */
      g_object_ref (cardman);
      g_idle_add_full (G_PRIORITY_LOW,
                       card_reload_finish_idle_cb, cardman, NULL);
    }
}