コード例 #1
0
ファイル: simple-pwquery.c プロジェクト: GroovIM/transport
/* Perform the simple query QUERY (which must be new-line and 0
   terminated) and return the error code.  */
int
simple_query (const char *query)
{
  int fd = -1;
  int nread;
  char response[500];
  int rc;

  rc = agent_open (&fd);
  if (rc)
    goto leave;

  rc = writen (fd, query, strlen (query));
  if (rc)
    goto leave;

  /* get response */
  nread = readline (fd, response, 499);
  if (nread < 0)
    {
      rc = -nread;
      goto leave;
    }
  if (nread < 3)
    {
      rc = SPWQ_PROTOCOL_ERROR;
      goto leave;
    }
  
  if (response[0] == 'O' && response[1] == 'K') 
    /* OK, do nothing.  */;
  else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
            && (response[7] == ' ' || response[7] == '\n') )
           || ((nread > 4 && !memcmp (response, "ERR ", 4)
                && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) 
    {
      /* 111 is the old Assuan code for canceled which might still
         be in use by old installations. 99 is GPG_ERR_CANCELED as
         used by modern gpg-agents; 0xffff is used to mask out the
         error source.  */
#ifdef SPWQ_USE_LOGGING
      log_info (_("canceled by user\n") );
#endif
    }
  else 
    {
#ifdef SPWQ_USE_LOGGING
      log_error (_("problem with the agent\n"));
#endif
      rc = SPWQ_ERR_RESPONSE;
    }
        
 leave:
  if (fd != -1)
    close (fd);
  return rc;
}
コード例 #2
0
ファイル: simple-pwquery.c プロジェクト: GroovIM/transport
/* Ask the gpg-agent for a passphrase and present the user with a
   DESCRIPTION, a PROMPT and optionally with a TRYAGAIN extra text.
   If a CACHEID is not NULL it is used to locate the passphrase in in
   the cache and store it under this ID.  If OPT_CHECK is true
   gpg-agent is asked to apply some checks on the passphrase security.
   If ERRORCODE is not NULL it should point a variable receiving an
   errorcode; this error code might be 0 if the user canceled the
   operation.  The function returns NULL to indicate an error.  */
char *
simple_pwquery (const char *cacheid, 
                const char *tryagain,
                const char *prompt,
                const char *description,
                int opt_check,
                int *errorcode)
{
  int fd = -1;
  int nread;
  char *result = NULL;
  char *pw = NULL;
  char *p;
  int rc, i; 

  rc = agent_open (&fd);
  if (rc)
    goto leave;

  if (!cacheid)
    cacheid = "X";
  if (!tryagain)
    tryagain = "X";
  if (!prompt)
    prompt = "X";
  if (!description)
    description = "X";

  {
    char *line;
    /* We allocate 3 times the needed space so that there is enough
       space for escaping. */
    line = spwq_malloc (15 + 10
                        + 3*strlen (cacheid) + 1
                        + 3*strlen (tryagain) + 1
                        + 3*strlen (prompt) + 1
                        + 3*strlen (description) + 1
                        + 2);
    if (!line)
      {
        rc = SPWQ_OUT_OF_CORE;
        goto leave;
      }
    strcpy (line, "GET_PASSPHRASE ");
    p = line+15;
    if (opt_check)
      p = stpcpy (p, "--check ");
    p = copy_and_escape (p, cacheid);
    *p++ = ' ';
    p = copy_and_escape (p, tryagain);
    *p++ = ' ';
    p = copy_and_escape (p, prompt);
    *p++ = ' ';
    p = copy_and_escape (p, description);
    *p++ = '\n';
    rc = writen (fd, line, p - line);
    spwq_free (line);
    if (rc)
      goto leave;
  }

  /* get response */
  pw = spwq_secure_malloc (500);
  nread = readline (fd, pw, 499);
  if (nread < 0)
    {
      rc = -nread;
      goto leave;
    }
  if (nread < 3)
    {
      rc = SPWQ_PROTOCOL_ERROR;
      goto leave;
    }
      
  if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') 
    { /* we got a passphrase - convert it back from hex */
      size_t pwlen = 0;
      
      for (i=3; i < nread && hexdigitp (pw+i); i+=2)
        pw[pwlen++] = xtoi_2 (pw+i);
      pw[pwlen] = 0; /* make a C String */
      result = pw;
      pw = NULL;
    }
  else if ((nread > 7 && !memcmp (pw, "ERR 111", 7)
            && (pw[7] == ' ' || pw[7] == '\n') )
           || ((nread > 4 && !memcmp (pw, "ERR ", 4)
                && (strtoul (pw+4, NULL, 0) & 0xffff) == 99)) ) 
    {
      /* 111 is the old Assuan code for canceled which might still
         be in use by old installations. 99 is GPG_ERR_CANCELED as
         used by modern gpg-agents; 0xffff is used to mask out the
         error source.  */
#ifdef SPWQ_USE_LOGGING
      log_info (_("canceled by user\n") );
#endif
      *errorcode = 0; /* Special error code to indicate Cancel. */
    }
  else if (nread > 4 && !memcmp (pw, "ERR ", 4))
    {
      switch ( (strtoul (pw+4, NULL, 0) & 0xffff) )
        {
        case 85: rc = SPWQ_NO_PIN_ENTRY;  break;
        default: rc = SPWQ_GENERAL_ERROR; break;
        }
    }
  else 
    {
#ifdef SPWQ_USE_LOGGING
      log_error (_("problem with the agent\n"));
#endif
      rc = SPWQ_ERR_RESPONSE;
    }
        
 leave:
  if (errorcode)
    *errorcode = rc;
  if (fd != -1)
    close (fd);
  if (pw)
    spwq_secure_free (pw);
  return result;
}
コード例 #3
0
ファイル: simple-pwquery.c プロジェクト: gpg/gnupg
/* Perform the simple query QUERY (which must be new-line and 0
   terminated) and return the error code.  */
