Exemple #1
0
void psTraceBytes(char *tag, unsigned char *p, int l)
{
	char	s[17];
	int		i;

	s[16] = '\0';
	_psTraceStr("psTraceBytes(%s, ", tag);
	_psTraceInt("%d);", l);
	for (i = 0; i < l; i++) {
		if (!(i & 0xF)) {
			if (i != 0) {
				mem2str(s, p - 16, 16);
				_psTraceStr("  %s", s);
			}
			_psTraceInt("\n0x%08x:", (int)p);
		}
		_psTraceInt("%02x ", *p++);
	}
	memset(s, 0x0, 16);
	i = l & 0xF;
	mem2str(s, p - i, (unsigned int)i);
	for (;i < 16; i++) {
		_psTrace("   ");
	}
	_psTraceStr("  %s", s);
	_psTrace("\n");
}
Exemple #2
0
/* Toggle a button and return the new state.  */
static void
toggle_button (LPDISPATCH button, const char *tag, int instid)
{
  int state;
  char tag2[256];
  char *p;
  LPDISPATCH inspector;
  
  inspector = get_inspector_from_instid (instid);
  if (!inspector)
    {
      log_debug ("%s:%s: inspector not found", SRCNAME, __func__);
      return;
    }

  state = get_oom_int (button, "State");
  log_debug ("%s:%s: button `%s' state is %d", SRCNAME, __func__, tag, state);
  state = (state == msoButtonUp)? msoButtonDown : msoButtonUp;
  put_oom_int (button, "State", state);

  /* Toggle the other button.  */
  mem2str (tag2, tag, sizeof tag2 - 2);
  p = strchr (tag2, '#');
  if (p)
    *p = 0;  /* Strip the instance id suffix.  */
  if (*tag2 && tag2[1] && !strcmp (tag2+strlen(tag2)-2, "@t"))
    tag2[strlen(tag2)-2] = 0; /* Remove the "@t".  */
  else
    strcat (tag2, "@t");      /* Append a "@t".  */
  
  log_debug ("%s:%s: setting `%s' state to %d", SRCNAME, __func__, tag2, state);
  set_one_button (inspector, tag2, state);
  inspector->Release ();
}
Exemple #3
0
static int
double_filter (void *opaque, int control,
	       iobuf_t chain, byte *buf, size_t *len)
{
  (void) opaque;

  if (control == IOBUFCTRL_DESC)
    {
      mem2str (buf, "double_filter", *len);
    }
  if (control == IOBUFCTRL_FLUSH)
    {
      int i;

      for (i = 0; i < *len; i ++)
	{
	  int rc;

	  rc = iobuf_writebyte (chain, buf[i]);
	  if (rc)
	    return rc;
	  rc = iobuf_writebyte (chain, buf[i]);
	  if (rc)
	    return rc;
	}
    }

  return 0;
}
Exemple #4
0
/* Return every other byte.  In particular, reads two bytes, returns
   the second one.  */
