Exemple #1
0
		public static bool IsLibraryInstalled(out Exception ex)
		{
			try
			{
				KdbManager mgr = new KdbManager();
				mgr.Dispose();
			}
			catch(Exception exMgr)
			{
				ex = exMgr;
				return false;
			}

			ex = null;
			return true;
		}
Exemple #2
0
		private static KdbErrorCode SetDatabaseKey(KdbManager mgr, CompositeKey pwKey)
		{
			KdbErrorCode e;

			bool bPassword = pwKey.ContainsType(typeof(KcpPassword));
			bool bKeyFile = pwKey.ContainsType(typeof(KcpKeyFile));

			string strPassword = (bPassword ? (pwKey.GetUserKey(
				typeof(KcpPassword)) as KcpPassword).Password.ReadString() : string.Empty);
			string strKeyFile = (bKeyFile ? (pwKey.GetUserKey(
				typeof(KcpKeyFile)) as KcpKeyFile).Path : string.Empty);

			if(bPassword && bKeyFile)
				e = mgr.SetMasterKey(strKeyFile, true, strPassword, IntPtr.Zero, false);
			else if(bPassword && !bKeyFile)
				e = mgr.SetMasterKey(strPassword, false, null, IntPtr.Zero, false);
			else if(!bPassword && bKeyFile)
				e = mgr.SetMasterKey(strKeyFile, true, null, IntPtr.Zero, false);
			else if(pwKey.ContainsType(typeof(KcpUserAccount)))
				throw new Exception(KPRes.KdbWUA);
			else throw new Exception(KLRes.InvalidCompositeKey);

			return e;
		}
Exemple #3
0
		private void WriteEntries(KdbManager mgr, Dictionary<PwGroup, uint> dictGroups,
			PwGroup pgRoot)
		{
			bool bWarnedOnce = false;
			uint uGroupCount, uEntryCount, uEntriesSaved = 0;
			pgRoot.GetCounts(true, out uGroupCount, out uEntryCount);

			DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();

			EntryHandler eh = delegate(PwEntry pe)
			{
				KdbEntry e = new KdbEntry();

				e.Uuid.Set(pe.Uuid.UuidBytes);

				if(pe.ParentGroup != pgRoot)
					e.GroupId = dictGroups[pe.ParentGroup];
				else
				{
					e.GroupId = 1;
					if((m_slLogger != null) && !bWarnedOnce)
					{
						m_slLogger.SetText(KdbPrefix +
							KPRes.FormatNoRootEntries, LogStatusType.Warning);
						bWarnedOnce = true;
					}

					if(dictGroups.Count == 0)
						throw new Exception(KPRes.FormatNoSubGroupsInRoot);
				}

				e.ImageId = (uint)pe.IconId;

				e.Title = pe.Strings.ReadSafe(PwDefs.TitleField);
				e.UserName = pe.Strings.ReadSafe(PwDefs.UserNameField);
				e.Password = pe.Strings.ReadSafe(PwDefs.PasswordField);
				e.Url = pe.Strings.ReadSafe(PwDefs.UrlField);

				string strNotes = pe.Strings.ReadSafe(PwDefs.NotesField);
				ExportCustomStrings(pe, ref strNotes);
				ExportAutoType(pe, ref strNotes);
				ExportUrlOverride(pe, ref strNotes);
				e.Additional = strNotes;

				e.PasswordLength = (uint)e.Password.Length;

				Debug.Assert(TimeUtil.PwTimeLength == 7);
				e.CreationTime.Set(pe.CreationTime);
				e.LastModificationTime.Set(pe.LastModificationTime);
				e.LastAccessTime.Set(pe.LastAccessTime);

				if(pe.Expires) e.ExpirationTime.Set(pe.ExpiryTime);
				else e.ExpirationTime.Set(dtNeverExpire);

				IntPtr hBinaryData = IntPtr.Zero;
				if(pe.Binaries.UCount >= 1)
				{
					foreach(KeyValuePair<string, ProtectedBinary> kvp in pe.Binaries)
					{
						e.BinaryDescription = kvp.Key;

						byte[] pbAttached = kvp.Value.ReadData();
						e.BinaryDataLength = (uint)pbAttached.Length;

						if(e.BinaryDataLength > 0)
						{
							hBinaryData = Marshal.AllocHGlobal((int)e.BinaryDataLength);
							Marshal.Copy(pbAttached, 0, hBinaryData, (int)e.BinaryDataLength);

							e.BinaryData = hBinaryData;
						}

						break;
					}

					if((pe.Binaries.UCount > 1) && (m_slLogger != null))
						m_slLogger.SetText(KdbPrefix + KPRes.FormatOnlyOneAttachment + "\r\n\r\n" +
							KPRes.Entry + ":\r\n" + KPRes.Title + ": " + e.Title + "\r\n" +
							KPRes.UserName + ": " + e.UserName, LogStatusType.Warning);
				}

				bool bResult = mgr.AddEntry(ref e);

				Marshal.FreeHGlobal(hBinaryData);
				hBinaryData = IntPtr.Zero;

				if(!bResult)
				{
					Debug.Assert(false);
					throw new InvalidOperationException();
				}

				++uEntriesSaved;
				if(m_slLogger != null)
					if(!m_slLogger.SetProgress((100 * uEntriesSaved) / uEntryCount))
						return false;

				return true;
			};

			if(!pgRoot.TraverseTree(TraversalMethod.PreOrder, null, eh))
				throw new InvalidOperationException();
		}