int
simple_query (const char *query)
{
  int fd = -1;
  int nread;
  char response[500];
  int have = 0;
  int rc;

  rc = agent_open (&fd);
  if (rc)
    goto leave;

  rc = writen (fd, query, strlen (query));
  if (rc)
    goto leave;

  while (1)
    {
      if (! have || ! strchr (response, '\n'))
        /* get response */
        {
          nread = readline (fd, &response[have],
                            sizeof (response) - 1 /* NUL */ - have);
          if (nread < 0)
            {
              rc = -nread;
              goto leave;
            }
          have += nread;
          if (have < 3)
            {
              rc = SPWQ_PROTOCOL_ERROR;
              goto leave;
            }
          response[have] = 0;
        }

      if (response[0] == 'O' && response[1] == 'K')
        /* OK, do nothing.  */;
      else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
                && (response[7] == ' ' || response[7] == '\n') )
               || ((nread > 4 && !memcmp (response, "ERR ", 4)
                    && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
        {
          /* 111 is the old Assuan code for canceled which might still
             be in use by old installations. 99 is GPG_ERR_CANCELED as
             used by modern gpg-agents; 0xffff is used to mask out the
             error source.  */
#ifdef SPWQ_USE_LOGGING
          log_info (_("canceled by user\n") );
#endif
        }
      else if (response[0] == 'S' && response[1] == ' ')
        {
          char *nextline;
          int consumed;

          nextline = strchr (response, '\n');
          if (! nextline)
            /* Point to the NUL.  */
            nextline = &response[have];
          else
            /* Move past the \n.  */
            nextline ++;

          consumed = (size_t) nextline - (size_t) response;

          /* Skip any additional newlines.  */
          while (consumed < have && response[consumed] == '\n')
            consumed ++;

          have -= consumed;

          if (have)
            memmove (response, &response[consumed], have + 1);

          continue;
        }
      else
        {
#ifdef SPWQ_USE_LOGGING
          log_error (_("problem with the agent (unexpected response \"%s\")\n"),
                     response);
#endif
          rc = SPWQ_ERR_RESPONSE;
        }

      break;
    }

 leave:
  if (fd != -1)
    close (fd);
  return rc;
}