static int
every_other_filter (void *opaque, int control,
		    iobuf_t chain, byte *buf, size_t *len)
{
  (void) opaque;

  if (control == IOBUFCTRL_DESC)
    {
      mem2str (buf, "every_other_filter", *len);
    }
  if (control == IOBUFCTRL_UNDERFLOW)
    {
      int c = iobuf_readbyte (chain);
      int c2;
      if (c == -1)
	c2 = -1;
      else
	c2 = iobuf_readbyte (chain);

      /* printf ("Discarding %d (%c); return %d (%c)\n", c, c, c2, c2); */

      if (c2 == -1)
	{
	  *len = 0;
	  return -1;
	}

      *buf = c2;
      *len = 1;

      return 0;
    }

  return 0;
}
Exemple #5
0
static void *
handle_taskbar (void *ctx)
{
    WNDCLASS wndwclass = {0, wndw_proc, 0, 0, glob_hinst,
                          0, 0, 0, 0, "gpg-agent"
                         };
    NOTIFYICONDATA nid;
    HWND hwnd;
    MSG msg;
    int rc;

    if (!RegisterClass (&wndwclass))
    {
        log_error ("error registering window class\n");
        ExitThread (0);
    }
    hwnd = CreateWindow ("gpg-agent", "gpg-agent",
                         0, 0, 0, 0, 0,
                         NULL, NULL, glob_hinst, NULL);
    if (!hwnd)
    {
        log_error ("error creating main window\n");
        ExitThread (0);
    }
    glob_hwnd = hwnd;
    UpdateWindow (hwnd);

    memset (&nid, 0, sizeof nid);
    nid.cbSize = sizeof (nid);
    nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
    nid.uCallbackMessage = WM_USER;
    nid.hWnd = glob_hwnd;
    nid.uID = 1;
    nid.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (1));
    mem2str (nid.szTip, "GnuPG Agent version "PACKAGE_VERSION,
             sizeof nid.szTip);
    Shell_NotifyIcon (NIM_ADD, &nid);
    DestroyIcon (nid.hIcon);

    fprintf (stderr, "%s: enter\n", __func__);
    while ( (rc=GetMessage (&msg, hwnd,  0, 0)) )
    {
        if (rc == -1)
        {
            log_error ("getMessage failed: %s\n", w32_strerror (-1));
            break;
        }
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
    fprintf (stderr,"%s: leave\n", __func__);
    ExitThread (0);
    return NULL;
}
/****************
 * Note: this function returns local time
 */
const char *
asctimestamp( u32 stamp )
{
    static char buffer[50];
#if defined (HAVE_STRFTIME) && defined (HAVE_NL_LANGINFO)
      static char fmt[50];
#endif
    struct tm *tp;
    time_t atime = stamp;

    if (atime < 0) {
        strcpy (buffer, "????" "-??" "-??");
        return buffer;
    }

    tp = localtime( &atime );
#ifdef HAVE_STRFTIME
#if defined(HAVE_NL_LANGINFO)
      mem2str( fmt, nl_langinfo(D_T_FMT), DIM(fmt)-3 );
      if( strstr( fmt, "%Z" ) == NULL )
	strcat( fmt, " %Z");
      strftime( buffer, DIM(buffer)-1, fmt, tp );
#else
      /* fixme: we should check whether the locale appends a " %Z"
       * These locales from glibc don't put the " %Z":
       * fi_FI hr_HR ja_JP lt_LT lv_LV POSIX ru_RU ru_SU sv_FI sv_SE zh_CN
       */
      strftime( buffer, DIM(buffer)-1, 
#ifdef HAVE_W32_SYSTEM                
                "%c"
#else
                "%c %Z"
#endif
                , tp );
#endif
    buffer[DIM(buffer)-1] = 0;
#else
    mem2str( buffer, asctime(tp), DIM(buffer) );
#endif
    return buffer;
}
Exemple #7
0
/****************
 * The filter is used to report progress to the user.
 */
