コード例 #1
0
ファイル: call-pinentry.c プロジェクト: Juul/gnupg
/* Pop up the PINentry, display the text DESC and a button with the
   text OK_BTN (which may be NULL to use the default of "OK") and wait
   for the user to hit this button.  The return value is not
   relevant.  */
int
agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
{
  int rc;
  char line[ASSUAN_LINELENGTH];

  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
    return gpg_error (GPG_ERR_CANCELED);

  rc = start_pinentry (ctrl);
  if (rc)
    return rc;

  if (desc)
    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
  else
    snprintf (line, DIM(line)-1, "RESET");
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  /* Most pinentries out in the wild return the old Assuan error code
     for canceled which gets translated to an assuan Cancel error and
     not to the code for a user cancel.  Fix this here. */
  if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);

  if (rc)
    return unlock_pinentry (rc);

  if (ok_btn)
    {
      snprintf (line, DIM(line)-1, "SETOK %s", ok_btn);
      line[DIM(line)-1] = 0;
      rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL,
                            NULL, NULL, NULL);
      if (rc)
        return unlock_pinentry (rc);
    }

  rc = assuan_transact (entry_ctx, "CONFIRM --one-button", NULL, NULL, NULL,
                        NULL, NULL, NULL);
  if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);

  return unlock_pinentry (rc);
}
コード例 #2
0
ファイル: keytable.c プロジェクト: gpg/gpa
static void
first_half_done_cb (GpaContext *context, gpg_error_t err,
                    GpaKeyTable *keytable)
{
    if (keytable->did_first_half || !cms_hack)
    {
        /* We are here for the second time and thus we continue with the
           real done handler.  We do this also if the CMS_HACK has not
           been enabled.  We reset the protocol to OpenPGP because some
           old code might assume that it is in OpenPGP mode.  */
        keytable->fpr = NULL; /* Not needed anymore.  */
        gpgme_set_protocol (keytable->context->ctx, GPGME_PROTOCOL_OpenPGP);
        done_cb (context, err, keytable);
        return;
    }

    /* Now continue with a key listing for X.509 keys but save the error
       of the the PGP key listing.  */
    keytable->first_half_err = err;
    keytable->did_first_half = 1;

    gpgme_set_protocol (context->ctx, GPGME_PROTOCOL_CMS);
    err = gpgme_op_keylist_start (keytable->context->ctx,
                                  keytable->fpr,
                                  keytable->secret);
    keytable->fpr = NULL; /* Not needed anymore.  */
    if (err)
    {
        if (keytable->first_half_err)
            gpa_gpgme_warning (keytable->first_half_err);

        if ((gpg_err_code (err) == GPG_ERR_INV_ENGINE
                || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_PROTOCOL)
                && gpg_err_source (err) == GPG_ERR_SOURCE_GPGME)
        {
            if (gpg_err_code (err) == GPG_ERR_UNSUPPORTED_PROTOCOL)
                g_message ("Note: Please check libgpgme has "
                           "been build with support for CMS");
            gpa_window_error
            (_("It seems that no CMS engine is installed.\n\n"
               "Temporary disabling support for X.509.\n\n"
               "Please install a CMS engine or invoke this program\n"
               "with the option --disable-x509 ."), NULL);
            cms_hack = 0;
            err = 0;
        }
        else
            gpa_gpgme_warning (err);
        if (keytable->end)
        {
            keytable->end (keytable->data);
        }
    }
}
コード例 #3
0
ファイル: be-encfs.c プロジェクト: 0ndorio/gnupg
/* The main processing function as used by the runner.  */
static gpg_error_t
encfs_handler (void *opaque, runner_t runner, const char *status_line)
{
  encfs_parm_t parm = opaque;
  gpg_error_t err;

  if (!parm || !runner)
    return gpg_error (GPG_ERR_BUG);
  if (!status_line)
    {
      /* Runner requested internal flushing - nothing to do here. */
      return 0;
    }

  err = handle_status_line (runner, status_line, parm->cmd, parm->tuples);
  if (gpg_err_code (err) == GPG_ERR_UNFINISHED
      && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
    {
      err = 0;
      /* No more need for the tuples.  */
      destroy_tupledesc (parm->tuples);
      parm->tuples = NULL;

      if (parm->cmd == ENCFS_CMD_CREATE)
        {
          /* The encfs tool keeps on running after creation of the
             container.  We don't want that and thus need to stop the
             encfs process. */
          run_umount_helper (parm->mountpoint);
          /* In case the umount helper does not work we try to kill
             the engine.  FIXME: We should figure out how to make
             fusermount work.  */
          runner_cancel (runner);
        }
    }

  return err;
}
コード例 #4
0
ファイル: gpg-error.c プロジェクト: BogdanStroe/cubrid
int
main (int argc, char *argv[])
{
  int i = 1;
  int listmode = 0;
  const char *source_sym;
  const char *error_sym;
  gpg_error_t err;

#ifndef GPG_ERR_INITIALIZED
  gpg_err_init ();
#endif

  i18n_init ();


  if (argc == 1)
    {
      fprintf (stderr, _("Usage: %s GPG-ERROR [...]\n"), 
               strrchr (argv[0],'/')? (strrchr (argv[0], '/')+1): argv[0]);
      exit (1);
    }
  else if (argc == 2 && !strcmp (argv[1], "--version"))
    {
      fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout);
      exit (0);
    }
  else if (argc == 2 && !strcmp (argv[1], "--list"))
    {
      listmode = 1;
    }


  if (listmode)
    {
      for (i=0; i <  GPG_ERR_SOURCE_DIM; i++)
        {
          /* We use error code 1 because gpg_err_make requires a
             non-zero error code. */
          err = gpg_err_make (i, 1);
          err -= 1;
	  source_sym = gpg_strsource_sym (err);
          if (source_sym)
            printf ("%u = (%u, -) = (%s, -) = (%s, -)\n",
                    err, gpg_err_source (err),
                    source_sym, gpg_strsource (err));
        }
      for (i=0; i <  GPG_ERR_CODE_DIM; i++)
        {
          err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
	  error_sym = gpg_strerror_sym (err);
          if (error_sym)
            printf ("%u = (-, %u) = (-, %s) = (-, %s)\n",
                    err, gpg_err_code (err),
                    error_sym, gpg_strerror (err));
        }

      i = argc;  /* Don't run the usual stuff.  */
    }
  while (i < argc)
    {
      if (get_err_from_number (argv[i], &err)
	  || get_err_from_symbol (argv[i], &err)
	  || get_err_from_str (argv[i], &err))
	{
	  source_sym = gpg_strsource_sym (err);
	  error_sym = gpg_strerror_sym (err);
	  
	  printf ("%u = (%u, %u) = (%s, %s) = (%s, %s)\n",
		  err, gpg_err_source (err), gpg_err_code (err),
		  source_sym ? source_sym : "-", error_sym ? error_sym : "-",
		  gpg_strsource (err), gpg_strerror (err));
	}
      else
	fprintf (stderr, _("%s: warning: could not recognize %s\n"),
		 argv[0], argv[i]);
      i++;
    }

  exit (0);
}
コード例 #5
0
ファイル: keybox-dump.c プロジェクト: rmoriz/gnupg-mirror
int
_keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
{
  FILE *fp;
  KEYBOXBLOB blob;
  int rc;
  unsigned long count = 0;
  struct file_stats_s stats;

  memset (&stats, 0, sizeof stats);

  if (!(fp = open_file (&filename, outfp)))
    return gpg_error_from_syserror ();

  for (;;)
    {
      rc = _keybox_read_blob (&blob, fp);
      if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
          && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
        {
          if (stats_only)
            stats.skipped_long_blobs++;
          else
            {
              fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
              fprintf (outfp, "# Record too large\nEND-RECORD\n");
            }
          count++;
          continue;
        }
      if (rc)
        break;

      if (stats_only)
        {
          update_stats (blob, &stats);
        }
      else
        {
          fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
          _keybox_dump_blob (blob, outfp);
          fprintf (outfp, "END-RECORD\n");
        }
      _keybox_release_blob (blob);
      count++;
    }
  if (rc == -1)
    rc = 0;
  if (rc)
    fprintf (outfp, "# error reading '%s': %s\n", filename, gpg_strerror (rc));

  if (fp != stdin)
    fclose (fp);

  if (stats_only)
    {
      fprintf (outfp,
               "Total number of blobs: %8lu\n"
               "               header: %8lu\n"
               "                empty: %8lu\n"
               "              openpgp: %8lu\n"
               "                 x509: %8lu\n"
               "          non flagged: %8lu\n"
               "       secret flagged: %8lu\n"
               "    ephemeral flagged: %8lu\n",
               stats.total_blob_count,
               stats.header_blob_count,
               stats.empty_blob_count,
               stats.pgp_blob_count,
               stats.x509_blob_count,
               stats.non_flagged,
               stats.secret_flagged,
               stats.ephemeral_flagged);
        if (stats.skipped_long_blobs)
          fprintf (outfp, "   skipped long blobs: %8lu\n",
                   stats.skipped_long_blobs);
        if (stats.unknown_blob_count)
          fprintf (outfp, "   unknown blob types: %8lu\n",
                   stats.unknown_blob_count);
        if (stats.too_short_blobs)
          fprintf (outfp, "      too short blobs: %8lu (error)\n",
                   stats.too_short_blobs);
        if (stats.too_large_blobs)
          fprintf (outfp, "      too large blobs: %8lu (error)\n",
                   stats.too_large_blobs);
    }

  return rc;
}
コード例 #6
0
ファイル: engine-gpgsm.c プロジェクト: serghei/kde3-kdepim
static gpgme_error_t
map_assuan_error(gpg_error_t err)
{
    if(!err)
        return 0;

    if(err == -1)
        return gpg_error(GPG_ERR_INV_ENGINE);

    /* New code will use gpg_error_t values.  */
    if(gpg_err_source(err))
        return (gpgme_error_t) err;

    /* Legacy code will use old values.  */
    switch(err)
    {
        case ASSUAN_No_Error:
            return gpg_error(GPG_ERR_NO_ERROR);
        case ASSUAN_General_Error:
            return gpg_error(GPG_ERR_GENERAL);
        case ASSUAN_Out_Of_Core:
            return gpg_error(GPG_ERR_ENOMEM);
        case ASSUAN_Invalid_Value:
            return gpg_error(GPG_ERR_INV_VALUE);
        case ASSUAN_Timeout:
            return gpg_error(GPG_ERR_ETIMEDOUT);
        case ASSUAN_Read_Error:
            return gpg_error(GPG_ERR_GENERAL);
        case ASSUAN_Write_Error:
            return gpg_error(GPG_ERR_GENERAL);

        case ASSUAN_Problem_Starting_Server:
        case ASSUAN_Not_A_Server:
        case ASSUAN_Not_A_Client:
        case ASSUAN_Nested_Commands:
        case ASSUAN_No_Data_Callback:
        case ASSUAN_No_Inquire_Callback:
        case ASSUAN_Connect_Failed:
        case ASSUAN_Accept_Failed:
        case ASSUAN_Invalid_Command:
        case ASSUAN_Unknown_Command:
        case ASSUAN_Syntax_Error:
        case ASSUAN_Parameter_Error:
        case ASSUAN_Parameter_Conflict:
        case ASSUAN_No_Input:
        case ASSUAN_No_Output:
        case ASSUAN_No_Data_Available:
        case ASSUAN_Too_Much_Data:
        case ASSUAN_Inquire_Unknown:
        case ASSUAN_Inquire_Error:
        case ASSUAN_Invalid_Option:
        case ASSUAN_Unexpected_Status:
        case ASSUAN_Unexpected_Data:
        case ASSUAN_Invalid_Status:
            return gpg_error(GPG_ERR_ASSUAN);

        case ASSUAN_Invalid_Response:
            return gpg_error(GPG_ERR_INV_RESPONSE);

        case ASSUAN_Not_Implemented:
            return gpg_error(GPG_ERR_NOT_IMPLEMENTED);
        case ASSUAN_Line_Too_Long:
            return gpg_error(GPG_ERR_LINE_TOO_LONG);
        case ASSUAN_Line_Not_Terminated:
            return gpg_error(GPG_ERR_INCOMPLETE_LINE);
        case ASSUAN_Canceled:
            return gpg_error(GPG_ERR_CANCELED);

        case ASSUAN_Unsupported_Algorithm:
            return gpg_error(GPG_ERR_UNSUPPORTED_ALGORITHM);
        case ASSUAN_Server_Resource_Problem:
            return gpg_error(GPG_ERR_RESOURCE_LIMIT);
        case ASSUAN_Server_IO_Error:
            return gpg_error(GPG_ERR_GENERAL);
        case ASSUAN_Server_Bug:
            return gpg_error(GPG_ERR_BUG);
        case ASSUAN_Invalid_Data:
            return gpg_error(GPG_ERR_INV_DATA);
        case ASSUAN_Invalid_Index:
            return gpg_error(GPG_ERR_INV_INDEX);
        case ASSUAN_Not_Confirmed:
            return gpg_error(GPG_ERR_NOT_CONFIRMED);
        case ASSUAN_Bad_Certificate:
            return gpg_error(GPG_ERR_BAD_CERT);
        case ASSUAN_Bad_Certificate_Chain:
            return gpg_error(GPG_ERR_BAD_CERT_CHAIN);
        case ASSUAN_Missing_Certificate:
            return gpg_error(GPG_ERR_MISSING_CERT);
        case ASSUAN_Bad_Signature:
            return gpg_error(GPG_ERR_BAD_SIGNATURE);
        case ASSUAN_No_Agent:
            return gpg_error(GPG_ERR_NO_AGENT);
        case ASSUAN_Agent_Error:
            return gpg_error(GPG_ERR_AGENT);
        case ASSUAN_No_Public_Key:
            return gpg_error(GPG_ERR_NO_PUBKEY);
        case ASSUAN_No_Secret_Key:
            return gpg_error(GPG_ERR_NO_SECKEY);
        case ASSUAN_Invalid_Name:
            return gpg_error(GPG_ERR_INV_NAME);

        case ASSUAN_Cert_Revoked:
            return gpg_error(GPG_ERR_CERT_REVOKED);
        case ASSUAN_No_CRL_For_Cert:
            return gpg_error(GPG_ERR_NO_CRL_KNOWN);
        case ASSUAN_CRL_Too_Old:
            return gpg_error(GPG_ERR_CRL_TOO_OLD);
        case ASSUAN_Not_Trusted:
            return gpg_error(GPG_ERR_NOT_TRUSTED);

        case ASSUAN_Card_Error:
            return gpg_error(GPG_ERR_CARD);
        case ASSUAN_Invalid_Card:
            return gpg_error(GPG_ERR_INV_CARD);
        case ASSUAN_No_PKCS15_App:
            return gpg_error(GPG_ERR_NO_PKCS15_APP);
        case ASSUAN_Card_Not_Present:
            return gpg_error(GPG_ERR_CARD_NOT_PRESENT);
        case ASSUAN_Invalid_Id:
            return gpg_error(GPG_ERR_INV_ID);
        default:
            return gpg_error(GPG_ERR_GENERAL);
    }
}
コード例 #7
0
ファイル: be-encfs.c プロジェクト: 0ndorio/gnupg
/* Handle one line of the encfs tool's output.  This function is
   allowed to modify the content of BUFFER.  */