Exemple #4
0
		private static void WriteGroup(PwGroup pg, PwGroup pgRoot, ref uint uGroupIndex,
			Dictionary<PwGroup, UInt32> dictGroups, DateTime dtNeverExpire,
			KdbManager mgr, bool bForceLevel0)
		{
			if(pg == pgRoot) return;

			KdbGroup grp = new KdbGroup();

			grp.GroupId = uGroupIndex;
			dictGroups[pg] = grp.GroupId;

			grp.ImageId = (uint)pg.IconId;
			grp.Name = pg.Name;
			grp.CreationTime.Set(pg.CreationTime);
			grp.LastModificationTime.Set(pg.LastModificationTime);
			grp.LastAccessTime.Set(pg.LastAccessTime);

			if(pg.Expires)
				grp.ExpirationTime.Set(pg.ExpiryTime);
			else grp.ExpirationTime.Set(dtNeverExpire);

			grp.Level = (bForceLevel0 ? (ushort)0 : (ushort)(pg.GetLevel() - 1));

			if(pg.IsExpanded) grp.Flags |= (uint)KdbGroupFlags.Expanded;

			if(!mgr.AddGroup(ref grp))
			{
				Debug.Assert(false);
				throw new InvalidOperationException();
			}

			++uGroupIndex;
		}
Exemple #5
0
		private static void EnsureParentGroupsExported(PwGroup pgRoot, ref uint uGroupIndex,
			Dictionary<PwGroup, UInt32> dictGroups, DateTime dtNeverExpires,
			KdbManager mgr)
		{
			bool bHasAtLeastOneGroup = (dictGroups.Count > 0);
			uint uLocalIndex = uGroupIndex; // Local copy, can't use ref in delegate

			EntryHandler eh = delegate(PwEntry pe)
			{
				PwGroup pg = pe.ParentGroup;
				if(pg == null) { Debug.Assert(false); return true; }
				if(bHasAtLeastOneGroup && (pg == pgRoot)) return true;

				if(dictGroups.ContainsKey(pg)) return true;

				WriteGroup(pg, pgRoot, ref uLocalIndex, dictGroups, dtNeverExpires,
					mgr, true);
				return true;
			};

			pgRoot.TraverseTree(TraversalMethod.PreOrder, null, eh);
			uGroupIndex = uLocalIndex;
		}