static int
progress_filter (void *opaque, int control,
		 IOBUF a, byte *buf, size_t *ret_len)
{
  int rc = 0;
  progress_filter_context_t *pfx = opaque;

  if (control == IOBUFCTRL_INIT)
    {
      pfx->last = 0;
      pfx->offset = 0;
      pfx->last_time = make_timestamp ();

      write_status_progress (pfx->what, pfx->offset, pfx->total);
    }
  else if (control == IOBUFCTRL_UNDERFLOW)
    {
      u32 timestamp = make_timestamp ();
      int len = iobuf_read (a, buf, *ret_len);

      if (len >= 0)
	{
	  pfx->offset += len;
	  *ret_len = len;
	}
      else
	{
	  *ret_len = 0;
	  rc = -1;
	}
      if ((len == -1 && pfx->offset != pfx->last)
	  || timestamp - pfx->last_time > 0)
	{
          write_status_progress (pfx->what, pfx->offset, pfx->total);
	  pfx->last = pfx->offset;
	  pfx->last_time = timestamp;
	}
    }
  else if (control == IOBUFCTRL_FREE)
    {
      release_progress_context (pfx);
    }
  else if (control == IOBUFCTRL_DESC)
    mem2str (buf, "progress_filter", *ret_len);
  return rc;
}
Exemple #8
0
static int
format_keyid ( const char *s, u32 *kid )
{
    char helpbuf[9];
    switch ( strlen ( s ) ) {
    case 8:
        kid[0] = 0;
        kid[1] = strtoul( s, NULL, 16 );
        return 10;

    case 16:
        mem2str( helpbuf, s, 9 );
        kid[0] = strtoul( helpbuf, NULL, 16 );
        kid[1] = strtoul( s+8, NULL, 16 );
        return 11;
    }
    return 0; /* error */
}
Exemple #9
0
static void join_demo_header(int threads, work_t* works) {
    char buf[64];
    int usrcpu = usrcpu_usage(threads, works);
    int syscpu = syscpu_usage(threads, works);
    mem2str(buf, mem_usage(threads, works) + sizeof(pthread_t) * threads);
    TRACE("*** PTHREAD JOIN DEMO ***\n"
            "CPU usage\n"
            "\tuser:   drops from %3d%% to 0%%\n"
            "\tsystem: drops from %3d%% to 0%%\n"
            "Memory usage\n"
            "\tdrops from %s to 0\n"
            "Thread usage\n"
            "\ttotal:  drops from %d to 0\n"
            "\tlocked: none\n",
            100 * usrcpu / MAX(usrcpu + syscpu, cpucount()),
            100 * syscpu / MAX(usrcpu + syscpu, cpucount()),
            buf, threads + 1);
}
Exemple #10
0
static void rwlock_demo_header(int readers, int writers, work_t* works) {
    char buf[64];
    int usrcpu = usrcpu_usage(readers, works);
    int syscpu = syscpu_usage(readers, works);
    int total = usrcpu + syscpu;
    usrcpu = 100 * usrcpu / MAX(total, cpucount());
    syscpu = 100 * syscpu / MAX(total, cpucount());
    mem2str(buf, (readers + writers) * sizeof (pthread_t) + mem_usage(readers, works));
    TRACE("*** PTHREAD RWLOCK DEMO ***\n"
            "CPU usage\n"
            "\tuser:   about %3d%%\n"
            "\tsystem: about %3d%%\n"
            "Memory usage\n"
            "\t%s\n"
            "Thread usage\n"
            "\ttotal:  %d\n"
            "\tlocked: %d\n",
            usrcpu, syscpu,
            buf, readers + writers + 1, writers);
}
Exemple #11
0
/****************
 * The filter is used to make canonical text: Lines are terminated by
 * CR, LF, trailing white spaces are removed.
 */
int
text_filter( void *opaque, int control,
	     IOBUF a, byte *buf, size_t *ret_len)
{
    size_t size = *ret_len;
    text_filter_context_t *tfx = opaque;
    int rc=0;

    if( control == IOBUFCTRL_UNDERFLOW ) {
	rc = standard( tfx, a, buf, size, ret_len );
    }
    else if( control == IOBUFCTRL_FREE ) {
	if( tfx->truncated )
	    log_error(_("can't handle text lines longer than %d characters\n"),
			MAX_LINELEN );
	xfree( tfx->buffer );
	tfx->buffer = NULL;
    }
    else if( control == IOBUFCTRL_DESC )
        mem2str (buf, "text_filter", *ret_len);
    return rc;
}
Exemple #12
0
/*
 * This filter is used to en/de-cipher data with a symmetric algorithm
 */
