hash_stat hash_plugin_parse_hash(char *hashline, char *filename) { FILE *fp; unsigned char buf[1024]; long size, offset = 0; size_t i, j; uint32_t n; if (!(fp = fopen(filename, "rb"))) { //fprintf(stderr, "%s : %s\n", filename, strerror(errno)); return hash_err; } fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); count = fread(buf, KWMAGIC_LEN, 1, fp); if (memcmp(buf, KWMAGIC, KWMAGIC_LEN) != 0) { //fprintf(stderr, "%s : Not a KDE KWallet file!\n", filename); goto bail; } offset += KWMAGIC_LEN; count = fread(buf, 4, 1, fp); offset += 4; /* First byte is major version, second byte is minor version */ if (buf[0] != KWALLET_VERSION_MAJOR) { //fprintf(stderr, "%s : Unknown version!\n", filename); goto bail; } if (buf[1] != KWALLET_VERSION_MINOR) { //fprintf(stderr, "%s : Unknown version!\n", filename); goto bail; } if (buf[2] != KWALLET_CIPHER_BLOWFISH_CBC) { //fprintf(stderr, "%s : Unsupported cipher\n", filename); goto bail; } if (buf[3] != KWALLET_HASH_SHA1) { //fprintf(stderr, "%s : Unsupported hash\n", filename); goto bail; } /* Read in the hashes */ n = fget32_(fp); if (n > 0xffff) { //fprintf(stderr, "%s : sanity check failed!\n", filename); goto bail; } offset += 4; for (i = 0; i < n; ++i) { uint32_t fsz; count = fread(buf, 16, 1, fp); offset += 16; fsz = fget32_(fp); offset += 4; for (j = 0; j < fsz; ++j) { count = fread(buf, 16, 1, fp); offset += 16; } } /* Read in the rest of the file. */ encrypted_size = size - offset; count = fread(cs.ct, encrypted_size, 1, fp); if ((encrypted_size % 8) != 0) { //fprintf(stderr, "%s : invalid file structure!\n", filename); return hash_err; } fclose(fp); cs.ctlen = encrypted_size; (void) hash_add_username(filename); (void) hash_add_hash("KDE KWallet file \0", 0); (void) hash_add_salt("123"); (void) hash_add_salt2(" "); return hash_ok; bail: fclose(fp); return hash_err; }
static void get_uint32(FILE * fp, int *next_offset, uint32_t * val) { *val = fget32_(fp); *next_offset = *next_offset + 4; }
static void process_file(const char *fname) { FILE *fp; unsigned char buf[1024]; long size, offset = 0; size_t i, j; uint32_t n; const char *extension[]={".kwl"}; char *bname; if (!(fp = fopen(fname, "rb"))) { fprintf(stderr, "%s : %s\n", fname, strerror(errno)); return; } fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); count = fread(buf, KWMAGIC_LEN, 1, fp); if (memcmp(buf, KWMAGIC, KWMAGIC_LEN) != 0) { fprintf(stderr, "%s : Not a KDE KWallet file!\n", fname); exit(1); } offset += KWMAGIC_LEN; count = fread(buf, 4, 1, fp); offset += 4; /* First byte is major version, second byte is minor version */ if (buf[0] != KWALLET_VERSION_MAJOR) { fprintf(stderr, "%s : Unknown version!\n", fname); exit(2); } if (buf[1] != KWALLET_VERSION_MINOR) { fprintf(stderr, "%s : Unknown version!\n", fname); exit(3); } if (buf[2] != KWALLET_CIPHER_BLOWFISH_CBC) { fprintf(stderr, "%s : Unsupported cipher\n", fname); exit(4); } if (buf[3] != KWALLET_HASH_SHA1) { fprintf(stderr, "%s : Unsupported hash\n", fname); exit(5); } /* Read in the hashes */ n = fget32_(fp); if (n > 0xffff) { fprintf(stderr, "%s : sanity check failed!\n", fname); exit(6); } offset += 4; for (i = 0; i < n; ++i) { uint32_t fsz; count = fread(buf, 16, 1, fp); offset += 16; fsz = fget32_(fp); offset += 4; for (j = 0; j < fsz; ++j) { count = fread(buf, 16, 1, fp); offset += 16; } } /* Read in the rest of the file. */ encrypted_size = size - offset; count = fread(encrypted, encrypted_size, 1, fp); if ((encrypted_size % 8) != 0) { fprintf(stderr, "%s : invalid file structure!\n", fname); exit(7); } bname = strip_suffixes(basename(fname), extension, 1); printf("%s:$kwallet$%ld$", bname, encrypted_size); print_hex(encrypted, encrypted_size); printf(":::::%s\n", fname); fclose(fp); }