Exemple #6
0
		private static Dictionary<PwGroup, UInt32> WriteGroups(KdbManager mgr,
			PwGroup pgRoot)
		{
			Dictionary<PwGroup, UInt32> dictGroups = new Dictionary<PwGroup, uint>();

			uint uGroupIndex = 1;
			DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();

			GroupHandler gh = delegate(PwGroup pg)
			{
				WriteGroup(pg, pgRoot, ref uGroupIndex, dictGroups, dtNeverExpire,
					mgr, false);
				return true;
			};

			pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, null);
			Debug.Assert(dictGroups.Count == (int)(uGroupIndex - 1));

			EnsureParentGroupsExported(pgRoot, ref uGroupIndex, dictGroups,
				dtNeverExpire, mgr);
			return dictGroups;
		}
Exemple #7
0
		/// <summary>
		/// Save the contents of the current <c>PwDatabase</c> to a KDB file.
		/// </summary>
		/// <param name="strSaveToFile">Location to save the KDB file to.</param>
		public void Save(string strSaveToFile, PwGroup pgDataSource)
		{
			Debug.Assert(strSaveToFile != null);
			if(strSaveToFile == null) throw new ArgumentNullException("strSaveToFile");

			using(KdbManager mgr = new KdbManager())
			{
				KdbErrorCode e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey);
				if(e != KdbErrorCode.Success)
				{
					Debug.Assert(false);
					throw new Exception(KLRes.InvalidCompositeKey);
				}

				if(m_slLogger != null)
				{
					if(m_pwDatabase.MasterKey.ContainsType(typeof(KcpUserAccount)))
						m_slLogger.SetText(KPRes.KdbWUA, LogStatusType.Warning);

					if(m_pwDatabase.Name.Length != 0)
						m_slLogger.SetText(KdbPrefix + KPRes.FormatNoDatabaseName, LogStatusType.Warning);
					if(m_pwDatabase.Description.Length != 0)
						m_slLogger.SetText(KdbPrefix + KPRes.FormatNoDatabaseDesc, LogStatusType.Warning);
				}

				// Set properties
				if(m_pwDatabase.KeyEncryptionRounds >= (ulong)UInt32.MaxValue)
					mgr.KeyTransformationRounds = 0xFFFFFFFEU;
				else mgr.KeyTransformationRounds = (uint)m_pwDatabase.KeyEncryptionRounds;

				PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup);

				// Write groups and entries
				Dictionary<PwGroup, UInt32> dictGroups = WriteGroups(mgr, pgRoot);
				WriteEntries(mgr, dictGroups, pgRoot);

				e = mgr.SaveDatabase(strSaveToFile);
				if(e != KdbErrorCode.Success)
					throw new Exception(KLRes.FileSaveFailed);
			}
		}
Exemple #8
0
		private void ReadEntries(KdbManager mgr, Dictionary<UInt32, PwGroup> dictGroups)
		{
			DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();
			uint uEntryCount = mgr.EntryCount;

			for(uint uEntry = 0; uEntry < uEntryCount; ++uEntry)
			{
				KdbEntry e = mgr.GetEntry(uEntry);

				PwGroup pgContainer;
				if(!dictGroups.TryGetValue(e.GroupId, out pgContainer))
				{
					Debug.Assert(false);
					continue;
				}

				PwEntry pe = new PwEntry(false, false);
				pe.SetUuid(new PwUuid(e.Uuid.ToByteArray()), false);

				pgContainer.AddEntry(pe, true, true);

				pe.IconId = (e.ImageId < (uint)PwIcon.Count) ? (PwIcon)e.ImageId : PwIcon.Key;

				pe.Strings.Set(PwDefs.TitleField, new ProtectedString(
					m_pwDatabase.MemoryProtection.ProtectTitle, e.Title));
				pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
					m_pwDatabase.MemoryProtection.ProtectUserName, e.UserName));
				pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(
					m_pwDatabase.MemoryProtection.ProtectPassword, e.Password));
				pe.Strings.Set(PwDefs.UrlField, new ProtectedString(
					m_pwDatabase.MemoryProtection.ProtectUrl, e.Url));

				string strNotes = e.Additional;
				ImportAutoType(ref strNotes, pe);
				ImportUrlOverride(ref strNotes, pe);
				pe.Strings.Set(PwDefs.NotesField, new ProtectedString(
					m_pwDatabase.MemoryProtection.ProtectNotes, strNotes));

				pe.CreationTime = e.CreationTime.ToDateTime();
				pe.LastModificationTime = e.LastModificationTime.ToDateTime();
				pe.LastAccessTime = e.LastAccessTime.ToDateTime();
				pe.ExpiryTime = e.ExpirationTime.ToDateTime();

				pe.Expires = (pe.ExpiryTime != dtNeverExpire);

				if((e.BinaryDataLength > 0) && (e.BinaryData != IntPtr.Zero))
				{
					byte[] pbData = KdbManager.ReadBinary(e.BinaryData, e.BinaryDataLength);
					Debug.Assert(pbData.Length == e.BinaryDataLength);

					string strDesc = e.BinaryDescription;
					if(string.IsNullOrEmpty(strDesc)) strDesc = "Attachment";

					pe.Binaries.Set(strDesc, new ProtectedBinary(false, pbData));
				}

				if(m_slLogger != null)
				{
					if(!m_slLogger.SetProgress((100 * uEntry) / uEntryCount))
						throw new Exception(KPRes.Cancel);
				}
			}
		}