static gpg_error_t
handle_status_line (runner_t runner, const char *line,
                    enum encfs_cmds cmd, tupledesc_t tuples)
{
  gpg_error_t err;

  /* Check that encfs understands our new options.  */
  if (!strncmp (line, "$STATUS$", 8))
    {
      for (line +=8; *line && spacep (line); line++)
        ;
      log_info ("got status '%s'\n", line);
      if (!strcmp (line, "fuse_main_start"))
        {
          /* Send a special error code back to let the caller know
             that everything has been setup by encfs.  */
          err = gpg_error (GPG_ERR_UNFINISHED);
        }
      else
        err = 0;
    }
  else if (!strncmp (line, "$PROMPT$", 8))
    {
      for (line +=8; *line && spacep (line); line++)
        ;
      log_info ("got prompt '%s'\n", line);
      if (!strcmp (line, "create_root_dir"))
        err = send_cmd (runner, cmd == ENCFS_CMD_CREATE? "y":"n");
      else if (!strcmp (line, "create_mount_point"))
        err = send_cmd (runner, "y");
      else if (!strcmp (line, "passwd")
               || !strcmp (line, "new_passwd"))
        {
          if (tuples)
            {
              size_t n;
              const void *value;

              value = find_tuple (tuples, KEYBLOB_TAG_ENCKEY, &n);
              if (!value)
                err = gpg_error (GPG_ERR_INV_SESSION_KEY);
              else if ((err = send_cmd_bin (runner, value, n)))
                {
                  if (gpg_err_code (err) == GPG_ERR_BUG
                      && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT)
                    err = gpg_error (GPG_ERR_INV_SESSION_KEY);
                }
            }
          else
            err = gpg_error (GPG_ERR_NO_DATA);
        }
      else
        err = send_cmd (runner, ""); /* Default to send an empty line.  */
    }
  else if (strstr (line, "encfs: unrecognized option '"))
    err = gpg_error (GPG_ERR_INV_ENGINE);
  else
    err = 0;

