Ejemplo n.º 1
0
static int copy_headers(void *in_ch, const char *key, const char *value)
{
    char **ch = in_ch;

    strcpy(*ch, FIELD_SEPARATOR);
    *ch += strlen(FIELD_SEPARATOR);

    *ch = copy_and_escape(*ch, key);

    strcpy(*ch, KEYVAL_SEPARATOR);
    *ch += strlen(KEYVAL_SEPARATOR);

    *ch = copy_and_escape(*ch, value);

    return 1;
}
Ejemplo n.º 2
0
/* Ask the gpg-agent to clear the passphrase for the cache ID CACHEID.  */
int
simple_pwclear (const char *cacheid)
{
  char line[500];
  char *p;

  /* We need not more than 50 characters for the command and the
     terminating nul.  */
  if (strlen (cacheid) * 3 > sizeof (line) - 50)
    return SPWQ_PROTOCOL_ERROR;

  strcpy (line, "CLEAR_PASSPHRASE ");
  p = line + 17;
  p = copy_and_escape (p, cacheid);
  *p++ = '\n';
  *p++ = '\0';

  return simple_query (line);
}
Ejemplo n.º 3
0
Archivo: log.c Proyecto: DonCN/haiku
static const char *
escnonprint_internal (const char *str, char escape, int base)
{
  static int ringpos;                   /* current ring position */
  int nprcnt;

  assert (base == 8 || base == 16);

  nprcnt = count_nonprint (str);
  if (nprcnt == 0)
    /* If there are no non-printable chars in STR, don't bother
       copying anything, just return STR.  */
    return str;

  {
    /* Set up a pointer to the current ring position, so we can write
       simply r->X instead of ring[ringpos].X. */
    struct ringel *r = ring + ringpos;

    /* Every non-printable character is replaced with the escape char
       and three (or two, depending on BASE) *additional* chars.  Size
       must also include the length of the original string and one
       additional char for the terminating \0. */
    int needed_size = strlen (str) + 1 + (base == 8 ? 3 * nprcnt : 2 * nprcnt);

    /* If the current buffer is uninitialized or too small,
       (re)allocate it.  */
    if (r->buffer == NULL || r->size < needed_size)
      {
        r->buffer = xrealloc (r->buffer, needed_size);
        r->size = needed_size;
      }

    copy_and_escape (str, r->buffer, escape, base);
    ringpos = (ringpos + 1) % RING_SIZE;
    return r->buffer;
  }
}
Ejemplo n.º 4
0
/* 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;
}
Ejemplo n.º 5
0
/* Run a quality inquiry for PASSPHRASE of LENGTH.  (We need LENGTH
   because not all backends might be able to return a proper
   C-string.).  Returns: A value between -100 and 100 to give an
   estimate of the passphrase's quality.  Negative values are use if
   the caller won't even accept that passphrase.  Note that we expect
   just one data line which should not be escaped in any represent a
   numeric signed decimal value.  Extra data is currently ignored but
   should not be send at all.  */
int
pinentry_inq_quality (pinentry_t pin, const char *passphrase, size_t length)
{
  ASSUAN_CONTEXT ctx = pin->ctx_assuan;
  const char prefix[] = "INQUIRE QUALITY ";
  char *command;
  char *line;
  size_t linelen;
  int gotvalue = 0;
  int value = 0;
  int rc;

  if (!ctx)
    return 0; /* Can't run the callback.  */

  if (length > 300)
    length = 300;  /* Limit so that it definitely fits into an Assuan
                      line.  */

  command = secmem_malloc (strlen (prefix) + 3*length + 1);
  if (!command)
    return 0;
  strcpy (command, prefix);
  copy_and_escape (command + strlen(command), passphrase, length);
  rc = assuan_write_line (ctx, command);
  secmem_free (command);
  if (rc)
    {
      fprintf (stderr, "ASSUAN WRITE LINE failed: rc=%d\n", rc);
      return 0;
    }

  for (;;)
    {
      do 
        {
          rc = assuan_read_line (ctx, &line, &linelen);
          if (rc)
            {
              fprintf (stderr, "ASSUAN READ LINE failed: rc=%d\n", rc);
              return 0;
            }
        }    
      while (*line == '#' || !linelen);
      if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
          && (!line[3] || line[3] == ' '))
        break; /* END command received*/
      if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N'
          && (!line[3] || line[3] == ' '))
        break; /* CAN command received*/
      if (line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
          && (!line[3] || line[3] == ' '))
        break; /* ERR command received*/
      if (line[0] != 'D' || line[1] != ' ' || linelen < 3 || gotvalue)
        continue;
      gotvalue = 1;
      value = atoi (line+2);
    }
  if (value < -100)
    value = -100;
  else if (value > 100)
    value = 100;

  return value;
}