Exemple #9
0
		private Dictionary<UInt32, PwGroup> ReadGroups(KdbManager mgr)
		{
			uint uGroupCount = mgr.GroupCount;
			Dictionary<UInt32, PwGroup> dictGroups = new Dictionary<uint, PwGroup>();

			Stack<PwGroup> vGroupStack = new Stack<PwGroup>();
			vGroupStack.Push(m_pwDatabase.RootGroup);

			DateTime dtNeverExpire = KdbManager.GetNeverExpireTime();

			for(uint uGroup = 0; uGroup < uGroupCount; ++uGroup)
			{
				KdbGroup g = mgr.GetGroup(uGroup);

				PwGroup pg = new PwGroup(true, false);

				pg.Name = g.Name;
				pg.IconId = (g.ImageId < (uint)PwIcon.Count) ? (PwIcon)g.ImageId : PwIcon.Folder;
				
				pg.CreationTime = g.CreationTime.ToDateTime();
				pg.LastModificationTime = g.LastModificationTime.ToDateTime();
				pg.LastAccessTime = g.LastAccessTime.ToDateTime();
				pg.ExpiryTime = g.ExpirationTime.ToDateTime();

				pg.Expires = (pg.ExpiryTime != dtNeverExpire);

				pg.IsExpanded = ((g.Flags & (uint)KdbGroupFlags.Expanded) != 0);

				while(g.Level < (vGroupStack.Count - 1))
					vGroupStack.Pop();

				vGroupStack.Peek().AddGroup(pg, true);

				dictGroups[g.GroupId] = pg;

				if(g.Level == (uint)(vGroupStack.Count - 1))
					vGroupStack.Push(pg);
			}

			return dictGroups;
		}
Exemple #10
0
		/// <summary>
		/// Loads a KDB file and stores all loaded entries in the current
		/// PwDatabase instance.
		/// </summary>
		/// <param name="strFilePath">Relative or absolute path to the file to open.</param>
		public void Load(string strFilePath)
		{
			Debug.Assert(strFilePath != null);
			if(strFilePath == null) throw new ArgumentNullException("strFilePath");

			using(KdbManager mgr = new KdbManager())
			{
				KdbErrorCode e;

				e = KdbFile.SetDatabaseKey(mgr, m_pwDatabase.MasterKey);
				if(e != KdbErrorCode.Success)
					throw new Exception(KLRes.InvalidCompositeKey);

				e = mgr.OpenDatabase(strFilePath, IntPtr.Zero);
				if(e != KdbErrorCode.Success)
					throw new Exception(KLRes.FileLoadFailed);

				// Copy properties
				m_pwDatabase.KeyEncryptionRounds = mgr.KeyTransformationRounds;

				// Read groups and entries
				Dictionary<UInt32, PwGroup> dictGroups = ReadGroups(mgr);
				ReadEntries(mgr, dictGroups);
			}
		}