  return err;
}
コード例 #8
0
ファイル: call-pinentry.c プロジェクト: Juul/gnupg
/* Ask for the passphrase using the supplied arguments.  The returned
   passphrase needs to be freed by the caller. */
int
agent_get_passphrase (ctrl_t ctrl,
                      char **retpass, const char *desc, const char *prompt,
                      const char *errtext, int with_qualitybar)
{

  int rc;
  char line[ASSUAN_LINELENGTH];
  struct entry_parm_s parm;
  int saveflag;
  int close_button;

  *retpass = NULL;
  if (opt.batch)
    return gpg_error (GPG_ERR_BAD_PASSPHRASE);

  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
    {
      if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
        return gpg_error (GPG_ERR_CANCELED);

      if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
        {
	  size_t size;
	  size_t len = ASSUAN_LINELENGTH/2;
	  unsigned char *buffer = gcry_malloc_secure (len);

	  rc = pinentry_loopback(ctrl, "PASSPHRASE", &buffer, &size, len);
	  if (rc)
	    xfree(buffer);
	  else
	    {
	      buffer[size] = 0;
	      *retpass = buffer;
	    }
	  return rc;
        }
      return gpg_error (GPG_ERR_NO_PIN_ENTRY);
    }

  rc = start_pinentry (ctrl);
  if (rc)
    return rc;

  if (!prompt)
    prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");


  if (desc)
    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
  else
    snprintf (line, DIM(line)-1, "RESET");
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  if (with_qualitybar && opt.min_passphrase_len)
    {
      rc = setup_qualitybar ();
      if (rc)
        return unlock_pinentry (rc);
    }

  if (errtext)
    {
      snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
      line[DIM(line)-1] = 0;
      rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
      if (rc)
        return unlock_pinentry (rc);
    }

  memset (&parm, 0, sizeof parm);
  parm.size = ASSUAN_LINELENGTH/2 - 5;
  parm.buffer = gcry_malloc_secure (parm.size+10);
  if (!parm.buffer)
    return unlock_pinentry (out_of_core ());

  saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
  assuan_begin_confidential (entry_ctx);
  close_button = 0;
  rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
                        inq_quality, entry_ctx,
                        close_button_status_cb, &close_button);
  assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
  /* Most pinentries out in the wild return the old Assuan error code
     for canceled which gets translated to an assuan Cancel error and
     not to the code for a user cancel.  Fix this here. */
  if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
  /* Change error code in case the window close button was clicked
     to cancel the operation.  */
  if (close_button && gpg_err_code (rc) == GPG_ERR_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);

  if (rc)
    xfree (parm.buffer);
  else
    *retpass = parm.buffer;
  return unlock_pinentry (rc);
}
コード例 #9
0
ファイル: call-pinentry.c プロジェクト: Juul/gnupg
/* Call the Entry and ask for the PIN.  We do check for a valid PIN
   number here and repeat it as long as we have invalid formed
   numbers. */