int
cipher_filter_cfb (void *opaque, int control,
                   iobuf_t a, byte *buf, size_t *ret_len)
{
  cipher_filter_context_t *cfx = opaque;
  size_t size = *ret_len;
  int rc = 0;

  if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
    {
      rc = -1; /* not yet used */
    }
  else if (control == IOBUFCTRL_FLUSH) /* encrypt */
    {
      log_assert (a);
      if (!cfx->wrote_header)
        write_header (cfx, a);
      if (cfx->mdc_hash)
        gcry_md_write (cfx->mdc_hash, buf, size);
      gcry_cipher_encrypt (cfx->cipher_hd, buf, size, NULL, 0);
      if (cfx->short_blklen_warn)
        {
          cfx->short_blklen_count += size;
          if (cfx->short_blklen_count > (150 * 1024 * 1024))
            {
              log_info ("WARNING: encrypting more than %d MiB with algorithm "
                        "%s should be avoided\n", 150,
                        openpgp_cipher_algo_name (cfx->dek->algo));
              cfx->short_blklen_warn = 0; /* Don't show again.  */
            }
        }

      rc = iobuf_write (a, buf, size);
    }
  else if (control == IOBUFCTRL_FREE)
    {
      if (cfx->mdc_hash)
        {
          byte *hash;
          int hashlen = gcry_md_get_algo_dlen (gcry_md_get_algo(cfx->mdc_hash));
          byte temp[22];

          log_assert (hashlen == 20);
          /* We must hash the prefix of the MDC packet here. */
          temp[0] = 0xd3;
          temp[1] = 0x14;
          gcry_md_putc (cfx->mdc_hash, temp[0]);
          gcry_md_putc (cfx->mdc_hash, temp[1]);

          gcry_md_final (cfx->mdc_hash);
          hash = gcry_md_read (cfx->mdc_hash, 0);
          memcpy(temp+2, hash, 20);
          gcry_cipher_encrypt (cfx->cipher_hd, temp, 22, NULL, 0);
          gcry_md_close (cfx->mdc_hash); cfx->mdc_hash = NULL;
          if (iobuf_write( a, temp, 22))
            log_error ("writing MDC packet failed\n");
	}

      gcry_cipher_close (cfx->cipher_hd);
    }
  else if (control == IOBUFCTRL_DESC)
    {
      mem2str (buf, "cipher_filter_cfb", *ret_len);
    }

  return rc;
}
Exemple #13
0
int
operand2str(operand_t const *op, char *buf, size_t size)
{
    char *ptr = buf, *end = buf + size;

    switch (op->type) {
    case invalid:
        DBE(INSN, dprintk("(inval)"));
        break;
    case op_reg:
        ptr += reg2str(op->val.reg, op->tag.reg, op->size, op->rex_used,
                       ptr, end - ptr);
        DBE(INSN, dprintk("(reg) %s", buf));
        break;
    case op_seg:
        ptr += seg2str(op->val.seg, op->tag.seg, ptr, end - ptr);
        DBE(INSN, dprintk("(seg) %s", buf));
        break;
    case op_mem:
        ptr += mem2str(&op->val.mem, &op->tag.mem, op->size, op->rex_used, ptr,
                       end - ptr);
        DBE(INSN, dprintk("(mem) %s", buf));
        break;
    case op_imm:
        ptr += imm2str(op->val.imm, op->tag.imm, ptr, end - ptr);
        DBE(INSN, dprintk("(imm) %s", buf));
        break;
    case op_pcrel:
        ptr += pcrel2str(op->val.pcrel, op->tag.pcrel, ptr, end - ptr);
        DBE(INSN, dprintk("(pcrel) %s", buf));
        break;
    case op_cr:
        ptr += cr2str(op->val.cr, op->tag.cr, ptr, end - ptr);
        DBE(INSN, dprintk("(cr) %s", buf));
        break;
    case op_db:
        ptr += db2str(op->val.db, op->tag.db, ptr, end - ptr);
        DBE(INSN, dprintk("(db) %s", buf));
        break;
    case op_tr:
        ptr += tr2str(op->val.tr, op->tag.tr, ptr, end - ptr);
        DBE(INSN, dprintk("(tr) %s", buf));
        break;
    case op_mmx:
        ptr += mmx2str(op->val.mmx, op->tag.mmx, ptr, end - ptr);
        DBE(INSN, dprintk("(mm) %s", buf));
        break;
    case op_xmm:
        ptr += xmm2str(op->val.xmm, op->tag.xmm, ptr, end - ptr);
        DBE(INSN, dprintk("(xmm) %s", buf));
        break;
    case op_3dnow:
        ptr += op3dnow2str(op->val.d3now, op->tag.d3now, ptr, end - ptr);
        DBE(INSN, dprintk("(3dnow) %s", buf));
        break;
    case op_prefix:
        ptr += prefix2str(op->val.prefix, op->tag.prefix, ptr, end - ptr);
        break;
    case op_st:
        ptr += st2str(op->val.st, op->tag.st, ptr, end - ptr);
        break;
    default:
        dprintk("Invalid op->type[%d]\n", op->type);
        ASSERT(0);
    }

    return ptr - buf;
}
Exemple #14
0
int make_condition (char *argv, CONDITION **head)
{
  const char *delim="<>=!";
  
  int i,j;
  int op_id;
  CONDITION *new_condition;
  char *var;
  char *op;
  char *val;
  
  *head=NULL;
  
  j=0;
  while (argv[j])
  {
    for (i=j;argv[j] && isspace(argv[j]);j++);
    for (i=j;argv[j] && !isspace(argv[j]) && !strchr(delim,argv[j]);j++);
    if (i==j)
    {
      printf ("Error: undefined argument\n");
      return -1;
    }
    var=mem2str(argv+i, j-i);
    if ((xstrcmpi(var,"AND"))==0)
    {
      free (var);
      continue;
    }
    
    for (i=j;argv[j] && isspace(argv[j]);j++);
    for (i=j;argv[j] && strchr(delim,argv[j]) ;j++);
    if (i==j)
    {
      printf ("error: undefined operator for the argument ‘%s’\n",var);    
      free (var);
      return -1;
    }
    op=mem2str(argv+i, j-i);
    if ((op_id=check_op (op,var))<0)
    {
      free (var);
      free (op);
      return -1;
    }
    
    for (i=j;argv[j] && isspace(argv[j]);j++);
    if (argv[j]=='\'')
    {
      for (i=++j;argv[j] && argv[j]!='\'';j++);
      if (!argv[j])
      {
        printf ("Error: unclosed single quote\n");
        free (var);
        free (op);
        return -1;
      }
    }
    else 
      for (i=j;argv[j] && !isspace(argv[j]);j++);
      
    if (i==j)
    {
      printf ("error: undefined value for the argument ‘%s %s’\n",var,op);    
      free (var);
      free (op);
      return -1;
    }
    val=mem2str(argv+i, j-i);
    if (argv[j]=='\'') 
      j++;
    
    for (i=j;argv[j] && isspace(argv[j]);j++);
    
    if ((new_condition=xmalloc (sizeof(CONDITION)))==NULL)
      return -1;
    
    new_condition->var=var;
    new_condition->var_id=0;
    new_condition->op=op;
    new_condition->op_id=op_id;
    new_condition->val=val;
    new_condition->next=*head;
    
    *head=new_condition;
   
  }
  return 0;
}
Exemple #15
0
static int
decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
{
  decode_filter_ctx_t fc = opaque;
  size_t size = *ret_len;
  size_t n;
  int c, rc = 0;


  if ( control == IOBUFCTRL_UNDERFLOW && fc->eof_seen )
    {
      *ret_len = 0;
      rc = -1;
    }
  else if ( control == IOBUFCTRL_UNDERFLOW )
    {
      log_assert (a);

      if (fc->partial)
        {
          for (n=0; n < size; n++ )
            {
              c = iobuf_get(a);
              if (c == -1)
                {
                  fc->eof_seen = 1; /* Normal EOF. */
                  break;
                }
              buf[n] = c;
            }
        }
      else
        {
          for (n=0; n < size && fc->length; n++, fc->length--)
            {
              c = iobuf_get(a);
              if (c == -1)
                {
                  fc->eof_seen = 3; /* Premature EOF. */
                  break;
                }
              buf[n] = c;
            }
          if (!fc->length)
            fc->eof_seen = 1; /* Normal EOF.  */
        }
      if (n)
        {
          if (fc->cipher_hd)
            gcry_cipher_decrypt (fc->cipher_hd, buf, n, NULL, 0);
        }
      else
        {
          if (!fc->eof_seen)
            fc->eof_seen = 1;
          rc = -1; /* Return EOF. */
        }
      *ret_len = n;
    }
  else if ( control == IOBUFCTRL_FREE )
    {
      release_dfx_context (fc);
    }
  else if ( control == IOBUFCTRL_DESC )
    {
      mem2str (buf, "decode_filter", *ret_len);
    }
  return rc;
}
Exemple #16
0
static int
mdc_decode_filter (void *opaque, int control, IOBUF a,
                   byte *buf, size_t *ret_len)
{
  decode_filter_ctx_t dfx = opaque;
  size_t n, size = *ret_len;
  int rc = 0;
  int c;

  /* Note: We need to distinguish between a partial and a fixed length
     packet.  The first is the usual case as created by GPG.  However
     for short messages the format degrades to a fixed length packet
     and other implementations might use fixed length as well.  Only
     looking for the EOF on fixed data works only if the encrypted
     packet is not followed by other data.  This used to be a long
     standing bug which was fixed on 2009-10-02.  */

  if ( control == IOBUFCTRL_UNDERFLOW && dfx->eof_seen )
    {
      *ret_len = 0;
      rc = -1;
    }
  else if( control == IOBUFCTRL_UNDERFLOW )
    {
      log_assert (a);
      log_assert (size > 44); /* Our code requires at least this size.  */

      /* Get at least 22 bytes and put it ahead in the buffer.  */
      if (dfx->partial)
        {
          for (n=22; n < 44; n++)
            {
              if ( (c = iobuf_get(a)) == -1 )
                break;
              buf[n] = c;
            }
        }
      else
        {
          for (n=22; n < 44 && dfx->length; n++, dfx->length--)
            {
              c = iobuf_get (a);
              if (c == -1)
                break; /* Premature EOF.  */
              buf[n] = c;
            }
        }
      if (n == 44)
        {
          /* We have enough stuff - flush the deferred stuff.  */
          if ( !dfx->defer_filled )  /* First time. */
            {
              memcpy (buf, buf+22, 22);
              n = 22;
	    }
          else
            {
              memcpy (buf, dfx->defer, 22);
	    }
          /* Fill up the buffer. */
          if (dfx->partial)
            {
              for (; n < size; n++ )
                {
                  if ( (c = iobuf_get(a)) == -1 )
                    {
                      dfx->eof_seen = 1; /* Normal EOF. */
                      break;
                    }
                  buf[n] = c;
                }
            }
          else
            {
              for (; n < size && dfx->length; n++, dfx->length--)
                {
                  c = iobuf_get(a);
                  if (c == -1)
                    {
                      dfx->eof_seen = 3; /* Premature EOF. */
                      break;
                    }
                  buf[n] = c;
                }
              if (!dfx->length)
                dfx->eof_seen = 1; /* Normal EOF.  */
            }

          /* Move the trailing 22 bytes back to the defer buffer.  We
             have at least 44 bytes thus a memmove is not needed.  */
          n -= 22;
          memcpy (dfx->defer, buf+n, 22 );
          dfx->defer_filled = 1;
	}
      else if ( !dfx->defer_filled )  /* EOF seen but empty defer buffer. */
        {
          /* This is bad because it means an incomplete hash. */
          n -= 22;
          memcpy (buf, buf+22, n );
          dfx->eof_seen = 2; /* EOF with incomplete hash.  */
	}
      else  /* EOF seen (i.e. read less than 22 bytes). */
        {
          memcpy (buf, dfx->defer, 22 );
          n -= 22;
          memcpy (dfx->defer, buf+n, 22 );
          dfx->eof_seen = 1; /* Normal EOF. */
	}

      if ( n )
        {
          if ( dfx->cipher_hd )
            gcry_cipher_decrypt (dfx->cipher_hd, buf, n, NULL, 0);
          if ( dfx->mdc_hash )
            gcry_md_write (dfx->mdc_hash, buf, n);
	}
      else
        {
          log_assert ( dfx->eof_seen );
          rc = -1; /* Return EOF.  */
	}
      *ret_len = n;
    }
  else if ( control == IOBUFCTRL_FREE )
    {
      release_dfx_context (dfx);
    }
  else if ( control == IOBUFCTRL_DESC )
    {
      mem2str (buf, "mdc_decode_filter", *ret_len);
    }
  return rc;
}
Exemple #17
0
/*
 * Filter to do a complete public key encryption.
 */
