void print_file_info(HANDLE hOut, BY_HANDLE_FILE_INFORMATION & bhfi, const wchar_t * filename) { char output[2048]; BprintBuffer<char> bp(output, NUMELMS(output), hOut); //char * pout = output; //if (label_output) bp.append("LINKS: "); //bp.append_num(bhfi.nNumberOfLinks); //if (label_output) bp.append(" INDEX:"); char numbuf[64], *p = numbuf; if (hex_filenumber) p = append(p, "0x", &numbuf[64]); if (quad_filenumber) { if (hex_filenumber) { append_hex(p, _qword(bhfi.nFileIndexLow, bhfi.nFileIndexHigh)); } else { append_num(p, _qword(bhfi.nFileIndexLow, bhfi.nFileIndexHigh)); } } else if (wide_filenumber) { if (hex_filenumber) { p = append_hex(p, bhfi.nFileIndexHigh, 2); p = append(p, ".", &numbuf[64]); p = append_hex(p, bhfi.nFileIndexLow, 8); } else { p = append_num(p, bhfi.nFileIndexHigh, false, 2, '0'); p = append(p, ".", &numbuf[64]); p = append_num(p, bhfi.nFileIndexLow, false, 9, '0'); } } else { unsigned __int64 id = _qword(bhfi.nFileIndexLow, bhfi.nFileIndexHigh); unsigned int sect = bhfi.nFileIndexHigh >> 16; id &= 0xFFFFFFFFFFFFull; if (hex_filenumber) { p = append_hex(p, sect, 2); p = append(p, ".", &numbuf[64]); p = append_hex(p, id, 6); } else { p = append_num(p, sect, false, 2, '0'); p = append(p, ".", &numbuf[64]); p = append_num(p, id, false, 7, '0'); } } //if (label_output) bp.append(" NAME:"); //*pout++ = ' '; ULONG_PTR vargs[] = { bhfi.nNumberOfLinks, (ULONG_PTR)(char*)numbuf, (ULONG_PTR)filename }; bp.vformatl(label_output ? "LINKS: {0:d} INDEX: {1} NAME: {2:w}" : " {0:d} {1} {2:w}", NUMELMS(vargs), vargs); //char * pend = output+sizeof(output)-6; //while (pout < pend && *filename) { *pout++ = (char)*filename++; } //if (*filename) bp.append("..."); //bp.EndLine(false); if ( ! bp.Write()) ExitProcess(GetLastError()); }
std::string encode(const traits& ts, const std::string& comp) { std::string::const_iterator f = comp.begin(); std::string::const_iterator anchor = f; std::string s; for (; f != comp.end();) { char c = *f; if (ts.char_class[(unsigned char)c] < CVAL || c == ENCODE_BEGIN_CHAR) { // Must encode. s.append(anchor, f); // Catch up to this char. s.append(1, ENCODE_BEGIN_CHAR); append_hex(c, s); // Convert. anchor = ++f; } else ++f; } return (anchor == comp.begin()) ? comp : s.append(f, comp.end()); }
static krb5_error_code entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) { char *p; size_t i; krb5_error_code ret; /* --- principal */ ret = krb5_unparse_name(context, ent->principal, &p); if(ret) return ret; append_string(context, sp, "%s ", p); free(p); /* --- kvno */ append_string(context, sp, "%d", ent->kvno); /* --- keys */ for(i = 0; i < ent->keys.len; i++){ /* --- mkvno, keytype */ if(ent->keys.val[i].mkvno) append_string(context, sp, ":%d:%d:", *ent->keys.val[i].mkvno, ent->keys.val[i].key.keytype); else append_string(context, sp, "::%d:", ent->keys.val[i].key.keytype); /* --- keydata */ append_hex(context, sp, &ent->keys.val[i].key.keyvalue); append_string(context, sp, ":"); /* --- salt */ if(ent->keys.val[i].salt){ append_string(context, sp, "%u/", ent->keys.val[i].salt->type); append_hex(context, sp, &ent->keys.val[i].salt->salt); }else append_string(context, sp, "-"); } append_string(context, sp, " "); /* --- created by */ append_event(context, sp, &ent->created_by); /* --- modified by */ append_event(context, sp, ent->modified_by); /* --- valid start */ if(ent->valid_start) append_string(context, sp, "%s ", time2str(*ent->valid_start)); else append_string(context, sp, "- "); /* --- valid end */ if(ent->valid_end) append_string(context, sp, "%s ", time2str(*ent->valid_end)); else append_string(context, sp, "- "); /* --- password ends */ if(ent->pw_end) append_string(context, sp, "%s ", time2str(*ent->pw_end)); else append_string(context, sp, "- "); /* --- max life */ if(ent->max_life) append_string(context, sp, "%d ", *ent->max_life); else append_string(context, sp, "- "); /* --- max renewable life */ if(ent->max_renew) append_string(context, sp, "%d ", *ent->max_renew); else append_string(context, sp, "- "); /* --- flags */ append_string(context, sp, "%d ", HDBFlags2int(ent->flags)); /* --- generation number */ if(ent->generation) { append_string(context, sp, "%s:%d:%d ", time2str(ent->generation->time), ent->generation->usec, ent->generation->gen); } else append_string(context, sp, "- "); /* --- extensions */ if(ent->extensions && ent->extensions->len > 0) { for(i = 0; i < ent->extensions->len; i++) { void *d; size_t size, sz = 0; ASN1_MALLOC_ENCODE(HDB_extension, d, size, &ent->extensions->val[i], &sz, ret); if (ret) { krb5_clear_error_message(context); return ret; } if(size != sz) krb5_abortx(context, "internal asn.1 encoder error"); if (hex_encode(d, size, &p) < 0) { free(d); krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } free(d); append_string(context, sp, "%s%s", p, ent->extensions->len - 1 != i ? ":" : ""); free(p); } } else append_string(context, sp, "-"); return 0; }
krb5_error_code entry2mit_string_int(krb5_context context, krb5_storage *sp, hdb_entry *ent) { krb5_error_code ret; ssize_t sz; size_t i, k; size_t num_tl_data = 0; size_t num_key_data = 0; char *p; HDB_Ext_KeySet *hist_keys = NULL; HDB_extension *extp; time_t last_pw_chg = 0; time_t exp = 0; time_t pwexp = 0; unsigned int max_life = 0; unsigned int max_renew = 0; if (ent->modified_by) num_tl_data++; ret = hdb_entry_get_pw_change_time(ent, &last_pw_chg); if (ret) return ret; if (last_pw_chg) num_tl_data++; extp = hdb_find_extension(ent, choice_HDB_extension_data_hist_keys); if (extp) hist_keys = &extp->data.u.hist_keys; for (i = 0; i < ent->keys.len;i++) { if (ent->keys.val[i].key.keytype == ETYPE_DES_CBC_MD4 || ent->keys.val[i].key.keytype == ETYPE_DES_CBC_MD5) continue; num_key_data++; } if (hist_keys) { for (i = 0; i < hist_keys->len; i++) { /* * MIT uses the highest kvno as the current kvno instead of * tracking kvno separately, so we can't dump keysets with kvno * higher than the entry's kvno. */ if (hist_keys->val[i].kvno >= ent->kvno) continue; for (k = 0; k < hist_keys->val[i].keys.len; k++) { if (ent->keys.val[k].key.keytype == ETYPE_DES_CBC_MD4 || ent->keys.val[k].key.keytype == ETYPE_DES_CBC_MD5) continue; num_key_data++; } } } ret = krb5_unparse_name(context, ent->principal, &p); if (ret) return ret; sz = append_string(context, sp, "princ\t38\t%u\t%u\t%u\t0\t%s\t%d", strlen(p), num_tl_data, num_key_data, p, flags_to_attr(ent->flags)); free(p); if (sz == -1) return ENOMEM; if (ent->max_life) max_life = *ent->max_life; if (ent->max_renew) max_renew = *ent->max_renew; if (ent->valid_end) exp = *ent->valid_end; if (ent->pw_end) pwexp = *ent->pw_end; sz = append_string(context, sp, "\t%u\t%u\t%u\t%u\t0\t0\t0", max_life, max_renew, exp, pwexp); if (sz == -1) return ENOMEM; /* Dump TL data we know: last pw chg and modified_by */ #define mit_KRB5_TL_LAST_PWD_CHANGE 1 #define mit_KRB5_TL_MOD_PRINC 2 if (last_pw_chg) { krb5_data d; time_t val; unsigned char *ptr; ptr = (unsigned char *)&last_pw_chg; val = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); d.data = &val; d.length = sizeof (last_pw_chg); sz = append_string(context, sp, "\t%u\t%u\t", mit_KRB5_TL_LAST_PWD_CHANGE, d.length); if (sz == -1) return ENOMEM; sz = append_hex(context, sp, 1, 1, &d); if (sz == -1) return ENOMEM; } if (ent->modified_by) { krb5_data d; unsigned int val; size_t plen; unsigned char *ptr; char *modby_p; ptr = (unsigned char *)&ent->modified_by->time; val = ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24); d.data = &val; d.length = sizeof (ent->modified_by->time); ret = krb5_unparse_name(context, ent->modified_by->principal, &modby_p); if (ret) return ret; plen = strlen(modby_p); sz = append_string(context, sp, "\t%u\t%u\t", mit_KRB5_TL_MOD_PRINC, d.length + plen + 1 /* NULL counted */); if (sz == -1) return ENOMEM; sz = append_hex(context, sp, 1, 1, &d); if (sz == -1) { free(modby_p); return ENOMEM; } d.data = modby_p; d.length = plen + 1; sz = append_hex(context, sp, 1, 1, &d); free(modby_p); if (sz == -1) return ENOMEM; } /* * Dump keys (remembering to not include any with kvno higher than * the entry's because MIT doesn't track entry kvno separately from * the entry's keys -- max kvno is it) */ for (i = 0; i < ent->keys.len; i++) { if (ent->keys.val[i].key.keytype == ETYPE_DES_CBC_MD4 || ent->keys.val[i].key.keytype == ETYPE_DES_CBC_MD5) continue; sz = append_mit_key(context, sp, ent->principal, ent->kvno, &ent->keys.val[i]); if (sz == -1) return ENOMEM; } for (i = 0; hist_keys && i < ent->kvno; i++) { size_t m; /* dump historical keys */ for (k = 0; k < hist_keys->len; k++) { if (hist_keys->val[k].kvno != ent->kvno - i) continue; for (m = 0; m < hist_keys->val[k].keys.len; m++) { if (ent->keys.val[k].key.keytype == ETYPE_DES_CBC_MD4 || ent->keys.val[k].key.keytype == ETYPE_DES_CBC_MD5) continue; sz = append_mit_key(context, sp, ent->principal, hist_keys->val[k].kvno, &hist_keys->val[k].keys.val[m]); if (sz == -1) return ENOMEM; } } } sz = append_string(context, sp, "\t-1;"); /* "extra data" */ if (sz == -1) return ENOMEM; return 0; }
static ssize_t append_mit_key(krb5_context context, krb5_storage *sp, krb5_const_principal princ, unsigned int kvno, Key *key) { krb5_error_code ret; krb5_salt k5salt; ssize_t sz; size_t key_versions = key->salt ? 2 : 1; size_t decrypted_key_length; char buf[2]; krb5_data keylenbytes; unsigned int salttype; sz = append_string(context, sp, "\t%u\t%u\t%d\t%d\t", key_versions, kvno, key->key.keytype, key->key.keyvalue.length + 2); if (sz == -1) return sz; ret = krb5_enctype_keysize(context, key->key.keytype, &decrypted_key_length); if (ret) return -1; /* XXX we lose the error code */ buf[0] = decrypted_key_length & 0xff; buf[1] = (decrypted_key_length & 0xff00) >> 8; keylenbytes.data = buf; keylenbytes.length = sizeof (buf); sz = append_hex(context, sp, 1, 1, &keylenbytes); if (sz == -1) return sz; sz = append_hex(context, sp, 1, 1, &key->key.keyvalue); if (!key->salt) return sz; /* Map salt to MIT KDB style */ switch (key->salt->type) { case KRB5_PADATA_PW_SALT: /* * Compute normal salt and then see whether it matches the stored one */ ret = krb5_get_pw_salt(context, princ, &k5salt); if (ret) return -1; if (k5salt.saltvalue.length == key->salt->salt.length && memcmp(k5salt.saltvalue.data, key->salt->salt.data, k5salt.saltvalue.length) == 0) salttype = KRB5_KDB_SALTTYPE_NORMAL; /* matches */ else if (key->salt->salt.length == strlen(princ->realm) && memcmp(key->salt->salt.data, princ->realm, key->salt->salt.length) == 0) salttype = KRB5_KDB_SALTTYPE_ONLYREALM; /* matches realm */ else if (key->salt->salt.length == k5salt.saltvalue.length - strlen(princ->realm) && memcmp((char *)k5salt.saltvalue.data + strlen(princ->realm), key->salt->salt.data, key->salt->salt.length) == 0) salttype = KRB5_KDB_SALTTYPE_NOREALM; /* matches w/o realm */ else salttype = KRB5_KDB_SALTTYPE_NORMAL; /* hope for best */ break; case KRB5_PADATA_AFS3_SALT: salttype = KRB5_KDB_SALTTYPE_AFS3; break; default: return -1; } sz = append_string(context, sp, "\t%u\t%u\t", salttype, key->salt->salt.length); if (sz == -1) return sz; return append_hex(context, sp, 1, 1, &key->salt->salt); }
static krb5_error_code entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) { char *p; int i; krb5_error_code ret; /* --- principal */ ret = krb5_unparse_name(context, ent->principal, &p); if(ret) return ret; append_string(context, sp, "%s ", p); free(p); /* --- kvno */ append_string(context, sp, "%d", ent->kvno); /* --- keys */ for(i = 0; i < ent->keys.len; i++){ /* --- mkvno, keytype */ if(ent->keys.val[i].mkvno) append_string(context, sp, ":%d:%d:", *ent->keys.val[i].mkvno, ent->keys.val[i].key.keytype); else append_string(context, sp, "::%d:", ent->keys.val[i].key.keytype); /* --- keydata */ append_hex(context, sp, &ent->keys.val[i].key.keyvalue); append_string(context, sp, ":"); /* --- salt */ if(ent->keys.val[i].salt){ append_string(context, sp, "%u/", ent->keys.val[i].salt->type); append_hex(context, sp, &ent->keys.val[i].salt->salt); }else append_string(context, sp, "-"); } append_string(context, sp, " "); /* --- created by */ append_event(context, sp, &ent->created_by); /* --- modified by */ append_event(context, sp, ent->modified_by); /* --- valid start */ if(ent->valid_start) append_string(context, sp, "%s ", time2str(*ent->valid_start)); else append_string(context, sp, "- "); /* --- valid end */ if(ent->valid_end) append_string(context, sp, "%s ", time2str(*ent->valid_end)); else append_string(context, sp, "- "); /* --- password ends */ if(ent->pw_end) append_string(context, sp, "%s ", time2str(*ent->pw_end)); else append_string(context, sp, "- "); /* --- max life */ if(ent->max_life) append_string(context, sp, "%d ", *ent->max_life); else append_string(context, sp, "- "); /* --- max renewable life */ if(ent->max_renew) append_string(context, sp, "%d ", *ent->max_renew); else append_string(context, sp, "- "); /* --- flags */ append_string(context, sp, "%d ", HDBFlags2int(ent->flags)); /* --- generation number */ if(ent->generation) { append_string(context, sp, "%s:%d:%d", time2str(ent->generation->time), ent->generation->usec, ent->generation->gen); } else append_string(context, sp, "-"); return 0; }