int
agent_askpin (ctrl_t ctrl,
              const char *desc_text, const char *prompt_text,
              const char *initial_errtext,
              struct pin_entry_info_s *pininfo)
{
  int rc;
  char line[ASSUAN_LINELENGTH];
  struct entry_parm_s parm;
  const char *errtext = NULL;
  int is_pin = 0;
  int saveflag;
  int close_button;

  if (opt.batch)
    return 0; /* fixme: we should return BAD PIN */

  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
    {
      if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
        return gpg_error (GPG_ERR_CANCELED);
      if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
        {
	  unsigned char *passphrase;
	  size_t size;

	  *pininfo->pin = 0; /* Reset the PIN. */
	  rc = pinentry_loopback(ctrl, "PASSPHRASE", &passphrase, &size,
		  pininfo->max_length);
	  if (rc)
	    return rc;

	  memcpy(&pininfo->pin, passphrase, size);
	  xfree(passphrase);
	  pininfo->pin[size] = 0;
	  if (pininfo->check_cb)
	    {
	      /* More checks by utilizing the optional callback. */
	      pininfo->cb_errtext = NULL;
	      rc = pininfo->check_cb (pininfo);
	    }
	  return rc;
	}
      return gpg_error(GPG_ERR_NO_PIN_ENTRY);
    }

