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"); }
/* 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 (); }
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; }
/* 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; }
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; }
/**************** * 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; }
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 */ }
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); }
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); }
/**************** * 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; }
/* * 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; }
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; }
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; }
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; }
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; }
/* * 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; }