/// <summary> /// Reads the next part of the database. /// </summary> /// <returns>true if there was a next part</returns> public bool Read() { if (_error) { throw new InvalidOperationException("An error has already been reported."); } if (CurrentPartType == PasswordSafePartType.None) { _error = true; throw new InvalidOperationException("No passphrase set"); } if (CurrentPartType == PasswordSafePartType.End) { return(false); } if (CurrentPartType == PasswordSafePartType.Keys) { Header = ReadHeader(); if (Header != null) { CurrentPartType = PasswordSafePartType.Header; return(true); } return(false); } if (CurrentPartType == PasswordSafePartType.Header || CurrentPartType == PasswordSafePartType.Record) { Record = ReadRecord(); if (Record != null) { CurrentPartType = PasswordSafePartType.Record; return(true); } } ReadHmac(); CurrentPartType = PasswordSafePartType.End; return(true); }
/// <summary> /// Reads one data record. /// </summary> /// <returns>The record</returns> private PasswordSafeRecord ReadRecord() { var fields = ReadGenericRecord(); if (fields == null) { return(null); } var record = new PasswordSafeRecord(); var endSeen = false; foreach (var field in fields) { if (endSeen) { throw new InvalidDataException("The END filed must be last in the header"); } var data = field.DataBuffer(); switch ((PasswordSafeRecordTypeCode)field.Type) { case PasswordSafeRecordTypeCode.NAME: throw new InvalidDataException("The NAME field type is not allowed here."); case PasswordSafeRecordTypeCode.UUID: if (data.Length != 16) { throw new InvalidDataException("UUID field length wrong"); } record.Uuid = new Guid(data); break; case PasswordSafeRecordTypeCode.GROUP: record.Group = Encoding.UTF8.GetString(data, 0, data.Length); //.UTF8.GetString(data,0,data.Length); break; case PasswordSafeRecordTypeCode.TITLE: record.Title = Encoding.UTF8.GetString(data, 0, data.Length); break; case PasswordSafeRecordTypeCode.USER: record.User = Encoding.UTF8.GetString(data, 0, data.Length); break; case PasswordSafeRecordTypeCode.NOTES: record.Notes = Encoding.UTF8.GetString(data, 0, data.Length); break; case PasswordSafeRecordTypeCode.PASSWORD: record.PasswordValue = Encoding.UTF8.GetString(data, 0, data.Length); break; case PasswordSafeRecordTypeCode.CTIME: record.TimeRecordCreatedUtc = GetUtcFromUnixTime(data); break; case PasswordSafeRecordTypeCode.PMTIME: record.TimePasswordModifiedUtc = GetUtcFromUnixTime(data); break; case PasswordSafeRecordTypeCode.ATIME: record.TimeRecordAccessedUtc = GetUtcFromUnixTime(data); break; case PasswordSafeRecordTypeCode.LTIME: record.TimePasswordExpiresUtc = GetUtcFromUnixTime(data); break; case PasswordSafeRecordTypeCode.POLICY: throw new InvalidDataException("The POLICY field type is not allowed here."); case PasswordSafeRecordTypeCode.RMTIME: record.TimeRecordModifiedUtc = GetUtcFromUnixTime(data); break; case PasswordSafeRecordTypeCode.URL: record.ResourceLocator = Encoding.UTF8.GetString(data, 0, data.Length); break; case PasswordSafeRecordTypeCode.AUTOTYPE: record.AutoType = Encoding.UTF8.GetString(data, 0, data.Length); break; case PasswordSafeRecordTypeCode.PWHIST: var serializedHistory = Encoding.UTF8.GetString(data, 0, data.Length); record.PasswordHistory = PasswordSafePasswordHistory.Parse(serializedHistory); break; case PasswordSafeRecordTypeCode.END: endSeen = true; break; default: record.UnknownFieldEntriesAdd(field); break; } } return(record); }