  if (!pininfo || pininfo->max_length < 1)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!desc_text && pininfo->min_digits)
    desc_text = _("Please enter your PIN, so that the secret key "
                  "can be unlocked for this session");
  else if (!desc_text)
    desc_text = _("Please enter your passphrase, so that the secret key "
                  "can be unlocked for this session");

  if (prompt_text)
    is_pin = !!strstr (prompt_text, "PIN");
  else
    is_pin = desc_text && strstr (desc_text, "PIN");

  rc = start_pinentry (ctrl);
  if (rc)
    return rc;

  snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  snprintf (line, DIM(line)-1, "SETPROMPT %s",
            prompt_text? prompt_text : is_pin? "PIN:" : "Passphrase:");
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  /* If a passphrase quality indicator has been requested and a
     minimum passphrase length has not been disabled, send the command
     to the pinentry.  */
  if (pininfo->with_qualitybar && opt.min_passphrase_len )
    {
      rc = setup_qualitybar ();
      if (rc)
        return unlock_pinentry (rc);
    }

  if (initial_errtext)
    {
      snprintf (line, DIM(line)-1, "SETERROR %s", initial_errtext);
      line[DIM(line)-1] = 0;
      rc = assuan_transact (entry_ctx, line,
                            NULL, NULL, NULL, NULL, NULL, NULL);
      if (rc)
        return unlock_pinentry (rc);
    }

  for (;pininfo->failed_tries < pininfo->max_tries; pininfo->failed_tries++)
    {
      memset (&parm, 0, sizeof parm);
      parm.size = pininfo->max_length;
      *pininfo->pin = 0; /* Reset the PIN. */
      parm.buffer = (unsigned char*)pininfo->pin;

      if (errtext)
        {
          /* TRANSLATORS: The string is appended to an error message in
             the pinentry.  The %s is the actual error message, the
             two %d give the current and maximum number of tries. */
          snprintf (line, DIM(line)-1, _("SETERROR %s (try %d of %d)"),
                    errtext, pininfo->failed_tries+1, pininfo->max_tries);
          line[DIM(line)-1] = 0;
          rc = assuan_transact (entry_ctx, line,
                                NULL, NULL, NULL, NULL, NULL, NULL);
          if (rc)
            return unlock_pinentry (rc);
          errtext = NULL;
        }

      saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
      assuan_begin_confidential (entry_ctx);
      close_button = 0;
      rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
                            inq_quality, entry_ctx,
                            close_button_status_cb, &close_button);
      assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
      /* Most pinentries out in the wild return the old Assuan error code
         for canceled which gets translated to an assuan Cancel error and
         not to the code for a user cancel.  Fix this here. */
      if (rc && gpg_err_source (rc)
          && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
        rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);

      /* Change error code in case the window close button was clicked
         to cancel the operation.  */
      if (close_button && gpg_err_code (rc) == GPG_ERR_CANCELED)
        rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_FULLY_CANCELED);

      if (gpg_err_code (rc) == GPG_ERR_ASS_TOO_MUCH_DATA)
        errtext = is_pin? _("PIN too long")
                        : _("Passphrase too long");
      else if (rc)
        return unlock_pinentry (rc);

      if (!errtext && pininfo->min_digits)
        {
          /* do some basic checks on the entered PIN. */
          if (!all_digitsp (pininfo->pin))
            errtext = _("Invalid characters in PIN");
          else if (pininfo->max_digits
                   && strlen (pininfo->pin) > pininfo->max_digits)
            errtext = _("PIN too long");
          else if (strlen (pininfo->pin) < pininfo->min_digits)
            errtext = _("PIN too short");
        }

      if (!errtext && pininfo->check_cb)
        {
          /* More checks by utilizing the optional callback. */
          pininfo->cb_errtext = NULL;
          rc = pininfo->check_cb (pininfo);
          if (rc == -1 && pininfo->cb_errtext)
            errtext = pininfo->cb_errtext;
          else if (gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
                   || gpg_err_code (rc) == GPG_ERR_BAD_PIN)
            errtext = (is_pin? _("Bad PIN")
                       : _("Bad Passphrase"));
          else if (rc)
            return unlock_pinentry (rc);
        }

      if (!errtext)
        return unlock_pinentry (0); /* okay, got a PIN or passphrase */
    }

  return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN
                          : GPG_ERR_BAD_PASSPHRASE));
}
コード例 #10
0
ファイル: get-passphrase.c プロジェクト: Distrotech/gnupg
/* Ask for a passphrase via gpg-agent.  On success the caller needs to
   free the string stored at R_PASSPHRASE.  On error NULL will be
   stored at R_PASSPHRASE and an appropriate gpg error code is
   returned.  With REPEAT set to 1, gpg-agent will ask the user to
   repeat the just entered passphrase.  CACHE_ID is a gpg-agent style
   passphrase cache id or NULL.  ERR_MSG is a error message to be
   presented to the user (e.g. "bad passphrase - try again") or NULL.
   PROMPT is the prompt string to label the entry box, it may be NULL
   for a default one.  DESC_MSG is a longer description to be
   displayed above the entry box, if may be NULL for a default one.
   If USE_SECMEM is true, the returned passphrase is retruned in
   secure memory.  The length of all these strings is limited; they
   need to fit in their encoded form into a standard Assuan line (i.e
   less then about 950 characters).  All strings shall be UTF-8.  */
