def _read_header(self, stream): """ Parse the header and write the values into self.header. Also sets self.header_length. """ # KeePass 2.07 has version 1.01, # 2.08 has 1.02, # 2.09 has 2.00, 2.10 has 2.02, 2.11 has 2.04, # 2.15 has 3.00. # The first 2 bytes are critical (i.e. loading will fail, if the # file version is too high), the last 2 bytes are informational. #TODO implement version check # the first header field starts at byte 12 after the signature stream.seek(12) while True: # field_id is a single byte field_id = stream_unpack(stream, None, 1, 'b') # field_id >10 is undefined if not field_id in self.header.fields.values(): raise IOError('Unknown header field found.') # two byte (short) length of field data length = stream_unpack(stream, None, 2, 'h') if length > 0: data = stream_unpack(stream, None, length, '{}s'.format(length)) self.header.b[field_id] = data # set position in data stream of end of header if field_id == 0: self.header_length = stream.tell() break
def _read_header(self, stream): """ Parses the header and write the values into self.header. Also sets self.header_length. """ # kdb3 has a fixed header length self.header_length = 124 # skip file signature stream.seek(8) field_id = 0 while True: length = self.header.lengths[field_id] data = stream_unpack(stream, None, length, '{}s'.format(length)) self.header.b[field_id] = data field_id += 1 if field_id > 8: break # this is impossible, as long as noone messes with self.header.lengths if self.header_length != stream.tell(): raise IOError('Unexpected header length! What did you do!?')