int
encrypt_filter (void *opaque, int control,
                iobuf_t a, byte *buf, size_t *ret_len)
{
  size_t size = *ret_len;
  encrypt_filter_context_t *efx = opaque;
  int rc = 0;

  if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */
    {
      BUG(); /* not used */
    }
  else if ( control == IOBUFCTRL_FLUSH ) /* encrypt */
    {
      if ( !efx->header_okay )
        {
          efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek );
          if ( !opt.def_cipher_algo  )
            {
              /* Try to get it from the prefs. */
              efx->cfx.dek->algo =
                select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL);
              if (efx->cfx.dek->algo == -1 )
                {
                  /* Because 3DES is implicitly in the prefs, this can
                     only happen if we do not have any public keys in
                     the list.  */
                  efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO;
                }

              /* In case 3DES has been selected, print a warning if
                 any key does not have a preference for AES.  This
                 should help to indentify why encrypting to several
                 recipients falls back to 3DES. */
              if (opt.verbose
                  && efx->cfx.dek->algo == CIPHER_ALGO_3DES)
                warn_missing_aes_from_pklist (efx->pk_list);
	    }
          else
            {
	      if (!opt.expert
                  && select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM,
                                             opt.def_cipher_algo,
                                             NULL) != opt.def_cipher_algo)
		log_info(_("forcing symmetric cipher %s (%d) "
			   "violates recipient preferences\n"),
			 openpgp_cipher_algo_name (opt.def_cipher_algo),
			 opt.def_cipher_algo);

	      efx->cfx.dek->algo = opt.def_cipher_algo;
	    }

          efx->cfx.dek->use_aead = use_aead (efx->pk_list, efx->cfx.dek->algo);
          if (!efx->cfx.dek->use_aead)
            efx->cfx.dek->use_mdc = !!use_mdc (efx->pk_list,efx->cfx.dek->algo);

          make_session_key ( efx->cfx.dek );
          if (DBG_CRYPTO)
            log_printhex (efx->cfx.dek->key, efx->cfx.dek->keylen, "DEK is: ");

          rc = write_pubkey_enc_from_list (efx->ctrl,
                                           efx->pk_list, efx->cfx.dek, a);
          if (rc)
            return rc;

          if(efx->symkey_s2k && efx->symkey_dek)
            {
              rc = write_symkey_enc (efx->symkey_s2k, efx->cfx.dek->use_aead,
                                     efx->symkey_dek, efx->cfx.dek, a);
              if (rc)
                return rc;
            }

          iobuf_push_filter (a,
                             efx->cfx.dek->use_aead? cipher_filter_aead
                             /**/                  : cipher_filter_cfb,
                             &efx->cfx);

          efx->header_okay = 1;
        }
      rc = iobuf_write (a, buf, size);

    }
  else if (control == IOBUFCTRL_FREE)
    {
      xfree (efx->symkey_dek);
      xfree (efx->symkey_s2k);
    }
  else if ( control == IOBUFCTRL_DESC )
    {
      mem2str (buf, "encrypt_filter", *ret_len);
    }
  return rc;
}