gpg_error_t
gnupg_get_passphrase (const char *cache_id,
                      const char *err_msg,
                      const char *prompt,
                      const char *desc_msg,
                      int repeat,
                      int check_quality,
                      int use_secmem,
                      char **r_passphrase)
{
  gpg_error_t err;
  char line[ASSUAN_LINELENGTH];
  const char *arg1 = NULL;
  char *arg2 = NULL;
  char *arg3 = NULL;
  char *arg4 = NULL;
  membuf_t data;

  *r_passphrase = NULL;

  err = start_agent ();
  if (err)
    return err;

  /* Check that the gpg-agent understands the repeat option.  */
  if (assuan_transact (agent_ctx,
                       "GETINFO cmd_has_option GET_PASSPHRASE repeat",
                       NULL, NULL, NULL, NULL, NULL, NULL))
    return gpg_error (GPG_ERR_NOT_SUPPORTED);

  arg1 = cache_id && *cache_id? cache_id:NULL;
  if (err_msg && *err_msg)
    if (!(arg2 = percent_plus_escape (err_msg)))
      goto no_mem;
  if (prompt && *prompt)
    if (!(arg3 = percent_plus_escape (prompt)))
      goto no_mem;
  if (desc_msg && *desc_msg)
    if (!(arg4 = percent_plus_escape (desc_msg)))
      goto no_mem;

  snprintf (line, DIM(line)-1,
            "GET_PASSPHRASE --data %s--repeat=%d -- %s %s %s %s",
            check_quality? "--check ":"",
            repeat,
            arg1? arg1:"X",
            arg2? arg2:"X",
            arg3? arg3:"X",
            arg4? arg4:"X");
  line[DIM(line)-1] = 0;
  xfree (arg2);
  xfree (arg3);
  xfree (arg4);

  if (use_secmem)
    init_membuf_secure (&data, 64);
  else
    init_membuf (&data, 64);
  err = assuan_transact (agent_ctx, line,
                         membuf_data_cb, &data,
                         default_inq_cb, NULL, NULL, NULL);

  /* Older Pinentries return the old assuan error code for canceled
     which gets translated bt libassuan to GPG_ERR_ASS_CANCELED and
     not to the code for a user cancel.  Fix this here. */
  if (err && gpg_err_source (err)
      && gpg_err_code (err) == GPG_ERR_ASS_CANCELED)
    err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);

  if (err)
    {
      void *p;
      size_t n;

      p = get_membuf (&data, &n);
      if (p)
        wipememory (p, n);
      xfree (p);
    }
  else
    {
      put_membuf (&data, "", 1);
      *r_passphrase = get_membuf (&data, NULL);
      if (!*r_passphrase)
        err = gpg_error_from_syserror ();
    }
  return err;
 no_mem:
  err = gpg_error_from_syserror ();
  xfree (arg2);
  xfree (arg3);
  xfree (arg4);
  return err;
}
コード例 #11
0
ファイル: call-pinentry.c プロジェクト: Juul/gnupg
/* Pop up the PIN-entry, display the text and the prompt and ask the
   user to confirm this.  We return 0 for success, ie. the user
   confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an
   other error.  If WITH_CANCEL it true an extra cancel button is
   displayed to allow the user to easily return a GPG_ERR_CANCELED.
   if the Pinentry does not support this, the user can still cancel by
   closing the Pinentry window.  */
int
agent_get_confirmation (ctrl_t ctrl,
                        const char *desc, const char *ok,
                        const char *notok, int with_cancel)
{
  int rc;
  char line[ASSUAN_LINELENGTH];

  if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
    {
      if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
        return gpg_error (GPG_ERR_CANCELED);

      return gpg_error (GPG_ERR_NO_PIN_ENTRY);
    }

  rc = start_pinentry (ctrl);
  if (rc)
    return rc;

  if (desc)
    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
  else
    snprintf (line, DIM(line)-1, "RESET");
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  /* Most pinentries out in the wild return the old Assuan error code
     for canceled which gets translated to an assuan Cancel error and
     not to the code for a user cancel.  Fix this here. */
  if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);

  if (rc)
    return unlock_pinentry (rc);

  if (ok)
    {
      snprintf (line, DIM(line)-1, "SETOK %s", ok);
      line[DIM(line)-1] = 0;
      rc = assuan_transact (entry_ctx,
                            line, NULL, NULL, NULL, NULL, NULL, NULL);
      if (rc)
        return unlock_pinentry (rc);
    }
  if (notok)
    {
      /* Try to use the newer NOTOK feature if a cancel button is
         requested.  If no cancel button is requested we keep on using
         the standard cancel.  */
      if (with_cancel)
        {
          snprintf (line, DIM(line)-1, "SETNOTOK %s", notok);
          line[DIM(line)-1] = 0;
          rc = assuan_transact (entry_ctx,
                                line, NULL, NULL, NULL, NULL, NULL, NULL);
        }
      else
        rc = GPG_ERR_ASS_UNKNOWN_CMD;

      if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
	{
	  snprintf (line, DIM(line)-1, "SETCANCEL %s", notok);
	  line[DIM(line)-1] = 0;
	  rc = assuan_transact (entry_ctx, line,
                                NULL, NULL, NULL, NULL, NULL, NULL);
	}
      if (rc)
        return unlock_pinentry (rc);
    }

  rc = assuan_transact (entry_ctx, "CONFIRM",
                        NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);

  return unlock_pinentry (rc);
}
コード例 #12
0
ファイル: strsource.c プロジェクト: 0xmono/miranda-ng
/* Return a pointer to a string containing a description of the error
   source in the error value ERR.  */
const char *
gpg_strsource (gpg_error_t err)
{
  gpg_err_source_t source = gpg_err_source (err);
  return dgettext (PACKAGE, msgstr + msgidx[msgidxof (source)]);
}
コード例 #13
0
ファイル: call-pinentry.c プロジェクト: HoraceWeebler/gnupg
/* Ask for the passphrase using the supplied arguments.  The returned
   passphrase needs to be freed by the caller. */
int 
agent_get_passphrase (ctrl_t ctrl,
                      char **retpass, const char *desc, const char *prompt,
                      const char *errtext, int with_qualitybar)
{

  int rc;
  char line[ASSUAN_LINELENGTH];
  struct entry_parm_s parm;
  int saveflag;

  *retpass = NULL;
  if (opt.batch)
    return gpg_error (GPG_ERR_BAD_PASSPHRASE); 

  rc = start_pinentry (ctrl);
  if (rc)
    return rc;

  if (!prompt)
    prompt = desc && strstr (desc, "PIN")? "PIN": _("Passphrase");


  if (desc)
    snprintf (line, DIM(line)-1, "SETDESC %s", desc);
  else
    snprintf (line, DIM(line)-1, "RESET");
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  snprintf (line, DIM(line)-1, "SETPROMPT %s", prompt);
  line[DIM(line)-1] = 0;
  rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
  if (rc)
    return unlock_pinentry (rc);

  if (with_qualitybar && opt.min_passphrase_len)
    {
      rc = setup_qualitybar ();
      if (rc)
        return unlock_pinentry (rc);
    }

  if (errtext)
    {
      snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
      line[DIM(line)-1] = 0;
      rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
      if (rc)
        return unlock_pinentry (rc);
    }

  memset (&parm, 0, sizeof parm);
  parm.size = ASSUAN_LINELENGTH/2 - 5;
  parm.buffer = gcry_malloc_secure (parm.size+10);
  if (!parm.buffer)
    return unlock_pinentry (out_of_core ());

  saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL);
  assuan_begin_confidential (entry_ctx);
  rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
                        inq_quality, entry_ctx, NULL, NULL);
  assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag);
  /* Most pinentries out in the wild return the old Assuan error code
     for canceled which gets translated to an assuan Cancel error and
     not to the code for a user cancel.  Fix this here. */
  if (rc && gpg_err_source (rc) && gpg_err_code (rc) == GPG_ERR_ASS_CANCELED)
    rc = gpg_err_make (gpg_err_source (rc), GPG_ERR_CANCELED);
  if (rc)
    xfree (parm.buffer);
  else
    *retpass = parm.buffer;
  return unlock_pinentry (rc);
}
コード例 #14
0
ファイル: gpg-error.c プロジェクト: OneSecure/libgpg-error
int
main (int argc, char *argv[])
{
  int i = 1;
  int listmode = 0;
  const char *source_sym;
  const char *error_sym;
  gpg_error_t err;

  gpgrt_init ();
  i18n_init ();

  if (argc == 1)
    {
      fprintf (stderr, _("Usage: %s GPG-ERROR [...]\n"),
               strrchr (argv[0],'/')? (strrchr (argv[0], '/')+1): argv[0]);
      exit (1);
    }
  else if (argc == 2 && !strcmp (argv[1], "--version"))
    {
      fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout);
      exit (0);
    }
  else if (argc == 2 && !strcmp (argv[1], "--help"))
    {
      fputs ("gpg-error (" PACKAGE_NAME ") " PACKAGE_VERSION "\n", stdout);
      fputs ("Options:\n"
             "  --version      Print version\n"
             "  --lib-version  Print library version\n"
             "  --help         Print this help\n"
             "  --list         Print all error codes\n"
             "  --defines      Print all error codes as #define lines\n"
             , stdout);
      exit (0);
    }
  else if (argc == 2 && !strcmp (argv[1], "--lib-version"))
    {
      printf ("Version from header: %s (0x%06x)\n",
              GPG_ERROR_VERSION, GPG_ERROR_VERSION_NUMBER);
      printf ("Version from binary: %s\n", gpg_error_check_version (NULL));
      printf ("Copyright blurb ...:%s\n", gpg_error_check_version ("\x01\x01"));
      exit (0);
    }
  else if (argc == 2 && !strcmp (argv[1], "--list"))
    {
      listmode = 1;
    }
  else if (argc == 2 && !strcmp (argv[1], "--defines"))
    {
      listmode = 2;
    }


  if (listmode == 1)
    {
      for (i=0; i <  GPG_ERR_SOURCE_DIM; i++)
        {
          /* We use error code 1 because gpg_err_make requires a
             non-zero error code. */
          err = gpg_err_make (i, 1);
          err -= 1;
	  source_sym = gpg_strsource_sym (err);
          if (source_sym)
            printf ("%u = (%u, -) = (%s, -) = (%s, -)\n",
                    err, gpg_err_source (err),
                    source_sym, gpg_strsource (err));
        }
      for (i=0; i <  GPG_ERR_CODE_DIM; i++)
        {
          err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
	  error_sym = gpg_strerror_sym (err);
          if (error_sym)
            printf ("%u = (-, %u) = (-, %s) = (-, %s)\n",
                    err, gpg_err_code (err),
                    error_sym, gpg_strerror (err));
        }
    }
  else if (listmode == 2)
    {
      int n, nmax;

      for (i=0, nmax=0; i <  GPG_ERR_SOURCE_DIM; i++)
        {
          err = gpg_err_make (i, 1);
	  source_sym = gpg_strsource_sym (err);
          if (source_sym)
            {
              n = strlen (source_sym);
              if (n > nmax)
                nmax = n;
            }
        }
      for (i=0; i <  GPG_ERR_SOURCE_DIM; i++)
        {
          err = gpg_err_make (i, 1);
	  source_sym = gpg_strsource_sym (err);
          if (source_sym)
            printf ("#define %-*s %3u\n", nmax,source_sym,gpg_err_source (err));
        }


      for (i=0, nmax = 0; i <  GPG_ERR_CODE_DIM; i++)
        {
          err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
	  error_sym = gpg_strerror_sym (err);
          if (error_sym)
            {
              n = strlen (error_sym);
              if (n > nmax)
                nmax = n;
            }
        }
      for (i=0; i <  GPG_ERR_CODE_DIM; i++)
        {
          err = gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, i);
	  error_sym = gpg_strerror_sym (err);
          if (error_sym)
            printf ("#define %-*s %5u\n", nmax, error_sym, gpg_err_code (err));
        }
    }
  else /* Standard mode.  */
    {
      while (i < argc)
        {
          if (get_err_from_number (argv[i], &err)
              || get_err_from_symbol (argv[i], &err)
              || get_err_from_str (argv[i], &err))
            {
              source_sym = gpg_strsource_sym (err);
              error_sym = gpg_strerror_sym (err);

              printf ("%u = (%u, %u) = (%s, %s) = (%s, %s)\n",
                      err, gpg_err_source (err), gpg_err_code (err),
                      source_sym ? source_sym : "-", error_sym ? error_sym:"-",
                      gpg_strsource (err), gpg_strerror (err));
            }
          else
            fprintf (stderr, _("%s: warning: could not recognize %s\n"),
                     argv[0], argv[i]);
          i++;
        }
    }

  exit (0);
}
コード例 #15
0
ファイル: cardman.c プロジェクト: 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);
    }
}
コード例 #16
0
ファイル: gpgmewrapper.cpp プロジェクト: sigsergv/guzum
QByteArray GPGME::decryptFile(const QString & filename, QString & keyId, QWidget * parent)
{
    setError(GPG_ERR_NO_ERROR); // clear error
    CallbackData cbData;
    cbData.parent = parent;


    qDebug() << "ERERR" << gpg_err_source(GPG_ERR_CODE_DIM+1);

    gpgme_set_passphrase_cb(p->context, passphraseCallback, &cbData);

    qDebug() << "decrypting file" << filename;
    gpgme_data_t data;
    gpgme_error_t err;

    QFile file(filename);
    if (!file.exists()) {
        setError(GPGME_WRAPPER_ERR_FILE_NOT_FOUND, true);
        return QByteArray();
    }
    if (!file.open(QIODevice::ReadOnly)) {
        setError(GPGME_WRAPPER_ERR_CANNOT_OPEN_FILE, true);
        return QByteArray();
    }
    if (file.size() > FILESIZE_HARD_LIMIT) {
        setError(GPGME_WRAPPER_ERR_FILE_TOO_LARGE, true);
        return QByteArray();
    }

    err = gpgme_data_new_from_fd(&data, file.handle());
    if (err != GPG_ERR_NO_ERROR) {
        setError(err);
        return QByteArray();
    }

    // process data (it's cipher)
    gpgme_data_t plain;
    gpgme_data_new(&plain);
    err = gpgme_op_decrypt(p->context, data, plain);
    // unset passphrase callback
    gpgme_set_passphrase_cb(p->context, 0, 0);
    if (err != GPG_ERR_NO_ERROR) {
        gpgme_data_release(data);
        gpgme_data_release(plain);
        setError(err);
        return QByteArray();
    }

    // decryption is successful so load plain data
    QByteArray resBytes;
    const int bufSize = 1000;
    int read;
    char buf[bufSize];

    gpgme_data_seek(plain, 0, SEEK_SET);
    while (true) {
        read = gpgme_data_read(plain, (void*)buf, bufSize);
        if (read == 0) {
            break;
        }
        if (read == -1) {
            // error, ignore for now
            break;
        }
        resBytes.append(buf, read);
    }

    gpgme_decrypt_result_t decrypt_res = gpgme_op_decrypt_result(p->context);
    gpgme_recipient_t recipient;
    if (decrypt_res) {
        recipient = decrypt_res->recipients;
        while (recipient) {
            keyId = recipient->keyid;
            recipient = recipient->next;
            break; // just ignore the other recipients
        }
    }
    return resBytes;
}