Unmodified KeepassLib from KeePass Desktop v2.20
This commit is contained in:
		
							
								
								
									
										1
									
								
								src/KeePassLib2Android/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/KeePassLib2Android/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
obj/
 | 
			
		||||
							
								
								
									
										220
									
								
								src/KeePassLib2Android/Collections/AutoTypeConfig.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								src/KeePassLib2Android/Collections/AutoTypeConfig.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Collections
 | 
			
		||||
{
 | 
			
		||||
	[Flags]
 | 
			
		||||
	public enum AutoTypeObfuscationOptions
 | 
			
		||||
	{
 | 
			
		||||
		None = 0,
 | 
			
		||||
		UseClipboard = 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class AutoTypeAssociation : IEquatable<AutoTypeAssociation>,
 | 
			
		||||
		IDeepCloneable<AutoTypeAssociation>
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strWindow = string.Empty;
 | 
			
		||||
		public string WindowName
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strWindow; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strWindow = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strSequence = string.Empty;
 | 
			
		||||
		public string Sequence
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strSequence; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strSequence = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public AutoTypeAssociation() { }
 | 
			
		||||
 | 
			
		||||
		public AutoTypeAssociation(string strWindow, string strSeq)
 | 
			
		||||
		{
 | 
			
		||||
			if(strWindow == null) throw new ArgumentNullException("strWindow");
 | 
			
		||||
			if(strSeq == null) throw new ArgumentNullException("strSeq");
 | 
			
		||||
 | 
			
		||||
			m_strWindow = strWindow;
 | 
			
		||||
			m_strSequence = strSeq;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Equals(AutoTypeAssociation other)
 | 
			
		||||
		{
 | 
			
		||||
			if(other == null) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_strWindow != other.m_strWindow) return false;
 | 
			
		||||
			if(m_strSequence != other.m_strSequence) return false;
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public AutoTypeAssociation CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			return (AutoTypeAssociation)this.MemberwiseClone();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A list of auto-type associations.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class AutoTypeConfig : IEquatable<AutoTypeConfig>,
 | 
			
		||||
		IDeepCloneable<AutoTypeConfig>
 | 
			
		||||
	{
 | 
			
		||||
		private bool m_bEnabled = true;
 | 
			
		||||
		private AutoTypeObfuscationOptions m_atooObfuscation =
 | 
			
		||||
			AutoTypeObfuscationOptions.None;
 | 
			
		||||
		private string m_strDefaultSequence = string.Empty;
 | 
			
		||||
		private List<AutoTypeAssociation> m_lWindowAssocs =
 | 
			
		||||
			new List<AutoTypeAssociation>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Specify whether auto-type is enabled or not.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool Enabled
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bEnabled; }
 | 
			
		||||
			set { m_bEnabled = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Specify whether the typing should be obfuscated.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public AutoTypeObfuscationOptions ObfuscationOptions
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_atooObfuscation; }
 | 
			
		||||
			set { m_atooObfuscation = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The default keystroke sequence that is auto-typed if
 | 
			
		||||
		/// no matching window is found in the <c>Associations</c>
 | 
			
		||||
		/// container.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string DefaultSequence
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strDefaultSequence; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strDefaultSequence = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get all auto-type window/keystroke sequence pairs.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public IEnumerable<AutoTypeAssociation> Associations
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_lWindowAssocs; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int AssociationsCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_lWindowAssocs.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new auto-type associations list.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public AutoTypeConfig()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Remove all associations.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public void Clear()
 | 
			
		||||
		{
 | 
			
		||||
			m_lWindowAssocs.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Clone the auto-type associations list.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>New, cloned object.</returns>
 | 
			
		||||
		public AutoTypeConfig CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			AutoTypeConfig newCfg = new AutoTypeConfig();
 | 
			
		||||
 | 
			
		||||
			newCfg.m_bEnabled = m_bEnabled;
 | 
			
		||||
			newCfg.m_atooObfuscation = m_atooObfuscation;
 | 
			
		||||
			newCfg.m_strDefaultSequence = m_strDefaultSequence;
 | 
			
		||||
 | 
			
		||||
			foreach(AutoTypeAssociation a in m_lWindowAssocs)
 | 
			
		||||
				newCfg.Add(a.CloneDeep());
 | 
			
		||||
 | 
			
		||||
			return newCfg;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Equals(AutoTypeConfig other)
 | 
			
		||||
		{
 | 
			
		||||
			if(other == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			if(m_bEnabled != other.m_bEnabled) return false;
 | 
			
		||||
			if(m_atooObfuscation != other.m_atooObfuscation) return false;
 | 
			
		||||
			if(m_strDefaultSequence != other.m_strDefaultSequence) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_lWindowAssocs.Count != other.m_lWindowAssocs.Count) return false;
 | 
			
		||||
			for(int i = 0; i < m_lWindowAssocs.Count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(!m_lWindowAssocs[i].Equals(other.m_lWindowAssocs[i]))
 | 
			
		||||
					return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(AutoTypeAssociation a)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(a != null); if(a == null) throw new ArgumentNullException("a");
 | 
			
		||||
 | 
			
		||||
			m_lWindowAssocs.Add(a);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public AutoTypeAssociation GetAt(int iIndex)
 | 
			
		||||
		{
 | 
			
		||||
			if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
 | 
			
		||||
				throw new ArgumentOutOfRangeException("iIndex");
 | 
			
		||||
 | 
			
		||||
			return m_lWindowAssocs[iIndex];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RemoveAt(int iIndex)
 | 
			
		||||
		{
 | 
			
		||||
			if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
 | 
			
		||||
				throw new ArgumentOutOfRangeException("iIndex");
 | 
			
		||||
 | 
			
		||||
			m_lWindowAssocs.RemoveAt(iIndex);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										173
									
								
								src/KeePassLib2Android/Collections/ProtectedBinaryDictionary.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/KeePassLib2Android/Collections/ProtectedBinaryDictionary.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Collections
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A list of <c>ProtectedBinary</c> objects (dictionary).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class ProtectedBinaryDictionary :
 | 
			
		||||
		IDeepCloneable<ProtectedBinaryDictionary>,
 | 
			
		||||
		IEnumerable<KeyValuePair<string, ProtectedBinary>>
 | 
			
		||||
	{
 | 
			
		||||
		private SortedDictionary<string, ProtectedBinary> m_vBinaries =
 | 
			
		||||
			new SortedDictionary<string, ProtectedBinary>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the number of binaries in this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public uint UCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return (uint)m_vBinaries.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new list of protected binaries.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedBinaryDictionary()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vBinaries.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<KeyValuePair<string, ProtectedBinary>> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vBinaries.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Clear()
 | 
			
		||||
		{
 | 
			
		||||
			m_vBinaries.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Clone the current <c>ProtectedBinaryList</c> object, including all
 | 
			
		||||
		/// stored protected strings.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>New <c>ProtectedBinaryList</c> object.</returns>
 | 
			
		||||
		public ProtectedBinaryDictionary CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			ProtectedBinaryDictionary plNew = new ProtectedBinaryDictionary();
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvpBin in m_vBinaries)
 | 
			
		||||
			{
 | 
			
		||||
				// ProtectedBinary objects are immutable
 | 
			
		||||
				plNew.Set(kvpBin.Key, kvpBin.Value);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return plNew;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool EqualsDictionary(ProtectedBinaryDictionary dict)
 | 
			
		||||
		{
 | 
			
		||||
			if(dict == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			if(m_vBinaries.Count != dict.m_vBinaries.Count) return false;
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvp in m_vBinaries)
 | 
			
		||||
			{
 | 
			
		||||
				ProtectedBinary pb = dict.Get(kvp.Key);
 | 
			
		||||
				if(pb == null) return false;
 | 
			
		||||
				if(!pb.Equals(kvp.Value)) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get one of the stored binaries.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strName">Binary identifier.</param>
 | 
			
		||||
		/// <returns>Protected binary. If the binary identified by
 | 
			
		||||
		/// <paramref name="strName" /> cannot be found, the function
 | 
			
		||||
		/// returns <c>null</c>.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public ProtectedBinary Get(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			ProtectedBinary pb;
 | 
			
		||||
			if(m_vBinaries.TryGetValue(strName, out pb)) return pb;
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set a binary object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strField">Identifier of the binary field to modify.</param>
 | 
			
		||||
		/// <param name="pbNewValue">New value. This parameter must not be <c>null</c>.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if any of the input
 | 
			
		||||
		/// parameters is <c>null</c>.</exception>
 | 
			
		||||
		public void Set(string strField, ProtectedBinary pbNewValue)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
 | 
			
		||||
			Debug.Assert(pbNewValue != null); if(pbNewValue == null) throw new ArgumentNullException("pbNewValue");
 | 
			
		||||
 | 
			
		||||
			m_vBinaries[strField] = pbNewValue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Remove a binary object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strField">Identifier of the binary field to remove.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the object has been successfully
 | 
			
		||||
		/// removed, otherwise <c>false</c>.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input parameter
 | 
			
		||||
		/// is <c>null</c>.</exception>
 | 
			
		||||
		public bool Remove(string strField)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
 | 
			
		||||
 | 
			
		||||
			return m_vBinaries.Remove(strField);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string KeysToString()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_vBinaries.Count == 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvp in m_vBinaries)
 | 
			
		||||
			{
 | 
			
		||||
				if(sb.Length > 0) sb.Append(", ");
 | 
			
		||||
				sb.Append(kvp.Key);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return sb.ToString();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										306
									
								
								src/KeePassLib2Android/Collections/ProtectedStringDictionary.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								src/KeePassLib2Android/Collections/ProtectedStringDictionary.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,306 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Collections
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A list of <c>ProtectedString</c> objects (dictionary).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class ProtectedStringDictionary :
 | 
			
		||||
		IDeepCloneable<ProtectedStringDictionary>,
 | 
			
		||||
		IEnumerable<KeyValuePair<string, ProtectedString>>
 | 
			
		||||
	{
 | 
			
		||||
		private SortedDictionary<string, ProtectedString> m_vStrings =
 | 
			
		||||
			new SortedDictionary<string, ProtectedString>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the number of strings in this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public uint UCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return (uint)m_vStrings.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new list of protected strings.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedStringDictionary()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vStrings.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<KeyValuePair<string, ProtectedString>> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vStrings.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Clear()
 | 
			
		||||
		{
 | 
			
		||||
			m_vStrings.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Clone the current <c>ProtectedStringList</c> object, including all
 | 
			
		||||
		/// stored protected strings.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>New <c>ProtectedStringList</c> object.</returns>
 | 
			
		||||
		public ProtectedStringDictionary CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			ProtectedStringDictionary plNew = new ProtectedStringDictionary();
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedString> kvpStr in m_vStrings)
 | 
			
		||||
			{
 | 
			
		||||
				// ProtectedString objects are immutable
 | 
			
		||||
				plNew.Set(kvpStr.Key, kvpStr.Value);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return plNew;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public bool EqualsDictionary(ProtectedStringDictionary dict)
 | 
			
		||||
		{
 | 
			
		||||
			return EqualsDictionary(dict, PwCompareOptions.None, MemProtCmpMode.None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public bool EqualsDictionary(ProtectedStringDictionary dict,
 | 
			
		||||
			MemProtCmpMode mpCompare)
 | 
			
		||||
		{
 | 
			
		||||
			return EqualsDictionary(dict, PwCompareOptions.None, mpCompare);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool EqualsDictionary(ProtectedStringDictionary dict,
 | 
			
		||||
			PwCompareOptions pwOpt, MemProtCmpMode mpCompare)
 | 
			
		||||
		{
 | 
			
		||||
			if(dict == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
 | 
			
		||||
				PwCompareOptions.None);
 | 
			
		||||
			if(!bNeEqStd)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_vStrings.Count != dict.m_vStrings.Count) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedString> kvp in m_vStrings)
 | 
			
		||||
			{
 | 
			
		||||
				bool bStdField = PwDefs.IsStandardField(kvp.Key);
 | 
			
		||||
				ProtectedString ps = dict.Get(kvp.Key);
 | 
			
		||||
 | 
			
		||||
				if(bNeEqStd && (ps == null) && bStdField)
 | 
			
		||||
					ps = ProtectedString.Empty;
 | 
			
		||||
 | 
			
		||||
				if(ps == null) return false;
 | 
			
		||||
 | 
			
		||||
				if(mpCompare == MemProtCmpMode.Full)
 | 
			
		||||
				{
 | 
			
		||||
					if(ps.IsProtected != kvp.Value.IsProtected) return false;
 | 
			
		||||
				}
 | 
			
		||||
				else if(mpCompare == MemProtCmpMode.CustomOnly)
 | 
			
		||||
				{
 | 
			
		||||
					if(!bStdField && (ps.IsProtected != kvp.Value.IsProtected))
 | 
			
		||||
						return false;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if(ps.ReadString() != kvp.Value.ReadString()) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(bNeEqStd)
 | 
			
		||||
			{
 | 
			
		||||
				foreach(KeyValuePair<string, ProtectedString> kvp in dict.m_vStrings)
 | 
			
		||||
				{
 | 
			
		||||
					ProtectedString ps = Get(kvp.Key);
 | 
			
		||||
 | 
			
		||||
					if(ps != null) continue; // Compared previously
 | 
			
		||||
					if(!PwDefs.IsStandardField(kvp.Key)) return false;
 | 
			
		||||
					if(!kvp.Value.IsEmpty) return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get one of the protected strings.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strName">String identifier.</param>
 | 
			
		||||
		/// <returns>Protected string. If the string identified by
 | 
			
		||||
		/// <paramref name="strName" /> cannot be found, the function
 | 
			
		||||
		/// returns <c>null</c>.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input parameter
 | 
			
		||||
		/// is <c>null</c>.</exception>
 | 
			
		||||
		public ProtectedString Get(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			ProtectedString ps;
 | 
			
		||||
			if(m_vStrings.TryGetValue(strName, out ps)) return ps;
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get one of the protected strings. The return value is never <c>null</c>.
 | 
			
		||||
		/// If the requested string cannot be found, an empty protected string
 | 
			
		||||
		/// object is returned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strName">String identifier.</param>
 | 
			
		||||
		/// <returns>Returns a protected string object. If the standard string
 | 
			
		||||
		/// has not been set yet, the return value is an empty string (<c>""</c>).</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public ProtectedString GetSafe(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			ProtectedString ps;
 | 
			
		||||
			if(m_vStrings.TryGetValue(strName, out ps)) return ps;
 | 
			
		||||
 | 
			
		||||
			return ProtectedString.Empty;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Test if a named string exists.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strName">Name of the string to try.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the string exists, otherwise <c>false</c>.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if
 | 
			
		||||
		/// <paramref name="strName" /> is <c>null</c>.</exception>
 | 
			
		||||
		public bool Exists(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			return m_vStrings.ContainsKey(strName);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get one of the protected strings. If the string doesn't exist, the
 | 
			
		||||
		/// return value is an empty string (<c>""</c>).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strName">Name of the requested string.</param>
 | 
			
		||||
		/// <returns>Requested string value or an empty string, if the named
 | 
			
		||||
		/// string doesn't exist.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public string ReadSafe(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			ProtectedString ps;
 | 
			
		||||
			if(m_vStrings.TryGetValue(strName, out ps))
 | 
			
		||||
				return ps.ReadString();
 | 
			
		||||
 | 
			
		||||
			return string.Empty;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get one of the entry strings. If the string doesn't exist, the
 | 
			
		||||
		/// return value is an empty string (<c>""</c>). If the string is
 | 
			
		||||
		/// in-memory protected, the return value is <c>PwDefs.HiddenPassword</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strName">Name of the requested string.</param>
 | 
			
		||||
		/// <returns>Returns the requested string in plain-text or
 | 
			
		||||
		/// <c>PwDefs.HiddenPassword</c> if the string cannot be found.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public string ReadSafeEx(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			ProtectedString ps;
 | 
			
		||||
			if(m_vStrings.TryGetValue(strName, out ps))
 | 
			
		||||
			{
 | 
			
		||||
				if(ps.IsProtected) return PwDefs.HiddenPassword;
 | 
			
		||||
				return ps.ReadString();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return string.Empty;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set a string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strField">Identifier of the string field to modify.</param>
 | 
			
		||||
		/// <param name="psNewValue">New value. This parameter must not be <c>null</c>.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if one of the input
 | 
			
		||||
		/// parameters is <c>null</c>.</exception>
 | 
			
		||||
		public void Set(string strField, ProtectedString psNewValue)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
 | 
			
		||||
			Debug.Assert(psNewValue != null); if(psNewValue == null) throw new ArgumentNullException("psNewValue");
 | 
			
		||||
 | 
			
		||||
			m_vStrings[strField] = psNewValue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Delete a string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strField">Name of the string field to delete.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the field has been successfully
 | 
			
		||||
		/// removed, otherwise the return value is <c>false</c>.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public bool Remove(string strField)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
 | 
			
		||||
 | 
			
		||||
			return m_vStrings.Remove(strField);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public List<string> GetKeys()
 | 
			
		||||
		{
 | 
			
		||||
			List<string> v = new List<string>();
 | 
			
		||||
 | 
			
		||||
			foreach(string strKey in m_vStrings.Keys) v.Add(strKey);
 | 
			
		||||
 | 
			
		||||
			return v;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void EnableProtection(string strField, bool bProtect)
 | 
			
		||||
		{
 | 
			
		||||
			ProtectedString ps = Get(strField);
 | 
			
		||||
			if(ps == null) return; // Nothing to do, no assert
 | 
			
		||||
 | 
			
		||||
			if(ps.IsProtected != bProtect)
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbData = ps.ReadUtf8();
 | 
			
		||||
				Set(strField, new ProtectedString(bProtect, pbData));
 | 
			
		||||
				MemUtil.ZeroByteArray(pbData);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										303
									
								
								src/KeePassLib2Android/Collections/PwObjectList.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										303
									
								
								src/KeePassLib2Android/Collections/PwObjectList.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,303 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Collections
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// List of objects that implement <c>IDeepCloneable</c>,
 | 
			
		||||
	/// and cannot be <c>null</c>.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <typeparam name="T">Type specifier.</typeparam>
 | 
			
		||||
	public sealed class PwObjectList<T> : IEnumerable<T>
 | 
			
		||||
		where T : class, IDeepCloneable<T>
 | 
			
		||||
	{
 | 
			
		||||
		private List<T> m_vObjects = new List<T>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get number of objects in this list.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public uint UCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return (uint)m_vObjects.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new list of objects.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwObjectList()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vObjects.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<T> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vObjects.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Clear()
 | 
			
		||||
		{
 | 
			
		||||
			// Do not destroy contained objects!
 | 
			
		||||
			m_vObjects.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Clone the current <c>PwObjectList</c>, including all
 | 
			
		||||
		/// stored objects (deep copy).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>New <c>PwObjectList</c>.</returns>
 | 
			
		||||
		public PwObjectList<T> CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			PwObjectList<T> pl = new PwObjectList<T>();
 | 
			
		||||
 | 
			
		||||
			foreach(T po in m_vObjects)
 | 
			
		||||
				pl.Add(po.CloneDeep());
 | 
			
		||||
 | 
			
		||||
			return pl;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwObjectList<T> CloneShallow()
 | 
			
		||||
		{
 | 
			
		||||
			PwObjectList<T> tNew = new PwObjectList<T>();
 | 
			
		||||
 | 
			
		||||
			foreach(T po in m_vObjects) tNew.Add(po);
 | 
			
		||||
 | 
			
		||||
			return tNew;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public List<T> CloneShallowToList()
 | 
			
		||||
		{
 | 
			
		||||
			PwObjectList<T> tNew = CloneShallow();
 | 
			
		||||
			return tNew.m_vObjects;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Add an object to this list.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pwObject">Object to be added.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public void Add(T pwObject)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwObject != null);
 | 
			
		||||
			if(pwObject == null) throw new ArgumentNullException("pwObject");
 | 
			
		||||
 | 
			
		||||
			m_vObjects.Add(pwObject);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(PwObjectList<T> vObjects)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(vObjects != null);
 | 
			
		||||
			if(vObjects == null) throw new ArgumentNullException("vObjects");
 | 
			
		||||
 | 
			
		||||
			foreach(T po in vObjects)
 | 
			
		||||
			{
 | 
			
		||||
				m_vObjects.Add(po);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(List<T> vObjects)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(vObjects != null);
 | 
			
		||||
			if(vObjects == null) throw new ArgumentNullException("vObjects");
 | 
			
		||||
 | 
			
		||||
			foreach(T po in vObjects)
 | 
			
		||||
			{
 | 
			
		||||
				m_vObjects.Add(po);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get an object of the list.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uIndex">Index of the object to get. Must be valid, otherwise an
 | 
			
		||||
		/// exception is thrown.</param>
 | 
			
		||||
		/// <returns>Reference to an existing <c>T</c> object. Is never <c>null</c>.</returns>
 | 
			
		||||
		public T GetAt(uint uIndex)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(uIndex < m_vObjects.Count);
 | 
			
		||||
			if(uIndex >= m_vObjects.Count) throw new ArgumentOutOfRangeException("uIndex");
 | 
			
		||||
 | 
			
		||||
			return m_vObjects[(int)uIndex];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void SetAt(uint uIndex, T pwObject)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwObject != null);
 | 
			
		||||
			if(pwObject == null) throw new ArgumentNullException("pwObject");
 | 
			
		||||
			if(uIndex >= (uint)m_vObjects.Count)
 | 
			
		||||
				throw new ArgumentOutOfRangeException("uIndex");
 | 
			
		||||
 | 
			
		||||
			m_vObjects[(int)uIndex] = pwObject;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a range of objects.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uStartIndexIncl">Index of the first object to be
 | 
			
		||||
		/// returned (inclusive).</param>
 | 
			
		||||
		/// <param name="uEndIndexIncl">Index of the last object to be
 | 
			
		||||
		/// returned (inclusive).</param>
 | 
			
		||||
		/// <returns></returns>
 | 
			
		||||
		public List<T> GetRange(uint uStartIndexIncl, uint uEndIndexIncl)
 | 
			
		||||
		{
 | 
			
		||||
			if(uStartIndexIncl >= (uint)m_vObjects.Count)
 | 
			
		||||
				throw new ArgumentOutOfRangeException("uStartIndexIncl");
 | 
			
		||||
			if(uEndIndexIncl >= (uint)m_vObjects.Count)
 | 
			
		||||
				throw new ArgumentOutOfRangeException("uEndIndexIncl");
 | 
			
		||||
			if(uStartIndexIncl > uEndIndexIncl)
 | 
			
		||||
				throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			List<T> list = new List<T>((int)(uEndIndexIncl - uStartIndexIncl) + 1);
 | 
			
		||||
			for(uint u = uStartIndexIncl; u <= uEndIndexIncl; ++u)
 | 
			
		||||
			{
 | 
			
		||||
				list.Add(m_vObjects[(int)u]);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return list;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int IndexOf(T pwReference)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwReference != null); if(pwReference == null) throw new ArgumentNullException("pwReference");
 | 
			
		||||
 | 
			
		||||
			return m_vObjects.IndexOf(pwReference);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Delete an object of this list. The object to be deleted is identified
 | 
			
		||||
		/// by a reference handle.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pwReference">Reference of the object to be deleted.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the object was deleted, <c>false</c> if
 | 
			
		||||
		/// the object wasn't found in this list.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public bool Remove(T pwReference)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwReference != null); if(pwReference == null) throw new ArgumentNullException("pwReference");
 | 
			
		||||
 | 
			
		||||
			return m_vObjects.Remove(pwReference);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void RemoveAt(uint uIndex)
 | 
			
		||||
		{
 | 
			
		||||
			m_vObjects.RemoveAt((int)uIndex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Move an object up or down.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="tObject">The object to be moved.</param>
 | 
			
		||||
		/// <param name="bUp">Move one up. If <c>false</c>, move one down.</param>
 | 
			
		||||
		public void MoveOne(T tObject, bool bUp)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(tObject != null);
 | 
			
		||||
			if(tObject == null) throw new ArgumentNullException("tObject");
 | 
			
		||||
 | 
			
		||||
			int nCount = m_vObjects.Count;
 | 
			
		||||
			if(nCount <= 1) return;
 | 
			
		||||
 | 
			
		||||
			int nIndex = m_vObjects.IndexOf(tObject);
 | 
			
		||||
			Debug.Assert(nIndex >= 0);
 | 
			
		||||
 | 
			
		||||
			if(bUp && (nIndex > 0)) // No assert for top item
 | 
			
		||||
			{
 | 
			
		||||
				T tTemp = m_vObjects[nIndex - 1];
 | 
			
		||||
				m_vObjects[nIndex - 1] = m_vObjects[nIndex];
 | 
			
		||||
				m_vObjects[nIndex] = tTemp;
 | 
			
		||||
			}
 | 
			
		||||
			else if(!bUp && (nIndex != (nCount - 1))) // No assert for bottom item
 | 
			
		||||
			{
 | 
			
		||||
				T tTemp = m_vObjects[nIndex + 1];
 | 
			
		||||
				m_vObjects[nIndex + 1] = m_vObjects[nIndex];
 | 
			
		||||
				m_vObjects[nIndex] = tTemp;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Move some of the objects in this list to the top/bottom.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="vObjects">List of objects to be moved.</param>
 | 
			
		||||
		/// <param name="bTop">Move to top. If <c>false</c>, move to bottom.</param>
 | 
			
		||||
		public void MoveTopBottom(T[] vObjects, bool bTop)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(vObjects != null);
 | 
			
		||||
			if(vObjects == null) throw new ArgumentNullException("vObjects");
 | 
			
		||||
 | 
			
		||||
			if(vObjects.Length == 0) return;
 | 
			
		||||
 | 
			
		||||
			int nCount = m_vObjects.Count;
 | 
			
		||||
			foreach(T t in vObjects) m_vObjects.Remove(t);
 | 
			
		||||
 | 
			
		||||
			if(bTop)
 | 
			
		||||
			{
 | 
			
		||||
				int nPos = 0;
 | 
			
		||||
				foreach(T t in vObjects)
 | 
			
		||||
				{
 | 
			
		||||
					m_vObjects.Insert(nPos, t);
 | 
			
		||||
					++nPos;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else // Move to bottom
 | 
			
		||||
			{
 | 
			
		||||
				foreach(T t in vObjects) m_vObjects.Add(t);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(nCount == m_vObjects.Count);
 | 
			
		||||
			if(nCount != m_vObjects.Count)
 | 
			
		||||
				throw new ArgumentException("At least one of the T objects in the vObjects list doesn't exist!");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Sort(IComparer<T> tComparer)
 | 
			
		||||
		{
 | 
			
		||||
			if(tComparer == null) throw new ArgumentNullException("tComparer");
 | 
			
		||||
 | 
			
		||||
			m_vObjects.Sort(tComparer);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static PwObjectList<T> FromArray(T[] tArray)
 | 
			
		||||
		{
 | 
			
		||||
			if(tArray == null) throw new ArgumentNullException("tArray");
 | 
			
		||||
 | 
			
		||||
			PwObjectList<T> l = new PwObjectList<T>();
 | 
			
		||||
			foreach(T t in tArray) { l.Add(t); }
 | 
			
		||||
			return l;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static PwObjectList<T> FromList(List<T> tList)
 | 
			
		||||
		{
 | 
			
		||||
			if(tList == null) throw new ArgumentNullException("tList");
 | 
			
		||||
 | 
			
		||||
			PwObjectList<T> l = new PwObjectList<T>();
 | 
			
		||||
			l.Add(tList);
 | 
			
		||||
			return l;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										80
									
								
								src/KeePassLib2Android/Collections/PwObjectPool.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/KeePassLib2Android/Collections/PwObjectPool.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Delegates;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Collections
 | 
			
		||||
{
 | 
			
		||||
	public sealed class PwObjectPool
 | 
			
		||||
	{
 | 
			
		||||
		private SortedDictionary<PwUuidComparable, IStructureItem> m_dict =
 | 
			
		||||
			new SortedDictionary<PwUuidComparable, IStructureItem>();
 | 
			
		||||
 | 
			
		||||
		public static PwObjectPool FromGroupRecursive(PwGroup pgRoot, bool bEntries)
 | 
			
		||||
		{
 | 
			
		||||
			if(pgRoot == null) throw new ArgumentNullException("pgRoot");
 | 
			
		||||
 | 
			
		||||
			PwObjectPool p = new PwObjectPool();
 | 
			
		||||
 | 
			
		||||
			if(!bEntries) p.m_dict[new PwUuidComparable(pgRoot.Uuid)] = pgRoot;
 | 
			
		||||
			GroupHandler gh = delegate(PwGroup pg)
 | 
			
		||||
			{
 | 
			
		||||
				p.m_dict[new PwUuidComparable(pg.Uuid)] = pg;
 | 
			
		||||
				return true;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			EntryHandler eh = delegate(PwEntry pe)
 | 
			
		||||
			{
 | 
			
		||||
				p.m_dict[new PwUuidComparable(pe.Uuid)] = pe;
 | 
			
		||||
				return true;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			pgRoot.TraverseTree(TraversalMethod.PreOrder, bEntries ? null : gh,
 | 
			
		||||
				bEntries ? eh : null);
 | 
			
		||||
			return p;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IStructureItem Get(PwUuid pwUuid)
 | 
			
		||||
		{
 | 
			
		||||
			IStructureItem pItem;
 | 
			
		||||
			m_dict.TryGetValue(new PwUuidComparable(pwUuid), out pItem);
 | 
			
		||||
			return pItem;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool ContainsOnlyType(Type t)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(KeyValuePair<PwUuidComparable, IStructureItem> kvp in m_dict)
 | 
			
		||||
			{
 | 
			
		||||
				if(kvp.Value.GetType() != t) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								src/KeePassLib2Android/Collections/StringDictionaryEx.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/KeePassLib2Android/Collections/StringDictionaryEx.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Collections
 | 
			
		||||
{
 | 
			
		||||
	public sealed class StringDictionaryEx : IDeepCloneable<StringDictionaryEx>,
 | 
			
		||||
		IEnumerable<KeyValuePair<string, string>>
 | 
			
		||||
	{
 | 
			
		||||
		private SortedDictionary<string, string> m_vDict =
 | 
			
		||||
			new SortedDictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
		public int Count
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vDict.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public StringDictionaryEx()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vDict.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vDict.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public StringDictionaryEx CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			StringDictionaryEx plNew = new StringDictionaryEx();
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, string> kvpStr in m_vDict)
 | 
			
		||||
				plNew.Set(kvpStr.Key, kvpStr.Value);
 | 
			
		||||
 | 
			
		||||
			return plNew;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string Get(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			string s;
 | 
			
		||||
			if(m_vDict.TryGetValue(strName, out s)) return s;
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Exists(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			return m_vDict.ContainsKey(strName);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set a string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strField">Identifier of the string field to modify.</param>
 | 
			
		||||
		/// <param name="strNewValue">New value. This parameter must not be <c>null</c>.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if one of the input
 | 
			
		||||
		/// parameters is <c>null</c>.</exception>
 | 
			
		||||
		public void Set(string strField, string strNewValue)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
 | 
			
		||||
			Debug.Assert(strNewValue != null); if(strNewValue == null) throw new ArgumentNullException("strNewValue");
 | 
			
		||||
 | 
			
		||||
			m_vDict[strField] = strNewValue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Delete a string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strField">Name of the string field to delete.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the field has been successfully
 | 
			
		||||
		/// removed, otherwise the return value is <c>false</c>.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public bool Remove(string strField)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
 | 
			
		||||
 | 
			
		||||
			return m_vDict.Remove(strField);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										162
									
								
								src/KeePassLib2Android/Cryptography/Cipher/CipherPool.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								src/KeePassLib2Android/Cryptography/Cipher/CipherPool.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.Cipher
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Pool of encryption/decryption algorithms (ciphers).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class CipherPool
 | 
			
		||||
	{
 | 
			
		||||
		private List<ICipherEngine> m_vCiphers = new List<ICipherEngine>();
 | 
			
		||||
		private static CipherPool m_poolGlobal = null;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Reference to the global cipher pool.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static CipherPool GlobalPool
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if(m_poolGlobal != null) return m_poolGlobal;
 | 
			
		||||
 | 
			
		||||
				m_poolGlobal = new CipherPool();
 | 
			
		||||
				m_poolGlobal.AddCipher(new StandardAesEngine());
 | 
			
		||||
 | 
			
		||||
				return m_poolGlobal;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Remove all cipher engines from the current pool.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public void Clear()
 | 
			
		||||
		{
 | 
			
		||||
			m_vCiphers.Clear();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Add a cipher engine to the pool.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="csEngine">Cipher engine to add. Must not be <c>null</c>.</param>
 | 
			
		||||
		public void AddCipher(ICipherEngine csEngine)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(csEngine != null);
 | 
			
		||||
			if(csEngine == null) throw new ArgumentNullException("csEngine");
 | 
			
		||||
 | 
			
		||||
			// Return if a cipher with that ID is registered already.
 | 
			
		||||
			for(int i = 0; i < m_vCiphers.Count; ++i)
 | 
			
		||||
				if(m_vCiphers[i].CipherUuid.EqualsValue(csEngine.CipherUuid))
 | 
			
		||||
					return;
 | 
			
		||||
 | 
			
		||||
			m_vCiphers.Add(csEngine);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a cipher identified by its UUID.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uuidCipher">UUID of the cipher to return.</param>
 | 
			
		||||
		/// <returns>Reference to the requested cipher. If the cipher is
 | 
			
		||||
		/// not found, <c>null</c> is returned.</returns>
 | 
			
		||||
		public ICipherEngine GetCipher(PwUuid uuidCipher)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(ICipherEngine iEngine in m_vCiphers)
 | 
			
		||||
			{
 | 
			
		||||
				if(iEngine.CipherUuid.EqualsValue(uuidCipher))
 | 
			
		||||
					return iEngine;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the index of a cipher. This index is temporary and should
 | 
			
		||||
		/// not be stored or used to identify a cipher.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uuidCipher">UUID of the cipher.</param>
 | 
			
		||||
		/// <returns>Index of the requested cipher. Returns <c>-1</c> if
 | 
			
		||||
		/// the specified cipher is not found.</returns>
 | 
			
		||||
		public int GetCipherIndex(PwUuid uuidCipher)
 | 
			
		||||
		{
 | 
			
		||||
			for(int i = 0; i < m_vCiphers.Count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_vCiphers[i].CipherUuid.EqualsValue(uuidCipher))
 | 
			
		||||
					return i;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the index of a cipher. This index is temporary and should
 | 
			
		||||
		/// not be stored or used to identify a cipher.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strDisplayName">Name of the cipher. Note that
 | 
			
		||||
		/// multiple ciphers can have the same name. In this case, the
 | 
			
		||||
		/// first matching cipher is returned.</param>
 | 
			
		||||
		/// <returns>Cipher with the specified name or <c>-1</c> if
 | 
			
		||||
		/// no cipher with that name is found.</returns>
 | 
			
		||||
		public int GetCipherIndex(string strDisplayName)
 | 
			
		||||
		{
 | 
			
		||||
			for(int i = 0; i < m_vCiphers.Count; ++i)
 | 
			
		||||
				if(m_vCiphers[i].DisplayName == strDisplayName)
 | 
			
		||||
					return i;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the number of cipher engines in this pool.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public int EngineCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vCiphers.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the cipher engine at the specified position. Throws
 | 
			
		||||
		/// an exception if the index is invalid. You can use this
 | 
			
		||||
		/// to iterate over all ciphers, but do not use it to
 | 
			
		||||
		/// identify ciphers.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="nIndex">Index of the requested cipher engine.</param>
 | 
			
		||||
		/// <returns>Reference to the cipher engine at the specified
 | 
			
		||||
		/// position.</returns>
 | 
			
		||||
		public ICipherEngine this[int nIndex]
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if((nIndex < 0) || (nIndex >= m_vCiphers.Count))
 | 
			
		||||
					throw new ArgumentOutOfRangeException("nIndex");
 | 
			
		||||
 | 
			
		||||
				return m_vCiphers[nIndex];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/KeePassLib2Android/Cryptography/Cipher/ICipherEngine.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/KeePassLib2Android/Cryptography/Cipher/ICipherEngine.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.Cipher
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Interface of an encryption/decryption class.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface ICipherEngine
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// UUID of the engine. If you want to write an engine/plugin,
 | 
			
		||||
		/// please contact the KeePass team to obtain a new UUID.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		PwUuid CipherUuid
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// String displayed in the list of available encryption/decryption
 | 
			
		||||
		/// engines in the GUI.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		string DisplayName
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Encrypt a stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="sPlainText">Stream to read the plain-text from.</param>
 | 
			
		||||
		/// <param name="pbKey">Key to use.</param>
 | 
			
		||||
		/// <param name="pbIV">Initialization vector.</param>
 | 
			
		||||
		/// <returns>Stream, from which the encrypted data can be read.</returns>
 | 
			
		||||
		Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Decrypt a stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="sEncrypted">Stream to read the encrypted data from.</param>
 | 
			
		||||
		/// <param name="pbKey">Key to use.</param>
 | 
			
		||||
		/// <param name="pbIV">Initialization vector.</param>
 | 
			
		||||
		/// <returns>Stream, from which the decrypted data can be read.</returns>
 | 
			
		||||
		Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										188
									
								
								src/KeePassLib2Android/Cryptography/Cipher/Salsa20Cipher.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								src/KeePassLib2Android/Cryptography/Cipher/Salsa20Cipher.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Implementation of the Salsa20 cipher, based on the eSTREAM submission.
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.Cipher
 | 
			
		||||
{
 | 
			
		||||
	public sealed class Salsa20Cipher
 | 
			
		||||
	{
 | 
			
		||||
		private uint[] m_state = new uint[16];
 | 
			
		||||
		private uint[] m_x = new uint[16]; // Working buffer
 | 
			
		||||
 | 
			
		||||
		private byte[] m_output = new byte[64];
 | 
			
		||||
		private int m_outputPos = 64;
 | 
			
		||||
 | 
			
		||||
		private static readonly uint[] m_sigma = new uint[4]{
 | 
			
		||||
			0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		public Salsa20Cipher(byte[] pbKey32, byte[] pbIV8)
 | 
			
		||||
		{
 | 
			
		||||
			KeySetup(pbKey32);
 | 
			
		||||
			IvSetup(pbIV8);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		~Salsa20Cipher()
 | 
			
		||||
		{
 | 
			
		||||
			// Clear sensitive data
 | 
			
		||||
			Array.Clear(m_state, 0, m_state.Length);
 | 
			
		||||
			Array.Clear(m_x, 0, m_x.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void NextOutput()
 | 
			
		||||
		{
 | 
			
		||||
			uint[] x = m_x; // Local alias for working buffer
 | 
			
		||||
 | 
			
		||||
			// Compiler/runtime might remove array bound checks after this
 | 
			
		||||
			if(x.Length < 16) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			Array.Copy(m_state, x, 16);
 | 
			
		||||
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				for(int i = 0; i < 10; ++i) // (int i = 20; i > 0; i -= 2)
 | 
			
		||||
				{
 | 
			
		||||
					x[ 4] ^= Rotl32(x[ 0] + x[12],  7);
 | 
			
		||||
					x[ 8] ^= Rotl32(x[ 4] + x[ 0],  9);
 | 
			
		||||
					x[12] ^= Rotl32(x[ 8] + x[ 4], 13);
 | 
			
		||||
					x[ 0] ^= Rotl32(x[12] + x[ 8], 18);
 | 
			
		||||
					x[ 9] ^= Rotl32(x[ 5] + x[ 1],  7);
 | 
			
		||||
					x[13] ^= Rotl32(x[ 9] + x[ 5],  9);
 | 
			
		||||
					x[ 1] ^= Rotl32(x[13] + x[ 9], 13);
 | 
			
		||||
					x[ 5] ^= Rotl32(x[ 1] + x[13], 18);
 | 
			
		||||
					x[14] ^= Rotl32(x[10] + x[ 6],  7);
 | 
			
		||||
					x[ 2] ^= Rotl32(x[14] + x[10],  9);
 | 
			
		||||
					x[ 6] ^= Rotl32(x[ 2] + x[14], 13);
 | 
			
		||||
					x[10] ^= Rotl32(x[ 6] + x[ 2], 18);
 | 
			
		||||
					x[ 3] ^= Rotl32(x[15] + x[11],  7);
 | 
			
		||||
					x[ 7] ^= Rotl32(x[ 3] + x[15],  9);
 | 
			
		||||
					x[11] ^= Rotl32(x[ 7] + x[ 3], 13);
 | 
			
		||||
					x[15] ^= Rotl32(x[11] + x[ 7], 18);
 | 
			
		||||
					x[ 1] ^= Rotl32(x[ 0] + x[ 3],  7);
 | 
			
		||||
					x[ 2] ^= Rotl32(x[ 1] + x[ 0],  9);
 | 
			
		||||
					x[ 3] ^= Rotl32(x[ 2] + x[ 1], 13);
 | 
			
		||||
					x[ 0] ^= Rotl32(x[ 3] + x[ 2], 18);
 | 
			
		||||
					x[ 6] ^= Rotl32(x[ 5] + x[ 4],  7);
 | 
			
		||||
					x[ 7] ^= Rotl32(x[ 6] + x[ 5],  9);
 | 
			
		||||
					x[ 4] ^= Rotl32(x[ 7] + x[ 6], 13);
 | 
			
		||||
					x[ 5] ^= Rotl32(x[ 4] + x[ 7], 18);
 | 
			
		||||
					x[11] ^= Rotl32(x[10] + x[ 9],  7);
 | 
			
		||||
					x[ 8] ^= Rotl32(x[11] + x[10],  9);
 | 
			
		||||
					x[ 9] ^= Rotl32(x[ 8] + x[11], 13);
 | 
			
		||||
					x[10] ^= Rotl32(x[ 9] + x[ 8], 18);
 | 
			
		||||
					x[12] ^= Rotl32(x[15] + x[14],  7);
 | 
			
		||||
					x[13] ^= Rotl32(x[12] + x[15],  9);
 | 
			
		||||
					x[14] ^= Rotl32(x[13] + x[12], 13);
 | 
			
		||||
					x[15] ^= Rotl32(x[14] + x[13], 18);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				for(int i = 0; i < 16; ++i)
 | 
			
		||||
					x[i] += m_state[i];
 | 
			
		||||
 | 
			
		||||
				for(int i = 0; i < 16; ++i)
 | 
			
		||||
				{
 | 
			
		||||
					m_output[i << 2] = (byte)x[i];
 | 
			
		||||
					m_output[(i << 2) + 1] = (byte)(x[i] >> 8);
 | 
			
		||||
					m_output[(i << 2) + 2] = (byte)(x[i] >> 16);
 | 
			
		||||
					m_output[(i << 2) + 3] = (byte)(x[i] >> 24);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				m_outputPos = 0;
 | 
			
		||||
				++m_state[8];
 | 
			
		||||
				if(m_state[8] == 0) ++m_state[9];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static uint Rotl32(uint x, int b)
 | 
			
		||||
		{
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				return ((x << b) | (x >> (32 - b)));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static uint U8To32Little(byte[] pb, int iOffset)
 | 
			
		||||
		{
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				return ((uint)pb[iOffset] | ((uint)pb[iOffset + 1] << 8) |
 | 
			
		||||
					((uint)pb[iOffset + 2] << 16) | ((uint)pb[iOffset + 3] << 24));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void KeySetup(byte[] k)
 | 
			
		||||
		{
 | 
			
		||||
			if(k == null) throw new ArgumentNullException("k");
 | 
			
		||||
			if(k.Length != 32) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			m_state[1] = U8To32Little(k, 0);
 | 
			
		||||
			m_state[2] = U8To32Little(k, 4);
 | 
			
		||||
			m_state[3] = U8To32Little(k, 8);
 | 
			
		||||
			m_state[4] = U8To32Little(k, 12);
 | 
			
		||||
			m_state[11] = U8To32Little(k, 16);
 | 
			
		||||
			m_state[12] = U8To32Little(k, 20);
 | 
			
		||||
			m_state[13] = U8To32Little(k, 24);
 | 
			
		||||
			m_state[14] = U8To32Little(k, 28);
 | 
			
		||||
			m_state[0] = m_sigma[0];
 | 
			
		||||
			m_state[5] = m_sigma[1];
 | 
			
		||||
			m_state[10] = m_sigma[2];
 | 
			
		||||
			m_state[15] = m_sigma[3];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void IvSetup(byte[] pbIV)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbIV == null) throw new ArgumentNullException("pbIV");
 | 
			
		||||
			if(pbIV.Length != 8) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			m_state[6] = U8To32Little(pbIV, 0);
 | 
			
		||||
			m_state[7] = U8To32Little(pbIV, 4);
 | 
			
		||||
			m_state[8] = 0;
 | 
			
		||||
			m_state[9] = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Encrypt(byte[] m, int nByteCount, bool bXor)
 | 
			
		||||
		{
 | 
			
		||||
			if(m == null) throw new ArgumentNullException("m");
 | 
			
		||||
			if(nByteCount > m.Length) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			int nBytesRem = nByteCount, nOffset = 0;
 | 
			
		||||
			while(nBytesRem > 0)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert((m_outputPos >= 0) && (m_outputPos <= 64));
 | 
			
		||||
				if(m_outputPos == 64) NextOutput();
 | 
			
		||||
				Debug.Assert(m_outputPos < 64);
 | 
			
		||||
 | 
			
		||||
				int nCopy = Math.Min(64 - m_outputPos, nBytesRem);
 | 
			
		||||
 | 
			
		||||
				if(bXor) MemUtil.XorArray(m_output, m_outputPos, m, nOffset, nCopy);
 | 
			
		||||
				else Array.Copy(m_output, m_outputPos, m, nOffset, nCopy);
 | 
			
		||||
 | 
			
		||||
				m_outputPos += nCopy;
 | 
			
		||||
				nBytesRem -= nCopy;
 | 
			
		||||
				nOffset += nCopy;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										140
									
								
								src/KeePassLib2Android/Cryptography/Cipher/StandardAesEngine.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/KeePassLib2Android/Cryptography/Cipher/StandardAesEngine.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.Cipher
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Standard AES cipher implementation.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class StandardAesEngine : ICipherEngine
 | 
			
		||||
	{
 | 
			
		||||
		private const CipherMode m_rCipherMode = CipherMode.CBC;
 | 
			
		||||
		private const PaddingMode m_rCipherPadding = PaddingMode.PKCS7;
 | 
			
		||||
 | 
			
		||||
		private static PwUuid m_uuidAes = null;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// UUID of the cipher engine. This ID uniquely identifies the
 | 
			
		||||
		/// AES engine. Must not be used by other ciphers.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static PwUuid AesUuid
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if(m_uuidAes == null)
 | 
			
		||||
				{
 | 
			
		||||
					m_uuidAes = new PwUuid(new byte[]{
 | 
			
		||||
						0x31, 0xC1, 0xF2, 0xE6, 0xBF, 0x71, 0x43, 0x50,
 | 
			
		||||
						0xBE, 0x58, 0x05, 0x21, 0x6A, 0xFC, 0x5A, 0xFF });
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return m_uuidAes;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the UUID of this cipher engine as <c>PwUuid</c> object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwUuid CipherUuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return StandardAesEngine.AesUuid; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a displayable name describing this cipher engine.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string DisplayName { get { return KLRes.EncAlgorithmAes; } }
 | 
			
		||||
 | 
			
		||||
		private static void ValidateArguments(Stream stream, bool bEncrypt, byte[] pbKey, byte[] pbIV)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(stream != null); if(stream == null) throw new ArgumentNullException("stream");
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey");
 | 
			
		||||
			Debug.Assert(pbKey.Length == 32);
 | 
			
		||||
			if(pbKey.Length != 32) throw new ArgumentException("Key must be 256 bits wide!");
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pbIV != null); if(pbIV == null) throw new ArgumentNullException("pbIV");
 | 
			
		||||
			Debug.Assert(pbIV.Length == 16);
 | 
			
		||||
			if(pbIV.Length != 16) throw new ArgumentException("Initialization vector must be 128 bits wide!");
 | 
			
		||||
 | 
			
		||||
			if(bEncrypt)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(stream.CanWrite);
 | 
			
		||||
				if(stream.CanWrite == false) throw new ArgumentException("Stream must be writable!");
 | 
			
		||||
			}
 | 
			
		||||
			else // Decrypt
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(stream.CanRead);
 | 
			
		||||
				if(stream.CanRead == false) throw new ArgumentException("Encrypted stream must be readable!");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static Stream CreateStream(Stream s, bool bEncrypt, byte[] pbKey, byte[] pbIV)
 | 
			
		||||
		{
 | 
			
		||||
			StandardAesEngine.ValidateArguments(s, bEncrypt, pbKey, pbIV);
 | 
			
		||||
 | 
			
		||||
			RijndaelManaged r = new RijndaelManaged();
 | 
			
		||||
 | 
			
		||||
			if(r.BlockSize != 128) // AES block size
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				r.BlockSize = 128;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			byte[] pbLocalIV = new byte[16];
 | 
			
		||||
			Array.Copy(pbIV, pbLocalIV, 16);
 | 
			
		||||
			r.IV = pbLocalIV;
 | 
			
		||||
 | 
			
		||||
			byte[] pbLocalKey = new byte[32];
 | 
			
		||||
			Array.Copy(pbKey, pbLocalKey, 32);
 | 
			
		||||
			r.KeySize = 256;
 | 
			
		||||
			r.Key = pbLocalKey;
 | 
			
		||||
 | 
			
		||||
			r.Mode = m_rCipherMode;
 | 
			
		||||
			r.Padding = m_rCipherPadding;
 | 
			
		||||
 | 
			
		||||
			ICryptoTransform iTransform = (bEncrypt ? r.CreateEncryptor() : r.CreateDecryptor());
 | 
			
		||||
			Debug.Assert(iTransform != null);
 | 
			
		||||
			if(iTransform == null) throw new SecurityException("Unable to create Rijndael transform!");
 | 
			
		||||
 | 
			
		||||
			return new CryptoStream(s, iTransform, bEncrypt ? CryptoStreamMode.Write :
 | 
			
		||||
				CryptoStreamMode.Read);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV)
 | 
			
		||||
		{
 | 
			
		||||
			return StandardAesEngine.CreateStream(sPlainText, true, pbKey, pbIV);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV)
 | 
			
		||||
		{
 | 
			
		||||
			return StandardAesEngine.CreateStream(sEncrypted, false, pbKey, pbIV);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										283
									
								
								src/KeePassLib2Android/Cryptography/CryptoRandom.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								src/KeePassLib2Android/Cryptography/CryptoRandom.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,283 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Windows.Forms;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Native;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Cryptographically strong random number generator. The returned values
 | 
			
		||||
	/// are unpredictable and cannot be reproduced.
 | 
			
		||||
	/// <c>CryptoRandom</c> is a singleton class.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class CryptoRandom
 | 
			
		||||
	{
 | 
			
		||||
		private byte[] m_pbEntropyPool = new byte[64];
 | 
			
		||||
		private uint m_uCounter;
 | 
			
		||||
		private RNGCryptoServiceProvider m_rng = new RNGCryptoServiceProvider();
 | 
			
		||||
		private ulong m_uGeneratedBytesCount = 0;
 | 
			
		||||
 | 
			
		||||
		private object m_oSyncRoot = new object();
 | 
			
		||||
 | 
			
		||||
		private static CryptoRandom m_pInstance = null;
 | 
			
		||||
		public static CryptoRandom Instance
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if(m_pInstance != null) return m_pInstance;
 | 
			
		||||
 | 
			
		||||
				m_pInstance = new CryptoRandom();
 | 
			
		||||
				return m_pInstance;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the number of random bytes that this instance generated so far.
 | 
			
		||||
		/// Note that this number can be higher than the number of random bytes
 | 
			
		||||
		/// actually requested using the <c>GetRandomBytes</c> method.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ulong GeneratedBytesCount
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				ulong u;
 | 
			
		||||
				lock(m_oSyncRoot) { u = m_uGeneratedBytesCount; }
 | 
			
		||||
				return u;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Event that is triggered whenever the internal <c>GenerateRandom256</c>
 | 
			
		||||
		/// method is called to generate random bytes.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public event EventHandler GenerateRandom256Pre;
 | 
			
		||||
 | 
			
		||||
		private CryptoRandom()
 | 
			
		||||
		{
 | 
			
		||||
			Random r = new Random();
 | 
			
		||||
			m_uCounter = (uint)r.Next();
 | 
			
		||||
 | 
			
		||||
			AddEntropy(GetSystemData(r));
 | 
			
		||||
			AddEntropy(GetCspData());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Update the internal seed of the random number generator based
 | 
			
		||||
		/// on entropy data.
 | 
			
		||||
		/// This method is thread-safe.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbEntropy">Entropy bytes.</param>
 | 
			
		||||
		public void AddEntropy(byte[] pbEntropy)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbEntropy == null) { Debug.Assert(false); return; }
 | 
			
		||||
			if(pbEntropy.Length == 0) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			byte[] pbNewData = pbEntropy;
 | 
			
		||||
			if(pbEntropy.Length >= 64)
 | 
			
		||||
			{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				SHA512Managed shaNew = new SHA512Managed();
 | 
			
		||||
#else
 | 
			
		||||
				SHA256Managed shaNew = new SHA256Managed();
 | 
			
		||||
#endif
 | 
			
		||||
				pbNewData = shaNew.ComputeHash(pbEntropy);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			MemoryStream ms = new MemoryStream();
 | 
			
		||||
			lock(m_oSyncRoot)
 | 
			
		||||
			{
 | 
			
		||||
				ms.Write(m_pbEntropyPool, 0, m_pbEntropyPool.Length);
 | 
			
		||||
				ms.Write(pbNewData, 0, pbNewData.Length);
 | 
			
		||||
 | 
			
		||||
				byte[] pbFinal = ms.ToArray();
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				Debug.Assert(pbFinal.Length == (64 + pbNewData.Length));
 | 
			
		||||
				SHA512Managed shaPool = new SHA512Managed();
 | 
			
		||||
#else
 | 
			
		||||
				SHA256Managed shaPool = new SHA256Managed();
 | 
			
		||||
#endif
 | 
			
		||||
				m_pbEntropyPool = shaPool.ComputeHash(pbFinal);
 | 
			
		||||
			}
 | 
			
		||||
			ms.Close();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static byte[] GetSystemData(Random rWeak)
 | 
			
		||||
		{
 | 
			
		||||
			MemoryStream ms = new MemoryStream();
 | 
			
		||||
			byte[] pb;
 | 
			
		||||
 | 
			
		||||
			pb = MemUtil.UInt32ToBytes((uint)Environment.TickCount);
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
			pb = TimeUtil.PackTime(DateTime.Now);
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			Point pt = Cursor.Position;
 | 
			
		||||
			pb = MemUtil.UInt32ToBytes((uint)pt.X);
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
			pb = MemUtil.UInt32ToBytes((uint)pt.Y);
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			pb = MemUtil.UInt32ToBytes((uint)rWeak.Next());
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
			pb = MemUtil.UInt32ToBytes((uint)NativeLib.GetPlatformID());
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				pb = MemUtil.UInt32ToBytes((uint)Environment.ProcessorCount);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)Environment.WorkingSet);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
				Version v = Environment.OSVersion.Version;
 | 
			
		||||
				int nv = (v.Major << 28) + (v.MajorRevision << 24) +
 | 
			
		||||
					(v.Minor << 20) + (v.MinorRevision << 16) +
 | 
			
		||||
					(v.Revision << 12) + v.Build;
 | 
			
		||||
				pb = MemUtil.UInt32ToBytes((uint)nv);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
				Process p = Process.GetCurrentProcess();
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.Handle.ToInt64());
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt32ToBytes((uint)p.HandleCount);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt32ToBytes((uint)p.Id);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.NonpagedSystemMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.PagedMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.PagedSystemMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.PeakPagedMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.PeakVirtualMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.PeakWorkingSet64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.PrivateMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.StartTime.ToBinary());
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.VirtualMemorySize64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
				pb = MemUtil.UInt64ToBytes((ulong)p.WorkingSet64);
 | 
			
		||||
				ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
				// Not supported in Mono 1.2.6:
 | 
			
		||||
				// pb = MemUtil.UInt32ToBytes((uint)p.SessionId);
 | 
			
		||||
				// ms.Write(pb, 0, pb.Length);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			pb = Guid.NewGuid().ToByteArray();
 | 
			
		||||
			ms.Write(pb, 0, pb.Length);
 | 
			
		||||
 | 
			
		||||
			byte[] pbAll = ms.ToArray();
 | 
			
		||||
			ms.Close();
 | 
			
		||||
			return pbAll;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private byte[] GetCspData()
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbCspRandom = new byte[32];
 | 
			
		||||
			m_rng.GetBytes(pbCspRandom);
 | 
			
		||||
			return pbCspRandom;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private byte[] GenerateRandom256()
 | 
			
		||||
		{
 | 
			
		||||
			if(this.GenerateRandom256Pre != null)
 | 
			
		||||
				this.GenerateRandom256Pre(this, EventArgs.Empty);
 | 
			
		||||
 | 
			
		||||
			byte[] pbFinal;
 | 
			
		||||
			lock(m_oSyncRoot)
 | 
			
		||||
			{
 | 
			
		||||
				unchecked { m_uCounter += 386047; } // Prime number
 | 
			
		||||
				byte[] pbCounter = MemUtil.UInt32ToBytes(m_uCounter);
 | 
			
		||||
 | 
			
		||||
				byte[] pbCspRandom = GetCspData();
 | 
			
		||||
 | 
			
		||||
				MemoryStream ms = new MemoryStream();
 | 
			
		||||
				ms.Write(m_pbEntropyPool, 0, m_pbEntropyPool.Length);
 | 
			
		||||
				ms.Write(pbCounter, 0, pbCounter.Length);
 | 
			
		||||
				ms.Write(pbCspRandom, 0, pbCspRandom.Length);
 | 
			
		||||
				pbFinal = ms.ToArray();
 | 
			
		||||
				Debug.Assert(pbFinal.Length == (m_pbEntropyPool.Length +
 | 
			
		||||
					pbCounter.Length + pbCspRandom.Length));
 | 
			
		||||
				ms.Close();
 | 
			
		||||
 | 
			
		||||
				m_uGeneratedBytesCount += 32;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			return sha256.ComputeHash(pbFinal);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a number of cryptographically strong random bytes.
 | 
			
		||||
		/// This method is thread-safe.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uRequestedBytes">Number of requested random bytes.</param>
 | 
			
		||||
		/// <returns>A byte array consisting of <paramref name="uRequestedBytes" />
 | 
			
		||||
		/// random bytes.</returns>
 | 
			
		||||
		public byte[] GetRandomBytes(uint uRequestedBytes)
 | 
			
		||||
		{
 | 
			
		||||
			if(uRequestedBytes == 0) return new byte[0]; // Allow zero-length array
 | 
			
		||||
 | 
			
		||||
			byte[] pbRes = new byte[uRequestedBytes];
 | 
			
		||||
			long lPos = 0;
 | 
			
		||||
 | 
			
		||||
			while(uRequestedBytes != 0)
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbRandom256 = GenerateRandom256();
 | 
			
		||||
				Debug.Assert(pbRandom256.Length == 32);
 | 
			
		||||
 | 
			
		||||
				long lCopy = (long)((uRequestedBytes < 32) ? uRequestedBytes : 32);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				Array.Copy(pbRandom256, 0, pbRes, lPos, lCopy);
 | 
			
		||||
#else
 | 
			
		||||
				Array.Copy(pbRandom256, 0, pbRes, (int)lPos, (int)lCopy);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				lPos += lCopy;
 | 
			
		||||
				uRequestedBytes -= (uint)lCopy;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug.Assert((int)lPos == pbRes.Length);
 | 
			
		||||
			return pbRes;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										209
									
								
								src/KeePassLib2Android/Cryptography/CryptoRandomStream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								src/KeePassLib2Android/Cryptography/CryptoRandomStream.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,209 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography.Cipher;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Algorithms supported by <c>CryptoRandomStream</c>.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum CrsAlgorithm
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Not supported.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Null = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A variant of the ARCFour algorithm (RC4 incompatible).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		ArcFourVariant = 1,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Salsa20 stream cipher algorithm.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Salsa20 = 2,
 | 
			
		||||
 | 
			
		||||
		Count = 3
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A random stream class. The class is initialized using random
 | 
			
		||||
	/// bytes provided by the caller. The produced stream has random
 | 
			
		||||
	/// properties, but for the same seed always the same stream
 | 
			
		||||
	/// is produced, i.e. this class can be used as stream cipher.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class CryptoRandomStream
 | 
			
		||||
	{
 | 
			
		||||
		private CrsAlgorithm m_crsAlgorithm;
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbState = null;
 | 
			
		||||
		private byte m_i = 0;
 | 
			
		||||
		private byte m_j = 0;
 | 
			
		||||
 | 
			
		||||
		private Salsa20Cipher m_salsa20 = null;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new cryptographically secure random stream object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="genAlgorithm">Algorithm to use.</param>
 | 
			
		||||
		/// <param name="pbKey">Initialization key. Must not be <c>null</c> and
 | 
			
		||||
		/// must contain at least 1 byte.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the
 | 
			
		||||
		/// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
 | 
			
		||||
		/// <exception cref="System.ArgumentException">Thrown if the
 | 
			
		||||
		/// <paramref name="pbKey" /> parameter contains no bytes or the
 | 
			
		||||
		/// algorithm is unknown.</exception>
 | 
			
		||||
		public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
 | 
			
		||||
		{
 | 
			
		||||
			m_crsAlgorithm = genAlgorithm;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey");
 | 
			
		||||
 | 
			
		||||
			uint uKeyLen = (uint)pbKey.Length;
 | 
			
		||||
			Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			if(genAlgorithm == CrsAlgorithm.ArcFourVariant)
 | 
			
		||||
			{
 | 
			
		||||
				// Fill the state linearly
 | 
			
		||||
				m_pbState = new byte[256];
 | 
			
		||||
				for(uint w = 0; w < 256; ++w) m_pbState[w] = (byte)w;
 | 
			
		||||
 | 
			
		||||
				unchecked
 | 
			
		||||
				{
 | 
			
		||||
					byte j = 0, t;
 | 
			
		||||
					uint inxKey = 0;
 | 
			
		||||
					for(uint w = 0; w < 256; ++w) // Key setup
 | 
			
		||||
					{
 | 
			
		||||
						j += (byte)(m_pbState[w] + pbKey[inxKey]);
 | 
			
		||||
 | 
			
		||||
						t = m_pbState[0]; // Swap entries
 | 
			
		||||
						m_pbState[0] = m_pbState[j];
 | 
			
		||||
						m_pbState[j] = t;
 | 
			
		||||
 | 
			
		||||
						++inxKey;
 | 
			
		||||
						if(inxKey >= uKeyLen) inxKey = 0;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				GetRandomBytes(512); // Increases security, see cryptanalysis
 | 
			
		||||
			}
 | 
			
		||||
			else if(genAlgorithm == CrsAlgorithm.Salsa20)
 | 
			
		||||
			{
 | 
			
		||||
				SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
				byte[] pbKey32 = sha256.ComputeHash(pbKey);
 | 
			
		||||
				byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B,
 | 
			
		||||
					0x97, 0x20, 0x5D, 0x2A }; // Unique constant
 | 
			
		||||
 | 
			
		||||
				m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
 | 
			
		||||
			}
 | 
			
		||||
			else // Unknown algorithm
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				throw new ArgumentException();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get <paramref name="uRequestedCount" /> random bytes.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uRequestedCount">Number of random bytes to retrieve.</param>
 | 
			
		||||
		/// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns>
 | 
			
		||||
		public byte[] GetRandomBytes(uint uRequestedCount)
 | 
			
		||||
		{
 | 
			
		||||
			if(uRequestedCount == 0) return new byte[0];
 | 
			
		||||
 | 
			
		||||
			byte[] pbRet = new byte[uRequestedCount];
 | 
			
		||||
 | 
			
		||||
			if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant)
 | 
			
		||||
			{
 | 
			
		||||
				unchecked
 | 
			
		||||
				{
 | 
			
		||||
					for(uint w = 0; w < uRequestedCount; ++w)
 | 
			
		||||
					{
 | 
			
		||||
						++m_i;
 | 
			
		||||
						m_j += m_pbState[m_i];
 | 
			
		||||
 | 
			
		||||
						byte t = m_pbState[m_i]; // Swap entries
 | 
			
		||||
						m_pbState[m_i] = m_pbState[m_j];
 | 
			
		||||
						m_pbState[m_j] = t;
 | 
			
		||||
 | 
			
		||||
						t = (byte)(m_pbState[m_i] + m_pbState[m_j]);
 | 
			
		||||
						pbRet[w] = m_pbState[t];
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if(m_crsAlgorithm == CrsAlgorithm.Salsa20)
 | 
			
		||||
				m_salsa20.Encrypt(pbRet, pbRet.Length, false);
 | 
			
		||||
			else { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return pbRet;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ulong GetRandomUInt64()
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = GetRandomBytes(8);
 | 
			
		||||
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				return ((ulong)pb[0]) | ((ulong)pb[1] << 8) |
 | 
			
		||||
					((ulong)pb[2] << 16) | ((ulong)pb[3] << 24) |
 | 
			
		||||
					((ulong)pb[4] << 32) | ((ulong)pb[5] << 40) |
 | 
			
		||||
					((ulong)pb[6] << 48) | ((ulong)pb[7] << 56);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if CRSBENCHMARK
 | 
			
		||||
		public static string Benchmark()
 | 
			
		||||
		{
 | 
			
		||||
			int nRounds = 2000000;
 | 
			
		||||
			
 | 
			
		||||
			string str = "ArcFour small: " + BenchTime(CrsAlgorithm.ArcFourVariant,
 | 
			
		||||
				nRounds, 16).ToString() + "\r\n";
 | 
			
		||||
			str += "ArcFour big: " + BenchTime(CrsAlgorithm.ArcFourVariant,
 | 
			
		||||
				32, 2 * 1024 * 1024).ToString() + "\r\n";
 | 
			
		||||
			str += "Salsa20 small: " + BenchTime(CrsAlgorithm.Salsa20,
 | 
			
		||||
				nRounds, 16).ToString() + "\r\n";
 | 
			
		||||
			str += "Salsa20 big: " + BenchTime(CrsAlgorithm.Salsa20,
 | 
			
		||||
				32, 2 * 1024 * 1024).ToString();
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static int BenchTime(CrsAlgorithm cra, int nRounds, int nDataSize)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbKey = new byte[4] { 0x00, 0x01, 0x02, 0x03 };
 | 
			
		||||
 | 
			
		||||
			int nStart = Environment.TickCount;
 | 
			
		||||
			for(int i = 0; i < nRounds; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				CryptoRandomStream c = new CryptoRandomStream(cra, pbKey);
 | 
			
		||||
				c.GetRandomBytes((uint)nDataSize);
 | 
			
		||||
			}
 | 
			
		||||
			int nEnd = Environment.TickCount;
 | 
			
		||||
 | 
			
		||||
			return (nEnd - nStart);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										180
									
								
								src/KeePassLib2Android/Cryptography/HashingStreamEx.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								src/KeePassLib2Android/Cryptography/HashingStreamEx.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	public sealed class HashingStreamEx : Stream
 | 
			
		||||
	{
 | 
			
		||||
		private Stream m_sBaseStream;
 | 
			
		||||
		private bool m_bWriting;
 | 
			
		||||
		private HashAlgorithm m_hash;
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbFinalHash = null;
 | 
			
		||||
 | 
			
		||||
		public byte[] Hash
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbFinalHash; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool CanRead
 | 
			
		||||
		{
 | 
			
		||||
			get { return !m_bWriting; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool CanSeek
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool CanWrite
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bWriting; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override long Length
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_sBaseStream.Length; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override long Position
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_sBaseStream.Position; }
 | 
			
		||||
			set { throw new NotSupportedException(); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public HashingStreamEx(Stream sBaseStream, bool bWriting, HashAlgorithm hashAlgorithm)
 | 
			
		||||
		{
 | 
			
		||||
			if(sBaseStream == null) throw new ArgumentNullException("sBaseStream");
 | 
			
		||||
 | 
			
		||||
			m_sBaseStream = sBaseStream;
 | 
			
		||||
			m_bWriting = bWriting;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			m_hash = (hashAlgorithm ?? new SHA256Managed());
 | 
			
		||||
#else // KeePassLibSD
 | 
			
		||||
			m_hash = null;
 | 
			
		||||
 | 
			
		||||
			try { m_hash = HashAlgorithm.Create("SHA256"); }
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
			try { if(m_hash == null) m_hash = HashAlgorithm.Create(); }
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
#endif
 | 
			
		||||
			if(m_hash == null) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			// Validate hash algorithm
 | 
			
		||||
			if((!m_hash.CanReuseTransform) || (!m_hash.CanTransformMultipleBlocks) ||
 | 
			
		||||
				(m_hash.InputBlockSize != 1) || (m_hash.OutputBlockSize != 1))
 | 
			
		||||
			{
 | 
			
		||||
#if DEBUG
 | 
			
		||||
				MessageService.ShowWarning("Broken HashAlgorithm object in HashingStreamEx.");
 | 
			
		||||
#endif
 | 
			
		||||
				m_hash = null;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Flush()
 | 
			
		||||
		{
 | 
			
		||||
			m_sBaseStream.Flush();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Close()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_hash != null)
 | 
			
		||||
			{
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					m_hash.TransformFinalBlock(new byte[0], 0, 0);
 | 
			
		||||
 | 
			
		||||
					m_pbFinalHash = m_hash.Hash;
 | 
			
		||||
				}
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
				m_hash = null;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_sBaseStream.Close();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override long Seek(long lOffset, SeekOrigin soOrigin)
 | 
			
		||||
		{
 | 
			
		||||
			throw new NotSupportedException();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void SetLength(long lValue)
 | 
			
		||||
		{
 | 
			
		||||
			throw new NotSupportedException();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override int Read(byte[] pbBuffer, int nOffset, int nCount)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bWriting) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			int nRead = m_sBaseStream.Read(pbBuffer, nOffset, nCount);
 | 
			
		||||
			int nPartialRead = nRead;
 | 
			
		||||
			while((nRead < nCount) && (nPartialRead != 0))
 | 
			
		||||
			{
 | 
			
		||||
				nPartialRead = m_sBaseStream.Read(pbBuffer, nOffset + nRead,
 | 
			
		||||
					nCount - nRead);
 | 
			
		||||
				nRead += nPartialRead;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			byte[] pbOrg = new byte[pbBuffer.Length];
 | 
			
		||||
			Array.Copy(pbBuffer, pbOrg, pbBuffer.Length);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			if((m_hash != null) && (nRead > 0))
 | 
			
		||||
				m_hash.TransformBlock(pbBuffer, nOffset, nRead, pbBuffer, nOffset);
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			Debug.Assert(MemUtil.ArraysEqual(pbBuffer, pbOrg));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return nRead;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Write(byte[] pbBuffer, int nOffset, int nCount)
 | 
			
		||||
		{
 | 
			
		||||
			if(!m_bWriting) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			byte[] pbOrg = new byte[pbBuffer.Length];
 | 
			
		||||
			Array.Copy(pbBuffer, pbOrg, pbBuffer.Length);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			if((m_hash != null) && (nCount > 0))
 | 
			
		||||
				m_hash.TransformBlock(pbBuffer, nOffset, nCount, pbBuffer, nOffset);
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			Debug.Assert(MemUtil.ArraysEqual(pbBuffer, pbOrg));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			m_sBaseStream.Write(pbBuffer, nOffset, nCount);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								src/KeePassLib2Android/Cryptography/HmacOtp.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/KeePassLib2Android/Cryptography/HmacOtp.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Generate HMAC-based one-time passwords as specified in RFC 4226.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class HmacOtp
 | 
			
		||||
	{
 | 
			
		||||
		private static readonly uint[] vDigitsPower = new uint[]{ 1, 10, 100,
 | 
			
		||||
			1000, 10000, 100000, 1000000, 10000000, 100000000 };
 | 
			
		||||
 | 
			
		||||
		public static string Generate(byte[] pbSecret, ulong uFactor,
 | 
			
		||||
			uint uCodeDigits, bool bAddChecksum, int iTruncationOffset)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbText = MemUtil.UInt64ToBytes(uFactor);
 | 
			
		||||
			Array.Reverse(pbText); // Big-Endian
 | 
			
		||||
 | 
			
		||||
			HMACSHA1 hsha1 = new HMACSHA1(pbSecret);
 | 
			
		||||
			byte[] pbHash = hsha1.ComputeHash(pbText);
 | 
			
		||||
 | 
			
		||||
			uint uOffset = (uint)(pbHash[pbHash.Length - 1] & 0xF);
 | 
			
		||||
			if((iTruncationOffset >= 0) && (iTruncationOffset < (pbHash.Length - 4)))
 | 
			
		||||
				uOffset = (uint)iTruncationOffset;
 | 
			
		||||
 | 
			
		||||
			uint uBinary = (uint)(((pbHash[uOffset] & 0x7F) << 24) |
 | 
			
		||||
				((pbHash[uOffset + 1] & 0xFF) << 16) |
 | 
			
		||||
				((pbHash[uOffset + 2] & 0xFF) << 8) |
 | 
			
		||||
				(pbHash[uOffset + 3] & 0xFF));
 | 
			
		||||
 | 
			
		||||
			uint uOtp = (uBinary % vDigitsPower[uCodeDigits]);
 | 
			
		||||
			if(bAddChecksum)
 | 
			
		||||
				uOtp = ((uOtp * 10) + CalculateChecksum(uOtp, uCodeDigits));
 | 
			
		||||
 | 
			
		||||
			uint uDigits = (bAddChecksum ? (uCodeDigits + 1) : uCodeDigits);
 | 
			
		||||
			return uOtp.ToString().PadLeft((int)uDigits, '0');
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static readonly uint[] vDoubleDigits = new uint[]{ 0, 2, 4, 6, 8,
 | 
			
		||||
			1, 3, 5, 7, 9 };
 | 
			
		||||
 | 
			
		||||
		private static uint CalculateChecksum(uint uNum, uint uDigits)
 | 
			
		||||
		{
 | 
			
		||||
			bool bDoubleDigit = true;
 | 
			
		||||
			uint uTotal = 0;
 | 
			
		||||
 | 
			
		||||
			while(0 < uDigits--)
 | 
			
		||||
			{
 | 
			
		||||
				uint uDigit = (uNum % 10);
 | 
			
		||||
				uNum /= 10;
 | 
			
		||||
 | 
			
		||||
				if(bDoubleDigit) uDigit = vDoubleDigits[uDigit];
 | 
			
		||||
 | 
			
		||||
				uTotal += uDigit;
 | 
			
		||||
				bDoubleDigit = !bDoubleDigit;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			uint uResult = (uTotal % 10);
 | 
			
		||||
			if(uResult != 0) uResult = 10 - uResult;
 | 
			
		||||
 | 
			
		||||
			return uResult;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -0,0 +1,65 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	internal static class CharSetBasedGenerator
 | 
			
		||||
	{
 | 
			
		||||
		internal static PwgError Generate(out ProtectedString psOut,
 | 
			
		||||
			PwProfile pwProfile, CryptoRandomStream crsRandomSource)
 | 
			
		||||
		{
 | 
			
		||||
			psOut = ProtectedString.Empty;
 | 
			
		||||
			if(pwProfile.Length == 0) return PwgError.Success;
 | 
			
		||||
 | 
			
		||||
			PwCharSet pcs = new PwCharSet(pwProfile.CharSet.ToString());
 | 
			
		||||
			char[] vGenerated = new char[pwProfile.Length];
 | 
			
		||||
 | 
			
		||||
			PwGenerator.PrepareCharSet(pcs, pwProfile);
 | 
			
		||||
 | 
			
		||||
			for(int nIndex = 0; nIndex < (int)pwProfile.Length; ++nIndex)
 | 
			
		||||
			{
 | 
			
		||||
				char ch = PwGenerator.GenerateCharacter(pwProfile, pcs,
 | 
			
		||||
					crsRandomSource);
 | 
			
		||||
 | 
			
		||||
				if(ch == char.MinValue)
 | 
			
		||||
				{
 | 
			
		||||
					Array.Clear(vGenerated, 0, vGenerated.Length);
 | 
			
		||||
					return PwgError.TooFewCharacters;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				vGenerated[nIndex] = ch;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vGenerated);
 | 
			
		||||
			psOut = new ProtectedString(true, pbUtf8);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbUtf8);
 | 
			
		||||
			Array.Clear(vGenerated, 0, vGenerated.Length);
 | 
			
		||||
 | 
			
		||||
			return PwgError.Success;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	public abstract class CustomPwGenerator
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Each custom password generation algorithm must have
 | 
			
		||||
		/// its own unique UUID.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public abstract PwUuid Uuid { get; }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Displayable name of the password generation algorithm.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public abstract string Name { get; }
 | 
			
		||||
 | 
			
		||||
		public virtual bool SupportsOptions
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Password generation function.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="prf">Password generation options chosen
 | 
			
		||||
		/// by the user. This may be <c>null</c>, if the default
 | 
			
		||||
		/// options should be used.</param>
 | 
			
		||||
		/// <param name="crsRandomSource">Source that the algorithm
 | 
			
		||||
		/// can use to generate random numbers.</param>
 | 
			
		||||
		/// <returns>Generated password or <c>null</c> in case
 | 
			
		||||
		/// of failure. If returning <c>null</c>, the caller assumes
 | 
			
		||||
		/// that an error message has already been shown to the user.</returns>
 | 
			
		||||
		public abstract ProtectedString Generate(PwProfile prf,
 | 
			
		||||
			CryptoRandomStream crsRandomSource);
 | 
			
		||||
 | 
			
		||||
		public virtual string GetOptions(string strCurrentOptions)
 | 
			
		||||
		{
 | 
			
		||||
			return string.Empty;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,110 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	public sealed class CustomPwGeneratorPool : IEnumerable<CustomPwGenerator>
 | 
			
		||||
	{
 | 
			
		||||
		private List<CustomPwGenerator> m_vGens = new List<CustomPwGenerator>();
 | 
			
		||||
 | 
			
		||||
		public int Count
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vGens.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public CustomPwGeneratorPool()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vGens.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<CustomPwGenerator> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vGens.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(CustomPwGenerator pwg)
 | 
			
		||||
		{
 | 
			
		||||
			if(pwg == null) throw new ArgumentNullException("pwg");
 | 
			
		||||
 | 
			
		||||
			PwUuid uuid = pwg.Uuid;
 | 
			
		||||
			if(uuid == null) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			int nIndex = FindIndex(uuid);
 | 
			
		||||
 | 
			
		||||
			if(nIndex >= 0) m_vGens[nIndex] = pwg; // Replace
 | 
			
		||||
			else m_vGens.Add(pwg);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public CustomPwGenerator Find(PwUuid uuid)
 | 
			
		||||
		{
 | 
			
		||||
			if(uuid == null) throw new ArgumentNullException("uuid");
 | 
			
		||||
 | 
			
		||||
			foreach(CustomPwGenerator pwg in m_vGens)
 | 
			
		||||
			{
 | 
			
		||||
				if(uuid.EqualsValue(pwg.Uuid)) return pwg;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public CustomPwGenerator Find(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			foreach(CustomPwGenerator pwg in m_vGens)
 | 
			
		||||
			{
 | 
			
		||||
				if(pwg.Name == strName) return pwg;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private int FindIndex(PwUuid uuid)
 | 
			
		||||
		{
 | 
			
		||||
			if(uuid == null) throw new ArgumentNullException("uuid");
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_vGens.Count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(uuid.EqualsValue(m_vGens[i].Uuid)) return i;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Remove(PwUuid uuid)
 | 
			
		||||
		{
 | 
			
		||||
			if(uuid == null) throw new ArgumentNullException("uuid");
 | 
			
		||||
 | 
			
		||||
			int nIndex = FindIndex(uuid);
 | 
			
		||||
			if(nIndex < 0) return false;
 | 
			
		||||
 | 
			
		||||
			m_vGens.RemoveAt(nIndex);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,173 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	internal static class PatternBasedGenerator
 | 
			
		||||
	{
 | 
			
		||||
		internal static PwgError Generate(out ProtectedString psOut,
 | 
			
		||||
			PwProfile pwProfile, CryptoRandomStream crsRandomSource)
 | 
			
		||||
		{
 | 
			
		||||
			psOut = ProtectedString.Empty;
 | 
			
		||||
			LinkedList<char> vGenerated = new LinkedList<char>();
 | 
			
		||||
			PwCharSet pcsCurrent = new PwCharSet();
 | 
			
		||||
			PwCharSet pcsCustom = new PwCharSet();
 | 
			
		||||
			PwCharSet pcsUsed = new PwCharSet();
 | 
			
		||||
			bool bInCharSetDef = false;
 | 
			
		||||
 | 
			
		||||
			string strPattern = ExpandPattern(pwProfile.Pattern);
 | 
			
		||||
			if(strPattern.Length == 0) return PwgError.Success;
 | 
			
		||||
 | 
			
		||||
			CharStream csStream = new CharStream(strPattern);
 | 
			
		||||
			char ch = csStream.ReadChar();
 | 
			
		||||
 | 
			
		||||
			while(ch != char.MinValue)
 | 
			
		||||
			{
 | 
			
		||||
				pcsCurrent.Clear();
 | 
			
		||||
 | 
			
		||||
				bool bGenerateChar = false;
 | 
			
		||||
 | 
			
		||||
				if(ch == '\\')
 | 
			
		||||
				{
 | 
			
		||||
					ch = csStream.ReadChar();
 | 
			
		||||
					if(ch == char.MinValue) // Backslash at the end
 | 
			
		||||
					{
 | 
			
		||||
						vGenerated.AddLast('\\');
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if(bInCharSetDef) pcsCustom.Add(ch);
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						vGenerated.AddLast(ch);
 | 
			
		||||
						pcsUsed.Add(ch);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else if(ch == '[')
 | 
			
		||||
				{
 | 
			
		||||
					pcsCustom.Clear();
 | 
			
		||||
					bInCharSetDef = true;
 | 
			
		||||
				}
 | 
			
		||||
				else if(ch == ']')
 | 
			
		||||
				{
 | 
			
		||||
					pcsCurrent.Add(pcsCustom.ToString());
 | 
			
		||||
 | 
			
		||||
					bInCharSetDef = false;
 | 
			
		||||
					bGenerateChar = true;
 | 
			
		||||
				}
 | 
			
		||||
				else if(bInCharSetDef)
 | 
			
		||||
				{
 | 
			
		||||
					if(pcsCustom.AddCharSet(ch) == false)
 | 
			
		||||
						pcsCustom.Add(ch);
 | 
			
		||||
				}
 | 
			
		||||
				else if(pcsCurrent.AddCharSet(ch) == false)
 | 
			
		||||
				{
 | 
			
		||||
					vGenerated.AddLast(ch);
 | 
			
		||||
					pcsUsed.Add(ch);
 | 
			
		||||
				}
 | 
			
		||||
				else bGenerateChar = true;
 | 
			
		||||
 | 
			
		||||
				if(bGenerateChar)
 | 
			
		||||
				{
 | 
			
		||||
					PwGenerator.PrepareCharSet(pcsCurrent, pwProfile);
 | 
			
		||||
 | 
			
		||||
					if(pwProfile.NoRepeatingCharacters)
 | 
			
		||||
						pcsCurrent.Remove(pcsUsed.ToString());
 | 
			
		||||
 | 
			
		||||
					char chGen = PwGenerator.GenerateCharacter(pwProfile,
 | 
			
		||||
						pcsCurrent, crsRandomSource);
 | 
			
		||||
 | 
			
		||||
					if(chGen == char.MinValue) return PwgError.TooFewCharacters;
 | 
			
		||||
 | 
			
		||||
					vGenerated.AddLast(chGen);
 | 
			
		||||
					pcsUsed.Add(chGen);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ch = csStream.ReadChar();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(vGenerated.Count == 0) return PwgError.Success;
 | 
			
		||||
 | 
			
		||||
			char[] vArray = new char[vGenerated.Count];
 | 
			
		||||
			vGenerated.CopyTo(vArray, 0);
 | 
			
		||||
 | 
			
		||||
			if(pwProfile.PatternPermutePassword)
 | 
			
		||||
				PwGenerator.ShufflePassword(vArray, crsRandomSource);
 | 
			
		||||
 | 
			
		||||
			byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vArray);
 | 
			
		||||
			psOut = new ProtectedString(true, pbUtf8);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbUtf8);
 | 
			
		||||
			Array.Clear(vArray, 0, vArray.Length);
 | 
			
		||||
			vGenerated.Clear();
 | 
			
		||||
 | 
			
		||||
			return PwgError.Success;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string ExpandPattern(string strPattern)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strPattern != null); if(strPattern == null) return string.Empty;
 | 
			
		||||
			string str = strPattern;
 | 
			
		||||
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				int nOpen = FindFirstUnescapedChar(str, '{');
 | 
			
		||||
				int nClose = FindFirstUnescapedChar(str, '}');
 | 
			
		||||
 | 
			
		||||
				if((nOpen >= 0) && (nOpen < nClose))
 | 
			
		||||
				{
 | 
			
		||||
					string strCount = str.Substring(nOpen + 1, nClose - nOpen - 1);
 | 
			
		||||
					str = str.Remove(nOpen, nClose - nOpen + 1);
 | 
			
		||||
 | 
			
		||||
					uint uRepeat;
 | 
			
		||||
					if(StrUtil.TryParseUInt(strCount, out uRepeat) && (nOpen >= 1))
 | 
			
		||||
					{
 | 
			
		||||
						if(uRepeat == 0)
 | 
			
		||||
							str = str.Remove(nOpen - 1, 1);
 | 
			
		||||
						else
 | 
			
		||||
							str = str.Insert(nOpen, new string(str[nOpen - 1], (int)uRepeat - 1));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static int FindFirstUnescapedChar(string str, char ch)
 | 
			
		||||
		{
 | 
			
		||||
			for(int i = 0; i < str.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				char chCur = str[i];
 | 
			
		||||
 | 
			
		||||
				if(chCur == '\\') ++i; // Next is escaped, skip it
 | 
			
		||||
				else if(chCur == ch) return i;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,318 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	public sealed class PwCharSet
 | 
			
		||||
	{
 | 
			
		||||
		public const string UpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 | 
			
		||||
		public const string LowerCase = "abcdefghijklmnopqrstuvwxyz";
 | 
			
		||||
		public const string Digits = "0123456789";
 | 
			
		||||
 | 
			
		||||
		public const string UpperConsonants = "BCDFGHJKLMNPQRSTVWXYZ";
 | 
			
		||||
		public const string LowerConsonants = "bcdfghjklmnpqrstvwxyz";
 | 
			
		||||
		public const string UpperVowels = "AEIOU";
 | 
			
		||||
		public const string LowerVowels = "aeiou";
 | 
			
		||||
 | 
			
		||||
		public const string Punctuation = @",.;:";
 | 
			
		||||
		public const string Brackets = @"[]{}()<>";
 | 
			
		||||
 | 
			
		||||
		public const string PrintableAsciiSpecial = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
 | 
			
		||||
 | 
			
		||||
		public const string UpperHex = "0123456789ABCDEF";
 | 
			
		||||
		public const string LowerHex = "0123456789abcdef";
 | 
			
		||||
 | 
			
		||||
		public const string Invalid = "\t\r\n";
 | 
			
		||||
		public const string LookAlike = @"O0l1I|";
 | 
			
		||||
 | 
			
		||||
		private const int CharTabSize = (0x10000 / 8);
 | 
			
		||||
 | 
			
		||||
		private List<char> m_vChars = new List<char>();
 | 
			
		||||
		private byte[] m_vTab = new byte[CharTabSize];
 | 
			
		||||
 | 
			
		||||
		private string m_strHighAnsi = string.Empty;
 | 
			
		||||
		private string m_strSpecial = string.Empty;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Create a new, empty character set collection object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwCharSet()
 | 
			
		||||
		{
 | 
			
		||||
			this.Initialize(true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwCharSet(string strCharSet)
 | 
			
		||||
		{
 | 
			
		||||
			this.Initialize(true);
 | 
			
		||||
			this.Add(strCharSet);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private PwCharSet(bool bFullInitialize)
 | 
			
		||||
		{
 | 
			
		||||
			this.Initialize(bFullInitialize);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Initialize(bool bFullInitialize)
 | 
			
		||||
		{
 | 
			
		||||
			this.Clear();
 | 
			
		||||
 | 
			
		||||
			if(bFullInitialize == false) return;
 | 
			
		||||
 | 
			
		||||
			StringBuilder sbHighAnsi = new StringBuilder();
 | 
			
		||||
			for(char ch = '~'; ch < 255; ++ch)
 | 
			
		||||
				sbHighAnsi.Append(ch);
 | 
			
		||||
			m_strHighAnsi = sbHighAnsi.ToString();
 | 
			
		||||
 | 
			
		||||
			PwCharSet pcs = new PwCharSet(false);
 | 
			
		||||
			pcs.AddRange('!', '/');
 | 
			
		||||
			pcs.AddRange(':', '@');
 | 
			
		||||
			pcs.AddRange('[', '`');
 | 
			
		||||
			pcs.Remove(@"-_ ");
 | 
			
		||||
			pcs.Remove(PwCharSet.Brackets);
 | 
			
		||||
			m_strSpecial = pcs.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Number of characters in this set.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public uint Size
 | 
			
		||||
		{
 | 
			
		||||
			get { return (uint)m_vChars.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a character of the set using an index.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uPos">Index of the character to get.</param>
 | 
			
		||||
		/// <returns>Character at the specified position. If the index is invalid,
 | 
			
		||||
		/// an <c>ArgumentOutOfRangeException</c> is thrown.</returns>
 | 
			
		||||
		public char this[uint uPos]
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if(uPos >= (uint)m_vChars.Count)
 | 
			
		||||
					throw new ArgumentOutOfRangeException("uPos");
 | 
			
		||||
 | 
			
		||||
				return m_vChars[(int)uPos];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string SpecialChars { get { return m_strSpecial; } }
 | 
			
		||||
		public string HighAnsiChars { get { return m_strHighAnsi; } }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Remove all characters from this set.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public void Clear()
 | 
			
		||||
		{
 | 
			
		||||
			m_vChars.Clear();
 | 
			
		||||
			Array.Clear(m_vTab, 0, m_vTab.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Contains(char ch)
 | 
			
		||||
		{
 | 
			
		||||
			return (((m_vTab[ch / 8] >> (ch % 8)) & 1) != char.MinValue);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Contains(string strCharacters)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strCharacters != null);
 | 
			
		||||
			if(strCharacters == null) throw new ArgumentNullException("strCharacters");
 | 
			
		||||
 | 
			
		||||
			foreach(char ch in strCharacters)
 | 
			
		||||
			{
 | 
			
		||||
				if(this.Contains(ch) == false) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Add characters to the set.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="ch">Character to add.</param>
 | 
			
		||||
		public void Add(char ch)
 | 
			
		||||
		{
 | 
			
		||||
			if(ch == char.MinValue) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			if(this.Contains(ch) == false)
 | 
			
		||||
			{
 | 
			
		||||
				m_vChars.Add(ch);
 | 
			
		||||
				m_vTab[ch / 8] |= (byte)(1 << (ch % 8));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Add characters to the set.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strCharSet">String containing characters to add.</param>
 | 
			
		||||
		public void Add(string strCharSet)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strCharSet != null);
 | 
			
		||||
			if(strCharSet == null) throw new ArgumentNullException("strCharSet");
 | 
			
		||||
 | 
			
		||||
			m_vChars.Capacity = m_vChars.Count + strCharSet.Length;
 | 
			
		||||
 | 
			
		||||
			foreach(char ch in strCharSet)
 | 
			
		||||
				this.Add(ch);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(string strCharSet1, string strCharSet2)
 | 
			
		||||
		{
 | 
			
		||||
			this.Add(strCharSet1);
 | 
			
		||||
			this.Add(strCharSet2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(string strCharSet1, string strCharSet2, string strCharSet3)
 | 
			
		||||
		{
 | 
			
		||||
			this.Add(strCharSet1);
 | 
			
		||||
			this.Add(strCharSet2);
 | 
			
		||||
			this.Add(strCharSet3);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void AddRange(char chMin, char chMax)
 | 
			
		||||
		{
 | 
			
		||||
			m_vChars.Capacity = m_vChars.Count + (chMax - chMin) + 1;
 | 
			
		||||
 | 
			
		||||
			for(char ch = chMin; ch < chMax; ++ch)
 | 
			
		||||
				this.Add(ch);
 | 
			
		||||
 | 
			
		||||
			this.Add(chMax);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool AddCharSet(char chCharSetIdentifier)
 | 
			
		||||
		{
 | 
			
		||||
			bool bResult = true;
 | 
			
		||||
 | 
			
		||||
			switch(chCharSetIdentifier)
 | 
			
		||||
			{
 | 
			
		||||
				case 'a': this.Add(PwCharSet.LowerCase, PwCharSet.Digits); break;
 | 
			
		||||
				case 'A': this.Add(PwCharSet.LowerCase, PwCharSet.UpperCase,
 | 
			
		||||
					PwCharSet.Digits); break;
 | 
			
		||||
				case 'U': this.Add(PwCharSet.UpperCase, PwCharSet.Digits); break;
 | 
			
		||||
				case 'c': this.Add(PwCharSet.LowerConsonants); break;
 | 
			
		||||
				case 'C': this.Add(PwCharSet.LowerConsonants,
 | 
			
		||||
					PwCharSet.UpperConsonants); break;
 | 
			
		||||
				case 'z': this.Add(PwCharSet.UpperConsonants); break;
 | 
			
		||||
				case 'd': this.Add(PwCharSet.Digits); break; // Digit
 | 
			
		||||
				case 'h': this.Add(PwCharSet.LowerHex); break;
 | 
			
		||||
				case 'H': this.Add(PwCharSet.UpperHex); break;
 | 
			
		||||
				case 'l': this.Add(PwCharSet.LowerCase); break;
 | 
			
		||||
				case 'L': this.Add(PwCharSet.LowerCase, PwCharSet.UpperCase); break;
 | 
			
		||||
				case 'u': this.Add(PwCharSet.UpperCase); break;
 | 
			
		||||
				case 'p': this.Add(PwCharSet.Punctuation); break;
 | 
			
		||||
				case 'b': this.Add(PwCharSet.Brackets); break;
 | 
			
		||||
				case 's': this.Add(PwCharSet.PrintableAsciiSpecial); break;
 | 
			
		||||
				case 'S': this.Add(PwCharSet.UpperCase, PwCharSet.LowerCase);
 | 
			
		||||
					this.Add(PwCharSet.Digits, PwCharSet.PrintableAsciiSpecial); break;
 | 
			
		||||
				case 'v': this.Add(PwCharSet.LowerVowels); break;
 | 
			
		||||
				case 'V': this.Add(PwCharSet.LowerVowels, PwCharSet.UpperVowels); break;
 | 
			
		||||
				case 'Z': this.Add(PwCharSet.UpperVowels); break;
 | 
			
		||||
				case 'x': this.Add(m_strHighAnsi); break;
 | 
			
		||||
				default: bResult = false; break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Remove(char ch)
 | 
			
		||||
		{
 | 
			
		||||
			m_vTab[ch / 8] &= (byte)~(1 << (ch % 8));
 | 
			
		||||
			return m_vChars.Remove(ch);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Remove(string strCharacters)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strCharacters != null);
 | 
			
		||||
			if(strCharacters == null) throw new ArgumentNullException("strCharacters");
 | 
			
		||||
 | 
			
		||||
			bool bResult = true;
 | 
			
		||||
			foreach(char ch in strCharacters)
 | 
			
		||||
			{
 | 
			
		||||
				if(!Remove(ch)) bResult = false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool RemoveIfAllExist(string strCharacters)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strCharacters != null);
 | 
			
		||||
			if(strCharacters == null) throw new ArgumentNullException("strCharacters");
 | 
			
		||||
 | 
			
		||||
			if(this.Contains(strCharacters) == false)
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			return this.Remove(strCharacters);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert the character set to a string containing all its characters.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>String containing all character set characters.</returns>
 | 
			
		||||
		public override string ToString()
 | 
			
		||||
		{
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
			foreach(char ch in m_vChars)
 | 
			
		||||
				sb.Append(ch);
 | 
			
		||||
 | 
			
		||||
			return sb.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string PackAndRemoveCharRanges()
 | 
			
		||||
		{
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(PwCharSet.UpperCase) ? 'U' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(PwCharSet.LowerCase) ? 'L' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(PwCharSet.Digits) ? 'D' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(m_strSpecial) ? 'S' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(PwCharSet.Punctuation) ? 'P' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(@"-") ? 'm' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(@"_") ? 'u' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(@" ") ? 's' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(PwCharSet.Brackets) ? 'B' : '_');
 | 
			
		||||
			sb.Append(this.RemoveIfAllExist(m_strHighAnsi) ? 'H' : '_');
 | 
			
		||||
 | 
			
		||||
			return sb.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void UnpackCharRanges(string strRanges)
 | 
			
		||||
		{
 | 
			
		||||
			if(strRanges == null) { Debug.Assert(false); return; }
 | 
			
		||||
			if(strRanges.Length < 10) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			if(strRanges[0] != '_') this.Add(PwCharSet.UpperCase);
 | 
			
		||||
			if(strRanges[1] != '_') this.Add(PwCharSet.LowerCase);
 | 
			
		||||
			if(strRanges[2] != '_') this.Add(PwCharSet.Digits);
 | 
			
		||||
			if(strRanges[3] != '_') this.Add(m_strSpecial);
 | 
			
		||||
			if(strRanges[4] != '_') this.Add(PwCharSet.Punctuation);
 | 
			
		||||
			if(strRanges[5] != '_') this.Add('-');
 | 
			
		||||
			if(strRanges[6] != '_') this.Add('_');
 | 
			
		||||
			if(strRanges[7] != '_') this.Add(' ');
 | 
			
		||||
			if(strRanges[8] != '_') this.Add(PwCharSet.Brackets);
 | 
			
		||||
			if(strRanges[9] != '_') this.Add(m_strHighAnsi);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,146 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	public enum PwgError
 | 
			
		||||
	{
 | 
			
		||||
		Success = 0,
 | 
			
		||||
		Unknown = 1,
 | 
			
		||||
		TooFewCharacters = 2,
 | 
			
		||||
		UnknownAlgorithm = 3
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Utility functions for generating random passwords.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class PwGenerator
 | 
			
		||||
	{
 | 
			
		||||
		public static PwgError Generate(out ProtectedString psOut,
 | 
			
		||||
			PwProfile pwProfile, byte[] pbUserEntropy,
 | 
			
		||||
			CustomPwGeneratorPool pwAlgorithmPool)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwProfile != null);
 | 
			
		||||
			if(pwProfile == null) throw new ArgumentNullException("pwProfile");
 | 
			
		||||
 | 
			
		||||
			CryptoRandomStream crs = CreateCryptoStream(pbUserEntropy);
 | 
			
		||||
			PwgError e = PwgError.Unknown;
 | 
			
		||||
 | 
			
		||||
			if(pwProfile.GeneratorType == PasswordGeneratorType.CharSet)
 | 
			
		||||
				e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs);
 | 
			
		||||
			else if(pwProfile.GeneratorType == PasswordGeneratorType.Pattern)
 | 
			
		||||
				e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs);
 | 
			
		||||
			else if(pwProfile.GeneratorType == PasswordGeneratorType.Custom)
 | 
			
		||||
				e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool);
 | 
			
		||||
			else { Debug.Assert(false); psOut = ProtectedString.Empty; }
 | 
			
		||||
 | 
			
		||||
			return e;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static CryptoRandomStream CreateCryptoStream(byte[] pbAdditionalEntropy)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbKey = CryptoRandom.Instance.GetRandomBytes(256);
 | 
			
		||||
 | 
			
		||||
			// Mix in additional entropy
 | 
			
		||||
			if((pbAdditionalEntropy != null) && (pbAdditionalEntropy.Length > 0))
 | 
			
		||||
			{
 | 
			
		||||
				for(int nKeyPos = 0; nKeyPos < pbKey.Length; ++nKeyPos)
 | 
			
		||||
					pbKey[nKeyPos] ^= pbAdditionalEntropy[nKeyPos % pbAdditionalEntropy.Length];
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return new CryptoRandomStream(CrsAlgorithm.Salsa20, pbKey);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static char GenerateCharacter(PwProfile pwProfile,
 | 
			
		||||
			PwCharSet pwCharSet, CryptoRandomStream crsRandomSource)
 | 
			
		||||
		{
 | 
			
		||||
			if(pwCharSet.Size == 0) return char.MinValue;
 | 
			
		||||
 | 
			
		||||
			ulong uIndex = crsRandomSource.GetRandomUInt64();
 | 
			
		||||
			uIndex %= (ulong)pwCharSet.Size;
 | 
			
		||||
 | 
			
		||||
			char ch = pwCharSet[(uint)uIndex];
 | 
			
		||||
 | 
			
		||||
			if(pwProfile.NoRepeatingCharacters)
 | 
			
		||||
				pwCharSet.Remove(ch);
 | 
			
		||||
 | 
			
		||||
			return ch;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static void PrepareCharSet(PwCharSet pwCharSet, PwProfile pwProfile)
 | 
			
		||||
		{
 | 
			
		||||
			pwCharSet.Remove(PwCharSet.Invalid);
 | 
			
		||||
 | 
			
		||||
			if(pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike);
 | 
			
		||||
 | 
			
		||||
			if(pwProfile.ExcludeCharacters.Length > 0)
 | 
			
		||||
				pwCharSet.Remove(pwProfile.ExcludeCharacters);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static void ShufflePassword(char[] pPassword,
 | 
			
		||||
			CryptoRandomStream crsRandomSource)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pPassword != null); if(pPassword == null) return;
 | 
			
		||||
			Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) return;
 | 
			
		||||
 | 
			
		||||
			if(pPassword.Length <= 1) return; // Nothing to shuffle
 | 
			
		||||
 | 
			
		||||
			for(int nSelect = 0; nSelect < pPassword.Length; ++nSelect)
 | 
			
		||||
			{
 | 
			
		||||
				ulong uRandomIndex = crsRandomSource.GetRandomUInt64();
 | 
			
		||||
				uRandomIndex %= (ulong)(pPassword.Length - nSelect);
 | 
			
		||||
 | 
			
		||||
				char chTemp = pPassword[nSelect];
 | 
			
		||||
				pPassword[nSelect] = pPassword[nSelect + (int)uRandomIndex];
 | 
			
		||||
				pPassword[nSelect + (int)uRandomIndex] = chTemp;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static PwgError GenerateCustom(out ProtectedString psOut,
 | 
			
		||||
			PwProfile pwProfile, CryptoRandomStream crs,
 | 
			
		||||
			CustomPwGeneratorPool pwAlgorithmPool)
 | 
			
		||||
		{
 | 
			
		||||
			psOut = ProtectedString.Empty;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pwProfile.GeneratorType == PasswordGeneratorType.Custom);
 | 
			
		||||
			if(pwAlgorithmPool == null) return PwgError.UnknownAlgorithm;
 | 
			
		||||
 | 
			
		||||
			string strID = pwProfile.CustomAlgorithmUuid;
 | 
			
		||||
			if(string.IsNullOrEmpty(strID)) { Debug.Assert(false); return PwgError.UnknownAlgorithm; }
 | 
			
		||||
 | 
			
		||||
			byte[] pbUuid = Convert.FromBase64String(strID);
 | 
			
		||||
			PwUuid uuid = new PwUuid(pbUuid);
 | 
			
		||||
			CustomPwGenerator pwg = pwAlgorithmPool.Find(uuid);
 | 
			
		||||
			if(pwg == null) { Debug.Assert(false); return PwgError.UnknownAlgorithm; }
 | 
			
		||||
 | 
			
		||||
			ProtectedString pwd = pwg.Generate(pwProfile.CloneDeep(), crs);
 | 
			
		||||
			if(pwd == null) return PwgError.Unknown;
 | 
			
		||||
 | 
			
		||||
			psOut = pwd;
 | 
			
		||||
			return PwgError.Success;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,277 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography.PasswordGenerator
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Type of the password generator. Different types like generators
 | 
			
		||||
	/// based on given patterns, based on character sets, etc. are
 | 
			
		||||
	/// available.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum PasswordGeneratorType
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Generator based on character spaces/sets, i.e. groups
 | 
			
		||||
		/// of characters like lower-case, upper-case or numeric characters.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		CharSet = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Password generation based on a pattern. The user has provided
 | 
			
		||||
		/// a pattern, which describes how the generated password has to
 | 
			
		||||
		/// look like.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Pattern = 1,
 | 
			
		||||
 | 
			
		||||
		Custom = 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class PwProfile : IDeepCloneable<PwProfile>
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strName = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Name
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strName; }
 | 
			
		||||
			set { m_strName = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private PasswordGeneratorType m_type = PasswordGeneratorType.CharSet;
 | 
			
		||||
		public PasswordGeneratorType GeneratorType
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_type; }
 | 
			
		||||
			set { m_type = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bUserEntropy = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool CollectUserEntropy
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bUserEntropy; }
 | 
			
		||||
			set { m_bUserEntropy = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private uint m_uLength = 20;
 | 
			
		||||
		public uint Length
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_uLength; }
 | 
			
		||||
			set { m_uLength = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private PwCharSet m_pwCharSet = new PwCharSet(PwCharSet.UpperCase +
 | 
			
		||||
			PwCharSet.LowerCase + PwCharSet.Digits);
 | 
			
		||||
		[XmlIgnore]
 | 
			
		||||
		public PwCharSet CharSet
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pwCharSet; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_pwCharSet = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strCharSetRanges = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string CharSetRanges
 | 
			
		||||
		{
 | 
			
		||||
			get { this.UpdateCharSet(true); return m_strCharSetRanges; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strCharSetRanges = value;
 | 
			
		||||
				this.UpdateCharSet(false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strCharSetAdditional = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string CharSetAdditional
 | 
			
		||||
		{
 | 
			
		||||
			get { this.UpdateCharSet(true); return m_strCharSetAdditional; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strCharSetAdditional = value;
 | 
			
		||||
				this.UpdateCharSet(false);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strPattern = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Pattern
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strPattern; }
 | 
			
		||||
			set { m_strPattern = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bPatternPermute = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool PatternPermutePassword
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bPatternPermute; }
 | 
			
		||||
			set { m_bPatternPermute = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bNoLookAlike = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool ExcludeLookAlike
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bNoLookAlike; }
 | 
			
		||||
			set { m_bNoLookAlike = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bNoRepeat = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool NoRepeatingCharacters
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bNoRepeat; }
 | 
			
		||||
			set { m_bNoRepeat = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strExclude = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string ExcludeCharacters
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strExclude; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strExclude = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strCustomID = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string CustomAlgorithmUuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strCustomID; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strCustomID = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strCustomOpt = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string CustomAlgorithmOptions
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strCustomOpt; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strCustomOpt = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwProfile()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwProfile CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			PwProfile p = new PwProfile();
 | 
			
		||||
 | 
			
		||||
			p.m_strName = m_strName;
 | 
			
		||||
			p.m_type = m_type;
 | 
			
		||||
			p.m_bUserEntropy = m_bUserEntropy;
 | 
			
		||||
			p.m_uLength = m_uLength;
 | 
			
		||||
			p.m_pwCharSet = new PwCharSet(m_pwCharSet.ToString());
 | 
			
		||||
			p.m_strCharSetRanges = m_strCharSetRanges;
 | 
			
		||||
			p.m_strCharSetAdditional = m_strCharSetAdditional;
 | 
			
		||||
			p.m_strPattern = m_strPattern;
 | 
			
		||||
			p.m_bPatternPermute = m_bPatternPermute;
 | 
			
		||||
			p.m_bNoLookAlike = m_bNoLookAlike;
 | 
			
		||||
			p.m_bNoRepeat = m_bNoRepeat;
 | 
			
		||||
			p.m_strExclude = m_strExclude;
 | 
			
		||||
			p.m_strCustomID = m_strCustomID;
 | 
			
		||||
			p.m_strCustomOpt = m_strCustomOpt;
 | 
			
		||||
 | 
			
		||||
			return p;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void UpdateCharSet(bool bSetXml)
 | 
			
		||||
		{
 | 
			
		||||
			if(bSetXml)
 | 
			
		||||
			{
 | 
			
		||||
				PwCharSet pcs = new PwCharSet(m_pwCharSet.ToString());
 | 
			
		||||
				m_strCharSetRanges = pcs.PackAndRemoveCharRanges();
 | 
			
		||||
				m_strCharSetAdditional = pcs.ToString();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				PwCharSet pcs = new PwCharSet(m_strCharSetAdditional);
 | 
			
		||||
				pcs.UnpackCharRanges(m_strCharSetRanges);
 | 
			
		||||
				m_pwCharSet = pcs;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static PwProfile DeriveFromPassword(ProtectedString psPassword)
 | 
			
		||||
		{
 | 
			
		||||
			PwProfile pp = new PwProfile();
 | 
			
		||||
			Debug.Assert(psPassword != null); if(psPassword == null) return pp;
 | 
			
		||||
 | 
			
		||||
			byte[] pbUtf8 = psPassword.ReadUtf8();
 | 
			
		||||
			char[] vChars = StrUtil.Utf8.GetChars(pbUtf8);
 | 
			
		||||
 | 
			
		||||
			pp.GeneratorType = PasswordGeneratorType.CharSet;
 | 
			
		||||
			pp.Length = (uint)vChars.Length;
 | 
			
		||||
 | 
			
		||||
			PwCharSet pcs = pp.CharSet;
 | 
			
		||||
			pcs.Clear();
 | 
			
		||||
 | 
			
		||||
			foreach(char ch in vChars)
 | 
			
		||||
			{
 | 
			
		||||
				if((ch >= 'A') && (ch <= 'Z')) pcs.Add(PwCharSet.UpperCase);
 | 
			
		||||
				else if((ch >= 'a') && (ch <= 'z')) pcs.Add(PwCharSet.LowerCase);
 | 
			
		||||
				else if((ch >= '0') && (ch <= '9')) pcs.Add(PwCharSet.Digits);
 | 
			
		||||
				else if((@"!#$%&'*+,./:;=?@^").IndexOf(ch) >= 0) pcs.Add(pcs.SpecialChars);
 | 
			
		||||
				else if(ch == ' ') pcs.Add(' ');
 | 
			
		||||
				else if(ch == '-') pcs.Add('-');
 | 
			
		||||
				else if(ch == '_') pcs.Add('_');
 | 
			
		||||
				else if(ch == '\"') pcs.Add(pcs.SpecialChars);
 | 
			
		||||
				else if(ch == '\\') pcs.Add(pcs.SpecialChars);
 | 
			
		||||
				else if((@"()[]{}<>").IndexOf(ch) >= 0) pcs.Add(PwCharSet.Brackets);
 | 
			
		||||
				else if((ch >= '~') && (ch <= 255)) pcs.Add(pcs.HighAnsiChars);
 | 
			
		||||
				else pcs.Add(ch);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Array.Clear(vChars, 0, vChars.Length);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbUtf8);
 | 
			
		||||
			return pp;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool HasSecurityReducingOption()
 | 
			
		||||
		{
 | 
			
		||||
			return (m_bNoLookAlike || m_bNoRepeat || (m_strExclude.Length > 0));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										540
									
								
								src/KeePassLib2Android/Cryptography/PopularPasswords.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										540
									
								
								src/KeePassLib2Android/Cryptography/PopularPasswords.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,540 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Bloom filter-based popular password checking.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class PopularPasswords
 | 
			
		||||
	{
 | 
			
		||||
		private const int PpcTableSize = 8192 * 8; // Bits, multiple of 64
 | 
			
		||||
 | 
			
		||||
		// Bits set: 32433 of 65536
 | 
			
		||||
		// Hash functions: 32
 | 
			
		||||
		// Phi (bits unset ratio) estimation: 0.505455388896019
 | 
			
		||||
		// Exact Phi: 0.505111694335938
 | 
			
		||||
		// False positives ratio: 1.67583063859565E-10
 | 
			
		||||
		private static readonly ulong[] PpcTable = {
 | 
			
		||||
			0x60383D3A85560B9BUL, 0x2578CE9D37C6AEB7UL, 0xF509A5743FD03228UL,
 | 
			
		||||
			0x19B7455E8933EE56UL, 0x5EA419ADCFD9C20EUL, 0xEA618EFC0B37A162UL,
 | 
			
		||||
			0xE0FD4D1FFF1CE415UL, 0x7A649E0301BB6060UL, 0x80D9CD9F9EEB603DUL,
 | 
			
		||||
			0x47D6010D0D6E6CDEUL, 0x2552708C589EB554UL, 0x073F1A3DB3267502UL,
 | 
			
		||||
			0x3313FEC2A2FEA475UL, 0x4593665C44934FEBUL, 0x410A301A23660395UL,
 | 
			
		||||
			0x6AD06DA533FF5659UL, 0x423DAF86F3E41F4AUL, 0x82F035A971C6FD18UL,
 | 
			
		||||
			0xB5E9139F28C93223UL, 0x1D07C3F4160585CAUL, 0x24B01EDB6B23E2C5UL,
 | 
			
		||||
			0xD52F25B724F936C9UL, 0x8018392517836928UL, 0x3AA4C0F8E181EDA2UL,
 | 
			
		||||
			0x8D93683EF7D52529UL, 0x6164BB6208114460UL, 0x737A04D8FEF3D88FUL,
 | 
			
		||||
			0x3400097098D5C2CBUL, 0x3C2B9ABE5C455B2EUL, 0x3A3819973AB32DA2UL,
 | 
			
		||||
			0x38ACB428510AF40BUL, 0x83320D5114B74771UL, 0xC25BEC333B90DCD1UL,
 | 
			
		||||
			0x0E9F412FBA3813D1UL, 0x047E31E3098EB2B8UL, 0xBB686AC643F1741FUL,
 | 
			
		||||
			0x0BE22E9C0EF0E8F2UL, 0x65AA9504E5F40D31UL, 0xE018DF5D64C62AC7UL,
 | 
			
		||||
			0x17020E9A7EFA12EDUL, 0xFC12A7C16006DE82UL, 0x8DE4747E3745346DUL,
 | 
			
		||||
			0x31D8C051A43CECAFUL, 0xBE9AFBEF127C1B12UL, 0xAEE94B4B808BBEE2UL,
 | 
			
		||||
			0x3A0099CA32835B41UL, 0x59EB3173468D8C49UL, 0x6F89DB1E6DAAE9E1UL,
 | 
			
		||||
			0x4C1ADAA837E968E4UL, 0x6E3593A56C682769UL, 0x022AD591689B5B82UL,
 | 
			
		||||
			0x4AC33861ED978032UL, 0xF6F476E4E6A1318DUL, 0x2DA690A11AA05A23UL,
 | 
			
		||||
			0x916FC56378C29D77UL, 0xAB3238BE22294659UL, 0x2D73A29019B28C77UL,
 | 
			
		||||
			0xAAF26C12EC9C3C42UL, 0x058A278A24B334F9UL, 0x033BD18FB8D9BACDUL,
 | 
			
		||||
			0x8B3833596008B07CUL, 0x280B6D093333E5E5UL, 0x2128DBE126CA3E1EUL,
 | 
			
		||||
			0xCCF09769382472D8UL, 0x0CB6E495BD90CED6UL, 0x1303A37577C01C5AUL,
 | 
			
		||||
			0xC8BBF4734FC34C53UL, 0x1B38B72B10F86CD5UL, 0x5098E2D6C1892E51UL,
 | 
			
		||||
			0x2DD8065B79DB5380UL, 0x5B9A1A6D6A2292B7UL, 0xC70F751604D0497CUL,
 | 
			
		||||
			0x911E08D7363B5213UL, 0x9F2E245273308D2EUL, 0x64D354827957F50EUL,
 | 
			
		||||
			0x09856750F560342CUL, 0xDE091F26603F0E70UL, 0xDDE6B4E76173E3B1UL,
 | 
			
		||||
			0xC1584AE1B26FA08EUL, 0x1EA29887837838D2UL, 0x6D7643FC67B15C54UL,
 | 
			
		||||
			0x921E60571ED103EAUL, 0x63EB1EB33E7AFFF1UL, 0x80BA4D1F95BFD615UL,
 | 
			
		||||
			0xEC8A1D4FC1A6B8E0UL, 0x2C46861B6DB17D1AUL, 0x01F05D06927E443BUL,
 | 
			
		||||
			0x6172EC2EABEAD454UL, 0x21B8726C6F7C4102UL, 0x3C016CD9945C72ECUL,
 | 
			
		||||
			0x708F77B2C0E8B665UL, 0xFC35BE2BB88974DAUL, 0x805897A33702BD61UL,
 | 
			
		||||
			0x9A93367A6041226CUL, 0xFDAB188B6158F6BEUL, 0x5F21014A065E918CUL,
 | 
			
		||||
			0xF4381DD77772D19CUL, 0xC664B6358AA85011UL, 0xF2639D7B3E2307E6UL,
 | 
			
		||||
			0x3FA000D4A5A9C37AUL, 0x8F45D116ED8DC70FUL, 0x8CB8758E45C140D0UL,
 | 
			
		||||
			0x49832B46D716236DUL, 0xCC8E4961A93065B8UL, 0x8A996533EDACEB0EUL,
 | 
			
		||||
			0x15B35155EC56FAC1UL, 0xE7E0C6C05A9F1885UL, 0x05914F9A1D1C79F9UL,
 | 
			
		||||
			0x730000A30B6725F0UL, 0xC95E671F8E543780UL, 0x47D68382400AF94EUL,
 | 
			
		||||
			0x1A27F2734FE2249AUL, 0x828079C332D9C0ABUL, 0x2E9BC798EA09170EUL,
 | 
			
		||||
			0x6B7CDAC829018C91UL, 0x7B89604901736993UL, 0xABE4EB26F47608F0UL,
 | 
			
		||||
			0x70D5FDC88A0FF1B1UL, 0x5A1F0BAB9AB8A158UL, 0xDC89AE0A735C51A4UL,
 | 
			
		||||
			0x36C1EA01E9C89B84UL, 0x3A9757AF204096DBUL, 0x1D56C8328540F963UL,
 | 
			
		||||
			0x910A8694692472FAUL, 0x697192C9DF145604UL, 0xB20F7A4438712AA2UL,
 | 
			
		||||
			0xE8C99185243F4896UL, 0xFBC8970EDBC39CA7UL, 0x33485403868C3761UL,
 | 
			
		||||
			0xAFA97DDEDB1D6AD8UL, 0x54A1A6F24476A3BBUL, 0xFE4E078B184BDB7FUL,
 | 
			
		||||
			0x5ED1543919754CD8UL, 0x86F8C775160FC08CUL, 0x9B4098F57019040DUL,
 | 
			
		||||
			0x039518BBE841327BUL, 0x111D0D420A3F5F6AUL, 0x0666067346AF34ACUL,
 | 
			
		||||
			0xD43F1D14EB239B9BUL, 0xA6BB91FEB5618F5BUL, 0xA2B5218B202409ADUL,
 | 
			
		||||
			0xC004FA688C3AC25EUL, 0xF0E2D9EA2935E1DCUL, 0x380B31CFA2F2AF43UL,
 | 
			
		||||
			0x50E050AE426250EAUL, 0x628ED94D1AA8F55BUL, 0xF8EB0654F0166311UL,
 | 
			
		||||
			0x1F8858D26DDA5CC5UL, 0x931425D11CB1EFEBUL, 0xF661D461DC1A05D3UL,
 | 
			
		||||
			0x7B75ED7EC6936DA8UL, 0x8713C59690985202UL, 0xF61D6F93F07C0E85UL,
 | 
			
		||||
			0xFD1771F6711D6F4FUL, 0x5835A67E1B11419FUL, 0x33EF08ABD56A1050UL,
 | 
			
		||||
			0x55B5D0043FA2C01CUL, 0x53316ED963B92D9DUL, 0x6A8C93744E521EDBUL,
 | 
			
		||||
			0x083E948062EB9543UL, 0x1C15289B3189AFB1UL, 0xA6A0A5053AE2212DUL,
 | 
			
		||||
			0x6573AF7F01FAFF3BUL, 0x58B6F034CFCFE843UL, 0xEB2837CA5AEA6AEDUL,
 | 
			
		||||
			0x633E7897097AC328UL, 0x7FA91789B6CCEE82UL, 0xBEE2402F4E7D65EEUL,
 | 
			
		||||
			0x616A103EC8FB0DBEUL, 0x65991F9FB25E13FCUL, 0x54EA8A3FADEC1F4BUL,
 | 
			
		||||
			0x6D497C5ACDEA0E7AUL, 0x5865045E8CA18527UL, 0xA406C09215ABD61FUL,
 | 
			
		||||
			0x68F81F5745FC9875UL, 0xE496D850CEFF3FA9UL, 0xD225C88D63212CB1UL,
 | 
			
		||||
			0x37676390525116D2UL, 0x415614AB14188A7DUL, 0xABE58EBC1F6DDC63UL,
 | 
			
		||||
			0xDE10312B2C25D28CUL, 0x86C86D7A0B847635UL, 0x408B511D584DC3DCUL,
 | 
			
		||||
			0x6711FCC14B303FEDUL, 0x1284DF9CC6972023UL, 0xC3CE0B33141BFA8FUL,
 | 
			
		||||
			0x0F3F58367D4A1819UL, 0x9313F83058FBE6D0UL, 0x6FCA5EF39B8E2F47UL,
 | 
			
		||||
			0xA90F5C95D887756DUL, 0x96C4E2AD85D5AF6EUL, 0x0ED68A81F526F0A0UL,
 | 
			
		||||
			0x53E4472DB4255A35UL, 0xAC581015134D58A6UL, 0x12C000D85C644FC7UL,
 | 
			
		||||
			0x124D489B2C0FE6E4UL, 0x8FF83531C6F5D61AUL, 0x132BD6488304F73BUL,
 | 
			
		||||
			0x110E99BC59604CB9UL, 0xC28186ACBC940C9BUL, 0x2094C07F48141230UL,
 | 
			
		||||
			0x65FB9881A5053589UL, 0x940A3E6D72F09D69UL, 0x972A922CB14BA66EUL,
 | 
			
		||||
			0x8D07E59C6DDD4327UL, 0xCB67F993F820157CUL, 0x65B7A54E5FB2ED6CUL,
 | 
			
		||||
			0xC235828849576653UL, 0xA695F85479467538UL, 0x9E2BA885E63C4243UL,
 | 
			
		||||
			0xDE64A6A5EF84C222UL, 0xC2AB9AF302080621UL, 0x88DBA09B87FA0734UL,
 | 
			
		||||
			0xDF002765B44D02E1UL, 0xD50D8D90587CD820UL, 0x1B68B70ED179EFE1UL,
 | 
			
		||||
			0xD6E77F8EC26AE95CUL, 0xEE57EB7C45051872UL, 0x4D2B445F36A7F9FDUL,
 | 
			
		||||
			0x5502ABB8BB14D7F1UL, 0xAF2C0DF0406FA901UL, 0x6522833444BF4A83UL,
 | 
			
		||||
			0xD7CB2E3FC691BE8DUL, 0x4F36F70D2E80D19AUL, 0xF6945FE911D4923BUL,
 | 
			
		||||
			0xE3C6FE1EA47399C1UL, 0xF09EA1B2F837702CUL, 0x5122537CF97B5CB5UL,
 | 
			
		||||
			0x0C8202B70E9BF154UL, 0x68B554AB58EB5E68UL, 0x7BF9B8052C9BEADEUL,
 | 
			
		||||
			0x33612BFCD303810DUL, 0x03E38CF67B37DC53UL, 0x2BFDFF8691F37D5CUL,
 | 
			
		||||
			0x4AB483D1CB1D07F6UL, 0xF071A58640639A5CUL, 0x9D6B98169B745CE1UL,
 | 
			
		||||
			0x5F42D3E870FDCD93UL, 0x4EDF04404F258238UL, 0x2EAB6E10D65C9BB3UL,
 | 
			
		||||
			0x5BB71411EF78DAD2UL, 0x0DE8128636A5D689UL, 0x18FDD1F484DC9365UL,
 | 
			
		||||
			0x9896B8896941DA5BUL, 0x8BEF8E3BA4448E5FUL, 0x963A1E977CB1D2CAUL,
 | 
			
		||||
			0x02BCF5F068D52851UL, 0x0CD783F09BFBE381UL, 0x350DA833D8C5DB47UL,
 | 
			
		||||
			0x8D444C914D795C43UL, 0x8A00B4DFC44D9476UL, 0x4B36CBEC089E55FDUL,
 | 
			
		||||
			0xD9D2FA1B0AC66211UL, 0x6C7FC30FA31A8B60UL, 0x9EF4504CC985AD6BUL,
 | 
			
		||||
			0x8F2E7E5E0C00EE73UL, 0x819131CFEEBEA069UL, 0xB1E406A863E7A1B4UL,
 | 
			
		||||
			0x501F072FF1F2AB67UL, 0xDE578BFC5ADBC264UL, 0xCDD66A09C8E13881UL,
 | 
			
		||||
			0x4D443460CE52957FUL, 0x3B198C267976ECFAUL, 0x6B98323D8BD26522UL,
 | 
			
		||||
			0x80161F6A489E4BF8UL, 0xE03A8AFCC7AE6872UL, 0x2484BD95A305AB27UL,
 | 
			
		||||
			0x6ADDAA46BF25DD0EUL, 0xA429D8B00100477CUL, 0x55AEDB88A074BF2CUL,
 | 
			
		||||
			0x63D9F9021AB8F5F3UL, 0x37858538A10C265CUL, 0xEF54C2CE9D063149UL,
 | 
			
		||||
			0xFA5CE5AF33E2C136UL, 0xE601A559D0C391D7UL, 0x7C4ED29BBF57DC7EUL,
 | 
			
		||||
			0x8FD0D4146DE9E900UL, 0xB58ABFA6CE6C0733UL, 0xF8D7F7743B33EAFFUL,
 | 
			
		||||
			0x453FA782F454643CUL, 0xD01752C21AF21E66UL, 0xA50BB7913EAF05DFUL,
 | 
			
		||||
			0x966D5B140B2F4189UL, 0x956F5638AFF3D148UL, 0x93FAA838420E8AB3UL,
 | 
			
		||||
			0x715E26043071EABDUL, 0x01E7B458B5FD3A41UL, 0x5CFA99C4CC0492AAUL,
 | 
			
		||||
			0x761FD391C3623044UL, 0xD39E44E9DB96B5BCUL, 0x8806C544F0534A07UL,
 | 
			
		||||
			0x9B225CAFE97EAAC1UL, 0xEAE5E18583492767UL, 0x6B4E51E4C297F096UL,
 | 
			
		||||
			0xFC512662EF47E41DUL, 0xB6AC60427DB46F8BUL, 0x8F137F3DB4429C9DUL,
 | 
			
		||||
			0x04C65FBEAE9FD8D0UL, 0xEB72305958AE5022UL, 0xAA93AA14BCA2961EUL,
 | 
			
		||||
			0x6C7547F9456CA37AUL, 0xEE6094871615BA34UL, 0x489BC8EDE0940402UL,
 | 
			
		||||
			0x1108AEFAAD892229UL, 0x673B8B1CF6BED23EUL, 0xFDB781A75FD94DEAUL,
 | 
			
		||||
			0x11D9E0F5D914A7BEUL, 0x02830D07F018143DUL, 0x9B3163B8188FD2BAUL,
 | 
			
		||||
			0x32C1BEC97D06117EUL, 0x697268B761240CFFUL, 0xBD89CE3037C2E7A9UL,
 | 
			
		||||
			0xF21C158125B19600UL, 0x632CB1931601B70AUL, 0x7BB3FB131338085CUL,
 | 
			
		||||
			0xA9C06689B8138384UL, 0x161CCBF83EBDC2A1UL, 0x2CF83C01A80B7935UL,
 | 
			
		||||
			0x9E51FE393B8E2FF0UL, 0xFE96E52B1606C1A7UL, 0x5E20DFB87F81ACCEUL,
 | 
			
		||||
			0xF95DB9602CDAE467UL, 0xDEA155CD35555FEBUL, 0xF0669B810F70CDC6UL,
 | 
			
		||||
			0xD36C2FBEB6A449ACUL, 0xCE500C6621C0A445UL, 0x41308909E366460AUL,
 | 
			
		||||
			0xAC4D8178DA0CEC24UL, 0xC69049179ED09F7DUL, 0x36B608A0BA2FD848UL,
 | 
			
		||||
			0xDF511894DD9568B4UL, 0xB3BFDF78EC861A6CUL, 0xCD50F39D19848153UL,
 | 
			
		||||
			0xD2C1BC57E78A408CUL, 0x1E6613EFBB11B5EBUL, 0xF58E30D2D90F73D3UL,
 | 
			
		||||
			0xCCB5E2F5E168D742UL, 0xEE97259469BDB672UL, 0x6784D35AF65935A8UL,
 | 
			
		||||
			0x71032765ADED1FE8UL, 0x4BBF2FE54D9B72E3UL, 0x5A1BB7831E876A05UL,
 | 
			
		||||
			0x12A8FC949EE91686UL, 0x8296F8FA83BD112CUL, 0xAAA7E3BFF64D34D5UL,
 | 
			
		||||
			0x0301655E1794EE4BUL, 0x1E547C011BBF30E1UL, 0x39D74FEC536F31D6UL,
 | 
			
		||||
			0x3C31A7478B1815BAUL, 0x525C774F82D5836EUL, 0xECF7186DC612FD8CUL,
 | 
			
		||||
			0x96B7C4EDD1F3536FUL, 0x7E8C21F19C08541CUL, 0xEE92DB0CF91E4B09UL,
 | 
			
		||||
			0xF666190D1591AE5DUL, 0x5E9B45102C895361UL, 0x9A95597AAE5C905DUL,
 | 
			
		||||
			0x6E1272E5BB93F93FUL, 0x0E39E612402BFCF8UL, 0x576C9E8CA2A3B35EUL,
 | 
			
		||||
			0x7E2E629996D0C35FUL, 0xC95DFF54E3524FCCUL, 0x260F9DEBDEB0E5CBUL,
 | 
			
		||||
			0x577B6C6640BAF1ABUL, 0xCA76677779CA358EUL, 0x9E2714BEBCFDB144UL,
 | 
			
		||||
			0xD660595CE30FD3EEUL, 0x72DE172D55A5706EUL, 0xB4C84D564489D420UL,
 | 
			
		||||
			0x160AA2B9399D5A9DUL, 0x2906ECE619DAC4D2UL, 0x12CE8E8E68A4C317UL,
 | 
			
		||||
			0x6BE2DFE89901CAA1UL, 0xEE1D68158102EB77UL, 0x64EB75E45BDA1AC5UL,
 | 
			
		||||
			0xEFECF9F98720B55DUL, 0x41CDF813931315BFUL, 0x5F1E4F50CF98FFD4UL,
 | 
			
		||||
			0xE69E09EED12E173BUL, 0x89A3707F0396FF65UL, 0x81E36B9DF4FFB492UL,
 | 
			
		||||
			0x58C32E883D4DE6DDUL, 0x2D4725C2A5F0B469UL, 0x6B2B9C27CC421CACUL,
 | 
			
		||||
			0x3C30F2AD966800C7UL, 0xFF74938BB76B8A7CUL, 0x52B5C99114FD93FAUL,
 | 
			
		||||
			0x51647EDCA6C104DAUL, 0xEB47684CF796DF4EUL, 0x376D74A5AB14BD71UL,
 | 
			
		||||
			0xF0871FEF8E9DAA3EUL, 0x1D65B134B2E045B6UL, 0x9DC8C0D8623BBA48UL,
 | 
			
		||||
			0xAD6FC3C59DBDADF4UL, 0x66F6EBA55488B569UL, 0xB00D53E0E2D38F0AUL,
 | 
			
		||||
			0x43A4212CEAD34593UL, 0x44724185FF7019FFUL, 0x50F46061432B3635UL,
 | 
			
		||||
			0x880AA4C24E6B320BUL, 0xCAFCB3409A0DB43FUL, 0xA7F1A13DEF47514BUL,
 | 
			
		||||
			0x3DC8A385A698220CUL, 0xFA17F82E30B85580UL, 0x430E7F0E88655F47UL,
 | 
			
		||||
			0x45A1566013837B47UL, 0x84B2306D2292804EUL, 0xE7A3AF21D074E419UL,
 | 
			
		||||
			0x09D08E2C5E569D4DUL, 0x84228F8908383FA2UL, 0xC34079610C8D3E82UL,
 | 
			
		||||
			0x66C96426C54A5453UL, 0xD41F164117D32C93UL, 0x7829A66BF1FEC186UL,
 | 
			
		||||
			0x4BB6846694BDFC18UL, 0x857D1C1C01352C01UL, 0xAB8E68BA85402A45UL,
 | 
			
		||||
			0x74B3C4F101FE76C8UL, 0x6CF482CFAFB29FFEUL, 0x28B174A18F4DC3D1UL,
 | 
			
		||||
			0x833C3425B2AA3755UL, 0x8AA58A32747F4432UL, 0xFE7B9FB4BCE3CD58UL,
 | 
			
		||||
			0xB0836B2C16FA5553UL, 0x1D08EE6861BF3F23UL, 0x0FAE41E914562DF3UL,
 | 
			
		||||
			0xB10A2E041937FC57UL, 0xDA60BB363415BF4CUL, 0xEEC67DBAB4CF4F0AUL,
 | 
			
		||||
			0x9A6ED59FCC923B5CUL, 0x9A913C01A8EC7A83UL, 0xAD4779F2F9C7721FUL,
 | 
			
		||||
			0x2BF0B7D105BE7459UL, 0x189EFA9AD5195EC6UL, 0xB5C9A2DD64B2A903UL,
 | 
			
		||||
			0x5BCD642B2C2FD32CUL, 0xFED3FBF78CB0891FUL, 0x1ED958EE3C36DD3FUL,
 | 
			
		||||
			0x030F5DE9CA65E97CUL, 0xBB5BCF8C931B85FEUL, 0xFD128759EA1D8061UL,
 | 
			
		||||
			0x2C0238AC416BE6BCUL, 0xBB018584EEACFA27UL, 0xCEA7288C1964DE15UL,
 | 
			
		||||
			0x7EA5C3840F29AA4DUL, 0x5DA841BA609E4A50UL, 0xE53AF84845985EB1UL,
 | 
			
		||||
			0x93264DA9487183E4UL, 0xC3A4E367AF6D8D15UL, 0xDD4EB6450577BAF8UL,
 | 
			
		||||
			0x2AA3093EE2C658ACUL, 0x3D036EC45055C580UL, 0xDDEDB34341C5B7DFUL,
 | 
			
		||||
			0x524FFBDC4A1FAC90UL, 0x1B9D63DE13D82907UL, 0x69F9BAF0E868B640UL,
 | 
			
		||||
			0xFC1A453A9253013CUL, 0x08B900DECAA77377UL, 0xFF24C72324153C59UL,
 | 
			
		||||
			0x6182C1285C507A9BUL, 0x4E6680A54A03CCC8UL, 0x7165680200B67F1FUL,
 | 
			
		||||
			0xC3290B26A07DCE5BUL, 0x2AD16584AA5BECE9UL, 0x5F10DF677C91B05EUL,
 | 
			
		||||
			0x4BE1B0E2334B198AUL, 0xEA2466E4F4E4406DUL, 0x6ECAA92FF91E6F1DUL,
 | 
			
		||||
			0x0267738EFA75CADDUL, 0x4282ED10A0EBFCF2UL, 0xD3F84CE8E1685271UL,
 | 
			
		||||
			0xB667ED35716CA215UL, 0x97B4623D70DB7FA8UL, 0xB7BA3AA5E6C2E7CBUL,
 | 
			
		||||
			0x8942B2F97118255BUL, 0x009050F842FB52ADUL, 0x114F5511999F5BD5UL,
 | 
			
		||||
			0x70C1CAAF1E83F00AUL, 0xAC8EE25D462BB1AAUL, 0x63EEF42AD4E1BED9UL,
 | 
			
		||||
			0x58DFBB3D22D3D1A5UL, 0x82B0027C0C63D816UL, 0x48D038F08F3D848BUL,
 | 
			
		||||
			0xCE262D5F9A12610EUL, 0xA54BF51C21BD0167UL, 0xF3645F6FB948397DUL,
 | 
			
		||||
			0x9188AE58532DA501UL, 0xEC90B0E1479DB767UL, 0x37F4886B83724F80UL,
 | 
			
		||||
			0x232B8FF20ACD95AFUL, 0x88A228285D6BCDF0UL, 0x321FB91600259AEEUL,
 | 
			
		||||
			0xA1F875F161D18E5EUL, 0x5B6087CDA21AEA0CUL, 0x0156923ED1A3D5F1UL,
 | 
			
		||||
			0xC2892C8A6133B5D3UL, 0x015CA4DF0EA6354DUL, 0x5E25EB261B69A7D4UL,
 | 
			
		||||
			0xAAA8CF0C012EFBA7UL, 0xCF3466248C37868BUL, 0x0D744514BD1D82C0UL,
 | 
			
		||||
			0xB00FF1431EDDF490UL, 0xC79B86A0E3A8AB08UL, 0xFC361529BC9F1252UL,
 | 
			
		||||
			0x869285653FB82865UL, 0x9F1C7A17546339ABUL, 0xE31AA66DBD5C4760UL,
 | 
			
		||||
			0x51B9D2A765E0FC31UL, 0x31F39528C4CD13D8UL, 0x16C6C35B0D3A341DUL,
 | 
			
		||||
			0x90296B1B0F28E2CDUL, 0x36338472A8DB5830UL, 0xA648E6D44DF14F87UL,
 | 
			
		||||
			0x93E231E65EB1823FUL, 0x95AA7B9D08E2B627UL, 0x7932D149374700C7UL,
 | 
			
		||||
			0x09EFE0A8BF245193UL, 0x742AA63BCEAFD6D8UL, 0x82D4BC5FEDF158B7UL,
 | 
			
		||||
			0x02CDEA673CFF150DUL, 0xD8D7B5813B602D15UL, 0xA5A7B670EF15A5EDUL,
 | 
			
		||||
			0x4C08E580A1D46AF2UL, 0xC3CA9B905D035647UL, 0x6A39ABB02F6F1B83UL,
 | 
			
		||||
			0xD2EC2169F4D02436UL, 0x8E6AEA4DF8515AF2UL, 0x7B3DD4A8693CA2DAUL,
 | 
			
		||||
			0xC2ABF17A50AEC383UL, 0xD4FB84F8B6D4F709UL, 0x2839A3EAA2E4C8A7UL,
 | 
			
		||||
			0x5D5FD278FE10E1E9UL, 0x5610DDF74125D5A7UL, 0xA484B0B83461DCEAUL,
 | 
			
		||||
			0xA511920C0A502369UL, 0xC53F30C6A5394CA4UL, 0x528799285D304DD4UL,
 | 
			
		||||
			0xF6D7914CB252BB48UL, 0x892129CB52E65D15UL, 0x15A81B70519ACE6FUL,
 | 
			
		||||
			0x5CFBFFD7A2A1C630UL, 0x3B900509C82DF46DUL, 0x19C3CE05D66D5FFCUL,
 | 
			
		||||
			0x937D521A4A4799A0UL, 0xD0AE34A6EAD7207DUL, 0x3258A69F1D1A1B38UL,
 | 
			
		||||
			0xB173E3255723CC02UL, 0xD7E48FEF7F414F1BUL, 0xDCEBA75F5C761ABEUL,
 | 
			
		||||
			0x6DA10C618DEA0D17UL, 0x423FA8B05954FBD1UL, 0x7E73C2E7D923F3C9UL,
 | 
			
		||||
			0xC22E21C927C684D1UL, 0x756BAA758764685FUL, 0x8C90B4C4E741D880UL,
 | 
			
		||||
			0x1B658C9F4B41D846UL, 0x5D80C14094366707UL, 0xB55FED3E03C00F2DUL,
 | 
			
		||||
			0x9B69EB7964C69C83UL, 0x356ED81C9494DADDUL, 0x7599AFF0B2A339D6UL,
 | 
			
		||||
			0xA5EBFD25C9B5816BUL, 0xA481DC1C8995E1EFUL, 0xE42C63DF0D402397UL,
 | 
			
		||||
			0x3B497B4C30873BAAUL, 0xA950B78BA8772C96UL, 0xD46308D4C76F115DUL,
 | 
			
		||||
			0x73714A4ACA76A857UL, 0x0DA86B958FF8CB7DUL, 0xEB61F617B90E0A75UL,
 | 
			
		||||
			0xD6106C9B39F51F55UL, 0xB179F73A6BD23B59UL, 0xE7F056E50104A460UL,
 | 
			
		||||
			0xBC5B5387634A8642UL, 0xE1678D8752996AF4UL, 0xB508F3D394664A4BUL,
 | 
			
		||||
			0xC88536DC4A219B0FUL, 0x39964CBB8CE367B1UL, 0xD51E211D5E9E1417UL,
 | 
			
		||||
			0x6821B97B496870F2UL, 0xA596257350CA0A99UL, 0x6D051EE2C49D4D1DUL,
 | 
			
		||||
			0xCB426AD61AA8D9B5UL, 0x5FFD3A4062B06D22UL, 0xDAD37BF2A4C594EBUL,
 | 
			
		||||
			0x6B9CC848E2B0C686UL, 0x19B4232F3BC622AEUL, 0x70C13C7E5950B702UL,
 | 
			
		||||
			0x383318CA622101ACUL, 0xD9647C028CD1C4DFUL, 0x006D123BC553B93CUL,
 | 
			
		||||
			0x2CA9D7D896EAE722UL, 0xF19872AC8A0BD5A8UL, 0x59838578EB9E8E5CUL,
 | 
			
		||||
			0xB948621EE99B27D4UL, 0x2B470E6036E0E387UL, 0xD0A7E8F0C8A32A84UL,
 | 
			
		||||
			0xCBF869271A8E0914UL, 0x705F76A5EA4437CFUL, 0xBAD2BF4933215152UL,
 | 
			
		||||
			0xE52EDE847038EA23UL, 0xB8A3EFD3D58D7607UL, 0x748472F5AD330239UL,
 | 
			
		||||
			0xCC079CFD428690F6UL, 0x3687450CB7534DACUL, 0x0FEF82D5CC8ACE2AUL,
 | 
			
		||||
			0x214653D5C552CA9AUL, 0x9FCA4E87BF6A04FDUL, 0x78D4B114D234A0D7UL,
 | 
			
		||||
			0x22840422BD6A5BB5UL, 0x5B9ABE0DE1B4410FUL, 0xB3B50007963FDD6BUL,
 | 
			
		||||
			0x53A8A46793B68E35UL, 0x8CDD8E8D188B6033UL, 0x5DD22B6E3ED49572UL,
 | 
			
		||||
			0xE561F5D27F5302D6UL, 0xDF89CEC3322E56CDUL, 0x87167F503D600F90UL,
 | 
			
		||||
			0x1698BB71C8201862UL, 0xF7BF5DFDB023108EUL, 0xA17FB15B66ACFB5FUL,
 | 
			
		||||
			0x2DD771987768073BUL, 0x19299D2D86E0EB29UL, 0x8B537B7F206EED29UL,
 | 
			
		||||
			0xE536DA153325ABFCUL, 0x30A69976796DB3B9UL, 0x8E65A2C94E2D4981UL,
 | 
			
		||||
			0xC301D53553BD6514UL, 0x46DF3639B9E43790UL, 0x3004CD0E5AFD0463UL,
 | 
			
		||||
			0x46E460B0F6ACA1A0UL, 0xCBA210E7372D9BD5UL, 0x45064274A74CA582UL,
 | 
			
		||||
			0xFDD57EA43CE631AEUL, 0xF2BA08FFA4A683D0UL, 0x8DA658C4DAD42999UL,
 | 
			
		||||
			0x7418042943E88040UL, 0x96000F72E9371FEFUL, 0xE9F1212DC8F47302UL,
 | 
			
		||||
			0x2AFB565ECC3553EDUL, 0xCD3D55137EFF7FD6UL, 0xD36F11059388E442UL,
 | 
			
		||||
			0xC4B47515DB5709DDUL, 0x5C363EFBF0BAAB67UL, 0x28C63B5A31650BBBUL,
 | 
			
		||||
			0x6AE54E5068061C81UL, 0xDEE62000F4E0AA21UL, 0xE8238672FE088A8BUL,
 | 
			
		||||
			0x9869CB6370F075B9UL, 0xBA376E2FC7DB330FUL, 0xB0F73E208487CDEEUL,
 | 
			
		||||
			0x359D5017BE37FE97UL, 0x684D828C7F95E2DCUL, 0x9985ECA20E46AE1FUL,
 | 
			
		||||
			0x8030A5137D1A21C4UL, 0xF78CDC00FC37AC39UL, 0x41CDDC8E61D9C644UL,
 | 
			
		||||
			0xB6F3CD1D833BAD1DUL, 0x301D0D858A23DE22UL, 0xA51FCA12AD849BC8UL,
 | 
			
		||||
			0x9F55E615986AB10EUL, 0x904AAA59854F2215UL, 0x12ECEA4AB40F51A7UL,
 | 
			
		||||
			0xB4EDF5807735E23BUL, 0x6190200F1C589478UL, 0xA3CA57F321909A5AUL,
 | 
			
		||||
			0x0BFAEE04B7325B63UL, 0x10C393E7FBCF826DUL, 0x4050A2CA53FDA708UL,
 | 
			
		||||
			0xF31114A9B462B680UL, 0x6FB9A6F121BA2006UL, 0x04550CF09389D602UL,
 | 
			
		||||
			0xB8C7D6D8CA8942F7UL, 0x71BB430C6436E9D1UL, 0xD9070DD5FAA0A10AUL,
 | 
			
		||||
			0x8FD6827757D07E5BUL, 0xD04E6C313F8FD974UL, 0x2CFDEA1187909B9AUL,
 | 
			
		||||
			0xC7A8E758C115F593UL, 0xA79A17663009ACC2UL, 0x8091A6B5372B141DUL,
 | 
			
		||||
			0xEB33B08767F5BA73UL, 0xDAC1F6823B6111C7UL, 0x697DF90C3515611BUL,
 | 
			
		||||
			0xCC1005F198761F48UL, 0x5067E4F5303B45A1UL, 0x04816D292A2D9AC2UL,
 | 
			
		||||
			0x2949C7A0874DD5E9UL, 0x25DB2547804CEE5EUL, 0x7EDC3A8946D6F229UL,
 | 
			
		||||
			0x00B586F67FD0C622UL, 0x3CAE5798E40324E0UL, 0x0A4F1437DE637164UL,
 | 
			
		||||
			0x5F59B2B715871981UL, 0x5D68FF31051E48FBUL, 0x0F2C369D73A2AA46UL,
 | 
			
		||||
			0xB009C6B53DD23399UL, 0xC366A81277084988UL, 0x5AF0E0CA0711E730UL,
 | 
			
		||||
			0x7AD831A9E9E854BAUL, 0x1DD5EDB0CA4E85AEUL, 0x54651209D259E9DDUL,
 | 
			
		||||
			0x3EBB1D9DAB237EADUL, 0xDA96989317AC464CUL, 0xBFCB0F8FBC52C74EUL,
 | 
			
		||||
			0x9597ACB9E27B692EUL, 0x6F436B1643C95B23UL, 0xB81A1253E1C3CD9DUL,
 | 
			
		||||
			0x7B35F37E905EC67EUL, 0x29CE62666EDA76DDUL, 0xFF2490DC1EC4014DUL,
 | 
			
		||||
			0x2D4FF9124DD6B5C4UL, 0xB9510FEC23E0E9D1UL, 0x8BCDBC56541ED071UL,
 | 
			
		||||
			0x5414E097C1B0CCB2UL, 0x82BEF8213076F5C7UL, 0xE9FC9A71BD512615UL,
 | 
			
		||||
			0xCF15ECC39490DF5AUL, 0x49FA9328D8EE97DBUL, 0x5F80FF0153BC2145UL,
 | 
			
		||||
			0xF63BA156B55BCB02UL, 0x0E3B9113109FDF36UL, 0x8FCD6528F54EDE69UL,
 | 
			
		||||
			0x5D6AE9C000054763UL, 0x326D873633431FBBUL, 0x380E07FFCEF7A978UL,
 | 
			
		||||
			0xDCAA09874A1DF230UL, 0x601494F49F6D261EUL, 0x856159486C9B60E3UL,
 | 
			
		||||
			0x85C7F822D07089A5UL, 0xAFFB99CF5AB836C2UL, 0x241AD414FBBB956BUL,
 | 
			
		||||
			0x0CFC042822831692UL, 0x382B16D049727FF2UL, 0x784F9997633C819AUL,
 | 
			
		||||
			0x5C40ED725F6C390AUL, 0x2CE78B7A3331BA9CUL, 0x9C80636639963B41UL,
 | 
			
		||||
			0x1B2D41C968355018UL, 0xD189B57691FB60E4UL, 0x3BD599A9DD85CE31UL,
 | 
			
		||||
			0x46FC8E2EF0B9A77CUL, 0x1A389E07D0075EA4UL, 0x1622CA52401DF2ACUL,
 | 
			
		||||
			0x528F3FF9B7993BFAUL, 0xF16C176CCA292DDBUL, 0x6C154010961EF542UL,
 | 
			
		||||
			0x04B78E92BF6C82DFUL, 0x7D9AFEA6ABB46072UL, 0x3BC573291CBFFC2EUL,
 | 
			
		||||
			0x277FFF096D567AF3UL, 0x1CBEB86841A6F757UL, 0xD0BCD49E76CA20A7UL,
 | 
			
		||||
			0x25B6024756B1FE90UL, 0xE685C04EF84881FBUL, 0xDCAB14B352FC442EUL,
 | 
			
		||||
			0x4FF80A521719953DUL, 0xD10425E411DBE94BUL, 0x60998D0507D6E38DUL,
 | 
			
		||||
			0x146AA432C981BD5EUL, 0x1729A596282AAA41UL, 0x152BE1A263BAF963UL,
 | 
			
		||||
			0x15278DF497D254CAUL, 0xE4B5E9891E88A5DAUL, 0x087FA3472067D0ACUL,
 | 
			
		||||
			0xD99C2899A0AD9158UL, 0x5040F234DC531236UL, 0x9D7E1531259EEE90UL,
 | 
			
		||||
			0x29AFB8B49391036EUL, 0x84B619599642D68EUL, 0xE838AAE0F249545CUL,
 | 
			
		||||
			0x42D524BA8BB96959UL, 0x9A5B3E817A20EE59UL, 0x584F0530EC4C566BUL,
 | 
			
		||||
			0xD6544FD14B47F945UL, 0x3613FB3B553A7CDEUL, 0x284E92B56831AA56UL,
 | 
			
		||||
			0xCEE89BA10E951A22UL, 0x476806FA1A8A44E0UL, 0xC84CEF151885C1DFUL,
 | 
			
		||||
			0x3DB1D5C1B0B73936UL, 0x45D2D90FDF452388UL, 0x038A7DD71BC5DD21UL,
 | 
			
		||||
			0x2AC90C7422C56819UL, 0x4742046638ECE0FBUL, 0x553B44360FC8495DUL,
 | 
			
		||||
			0xC8DBA1CF3F9A6E97UL, 0xF85919F494CAB021UL, 0x1479455C2FF236AFUL,
 | 
			
		||||
			0x29BCAD159F7D018DUL, 0x016DFF51CBA3BCC5UL, 0x234BF8A77F6B1CF5UL,
 | 
			
		||||
			0x20564C6F44F9E641UL, 0x063A550C5AA50FA8UL, 0xB063D0AAAA96DFECUL,
 | 
			
		||||
			0x3EC659DF42C092F8UL, 0x29D4A76A5A5F7E09UL, 0x65EFF3EE6E691D1EUL,
 | 
			
		||||
			0xBD1634F5721CF799UL, 0xE85BD016723B43FFUL, 0x5233E9E7AEA11022UL,
 | 
			
		||||
			0x8C68852EA9039B4CUL, 0x2C978ADBE885BC15UL, 0x726615ED9D497550UL,
 | 
			
		||||
			0x7C1E145EB8D2BD96UL, 0xC2FEFB25935A5D71UL, 0x9EE9C3E1C3DE416FUL,
 | 
			
		||||
			0xFFD568A03E20E0B3UL, 0xF53649AD90156F2AUL, 0x0331B91DCE54E7EDUL,
 | 
			
		||||
			0x67CED5A86E99392FUL, 0x16FC0A5815500B05UL, 0x030392E8D24A7C00UL,
 | 
			
		||||
			0x232E5E31DF32A7B5UL, 0xCC8BF22B1947DF21UL, 0x4EC2C72D9C1EEABDUL,
 | 
			
		||||
			0x0B1B79F45220E668UL, 0xCC3CF0EE9C4A899BUL, 0xFC260A60592EBC80UL,
 | 
			
		||||
			0xC1989A0382CB03EDUL, 0x35FE679A6CD800B2UL, 0x8A6B1ADE4FBB162FUL,
 | 
			
		||||
			0xB0FD284563625295UL, 0xCDCC1C7B2181D024UL, 0x5B8BA0C895C0BB23UL,
 | 
			
		||||
			0xA681FEA9ADCD43DBUL, 0x0FE30FB6876DE718UL, 0x6DDD1E27B769C494UL,
 | 
			
		||||
			0x83A1E58460FFE8BBUL, 0x8FAD6FD2DC90FF65UL, 0x41BB28B81201CB24UL,
 | 
			
		||||
			0xA148CE79B2597204UL, 0x7CB87DF97BB477A6UL, 0x9F79E6DED87DC688UL,
 | 
			
		||||
			0xE044D84A6C758171UL, 0x1A29E750D9EC4097UL, 0x8445FC2B80C4A0F5UL,
 | 
			
		||||
			0x5EFD9784AFED4ED2UL, 0x344C252BD90EB0E4UL, 0xEAD18D2E4418E5B5UL,
 | 
			
		||||
			0x207EF4FFC260BD24UL, 0xD2E5C3AE534EC538UL, 0x2F5A59BF3D10E7E1UL,
 | 
			
		||||
			0x9528E29266C2924CUL, 0x0121B6BDAB45D138UL, 0xADD0256ACBC771DDUL,
 | 
			
		||||
			0x7301769600C6C50DUL, 0x3E7404EA8231D497UL, 0xB39B3840B8D03117UL,
 | 
			
		||||
			0x56EFCEDDEF5B6634UL, 0xE6BE2C0D73B72098UL, 0x5A2841A21A5E4959UL,
 | 
			
		||||
			0xCFEB3586156DF6E0UL, 0xD84F58901E2D65B8UL, 0x79796786CCC59703UL,
 | 
			
		||||
			0x13BFA9A94DD07696UL, 0x7B63116A6B5458B6UL, 0x1406628176C932E0UL,
 | 
			
		||||
			0xDD7ACC4E97F91B1AUL, 0xC82B8F84A56BDBE8UL, 0x325D87D08ED8B0B0UL,
 | 
			
		||||
			0x3F7847B1E82002DDUL, 0x4662900D2ADAF6BFUL, 0x12AE9F58561DB1D7UL,
 | 
			
		||||
			0xA896E956A95CC074UL, 0xAA4FA3A2F8BA4084UL, 0x1D577E35F5DCA67FUL,
 | 
			
		||||
			0x796FF2D75469DEC2UL, 0xBD3F3F87E4DE894EUL, 0x3666B2262DEBFB6BUL,
 | 
			
		||||
			0x1E26D7AEEF976C2EUL, 0x6BC3854F867AC4A0UL, 0x743DBF8C2E95A821UL,
 | 
			
		||||
			0xA62A76B9AE2E645AUL, 0xB4D76561F40187C1UL, 0xD3E5F23F9FA5DB25UL,
 | 
			
		||||
			0x34B1F6B39E6A87E2UL, 0x7DA5C3DFF7BE72CFUL, 0xFDF46B1BE80AD4F9UL,
 | 
			
		||||
			0x0B21121CA9653B8AUL, 0x1199CA9D0A90F21AUL, 0x6021EA302D01E0BAUL,
 | 
			
		||||
			0x8101D063C05CF5D4UL, 0xE2652410DFE78F23UL, 0x84095ACF47C21A25UL,
 | 
			
		||||
			0xD7E29A4DB2FD3A99UL, 0x7793C0CB57959F93UL, 0x94C605308B9E5AA7UL,
 | 
			
		||||
			0x943DB1AC54165B8FUL, 0xC1391A544C07447CUL, 0x3FEF1A61F785D97BUL,
 | 
			
		||||
			0x6DFCC3152478BDE4UL, 0x312AFB0E1982933AUL, 0xB8069C2605631ED3UL,
 | 
			
		||||
			0x5A6076423430BED2UL, 0x34E379F09E2D4F42UL, 0x9167F5E4019573E3UL,
 | 
			
		||||
			0x18F81157828D2A49UL, 0xF4A8723B4955EAB8UL, 0x0BE6C0ABFEA9E8A6UL,
 | 
			
		||||
			0xC63ADCF2CEF25556UL, 0xC5EBD3BEAE9F364FUL, 0xA301D60CF5B6F2FCUL,
 | 
			
		||||
			0x8C606CA881D27A00UL, 0x826FEE13B554C18AUL, 0x8DF251716F10B776UL,
 | 
			
		||||
			0xB2573A33AC7D94FFUL, 0xC0E771248CB7ABB9UL, 0x753DD605DB38F4EAUL,
 | 
			
		||||
			0x21901664C3D92114UL, 0xA408FCB7A1892612UL, 0x3084FC64A03D6722UL,
 | 
			
		||||
			0xC8C9D9569AD42A34UL, 0x1FBFBAFC1694B383UL, 0x1894280CC3F94ABEUL,
 | 
			
		||||
			0xE14C38A7BBB54651UL, 0x23A48CC84A6EB704UL, 0xD034ADC45AABEDBDUL,
 | 
			
		||||
			0xC93F2C21C973C766UL, 0x66A8AEC11D743CC6UL, 0xB4F72AA52E37C145UL,
 | 
			
		||||
			0xB02834DF0D9266B4UL, 0xDB8E724EA1FF402FUL, 0x531E9C058112E352UL,
 | 
			
		||||
			0xC2F692531DB317D2UL, 0xEFC9586498D263A7UL, 0x84F2C524D2F3ADB9UL,
 | 
			
		||||
			0xAFAF02C27CF25D08UL, 0x385873595F9CFC09UL, 0x36DDA10D1A152B7AUL,
 | 
			
		||||
			0x9F9B997A0DACFB55UL, 0x10AB5EB5C4714882UL, 0x7BA4E8703E22B7EEUL,
 | 
			
		||||
			0x0A2BFD558607BCC8UL, 0x201D3706F74F8BA1UL, 0x3DBD573B1358F02EUL,
 | 
			
		||||
			0x5B37645FA93BCEBCUL, 0xC0166864BC1A7544UL, 0x45C7AA5559FC65D7UL,
 | 
			
		||||
			0xEFEA04AA83349B78UL, 0x607859194F9E9FD8UL, 0xA6B9AE5B53CF7710UL,
 | 
			
		||||
			0x73B9142ACBC50821UL, 0x8B7D67495887E65CUL, 0x39B6C4FB2B232E56UL,
 | 
			
		||||
			0xD212DB10E31D2A68UL, 0x629AC0A3D263DC6EUL, 0x6BC2E7FF912050BAUL,
 | 
			
		||||
			0xE0AD5A8FDB183F62UL, 0xF05648134F0C6F0FUL, 0x31E146F4AF980FDAUL,
 | 
			
		||||
			0x7FAF0078D84D62CCUL, 0xE13F044C2830D21EUL, 0x49A047AD204B4C4BUL,
 | 
			
		||||
			0xF3AFBE2237351A74UL, 0x32826C9217BB07EDUL, 0xD4C3AEB099319B5CUL,
 | 
			
		||||
			0x49CE5BD05B2B0F61UL, 0x75DD36984DCBD0A2UL, 0x84EC5D7C2F0AAC6CUL,
 | 
			
		||||
			0x8E59CC9B9942EDDFUL, 0x89FF85DCDF9AE895UL, 0x6F9EE0D8D9E8D414UL,
 | 
			
		||||
			0x10E01A59058D3904UL, 0x1DFAF567BFF55D2EUL, 0x8DD6A18C03382CD4UL,
 | 
			
		||||
			0xE12FD89A0CF58553UL, 0xE245DA902C0C4F5CUL, 0x8BE7566B9987520DUL,
 | 
			
		||||
			0x4CA1C0A4B38A3098UL, 0x81E45015BE618A72UL, 0xA80E0344FF27EFDFUL,
 | 
			
		||||
			0xC98DAEC6DC5005BAUL, 0xF56873F3A958AE5EUL, 0xDB88604670C794ACUL,
 | 
			
		||||
			0x4F68E448DDF6535FUL, 0x3443DBF1CA6031A8UL, 0x73DFA5DEEF409A41UL,
 | 
			
		||||
			0xA7C556941F6643B2UL, 0x424BC40D8C83D962UL, 0x6F292A325B99B726UL,
 | 
			
		||||
			0x6EECB1009717D65EUL, 0x899BE4CE7BB2D8EEUL, 0x25285FED3E59781DUL,
 | 
			
		||||
			0x14C5AEDD76E092D3UL, 0x9BB5EE10567640AEUL, 0xCD62A1D43558FD06UL,
 | 
			
		||||
			0x70A7B09FC5F39447UL, 0xF10064AE92EFFB99UL, 0xD55FA1A918A23082UL,
 | 
			
		||||
			0xD03F28AD25C73A78UL, 0x76CFFFEE094D8B0EUL, 0x4FD5A46AD5A4B4CFUL,
 | 
			
		||||
			0x8F3A36F9D7BF87E3UL, 0x64224315210625BEUL, 0x749A131B71B64350UL,
 | 
			
		||||
			0x9034FF9DAC089F48UL, 0xB58D3017E7321217UL, 0x549D818937D5CE90UL,
 | 
			
		||||
			0x903CE1452419E99CUL, 0xFD052F0388DB2E76UL, 0x7390051E3972480EUL,
 | 
			
		||||
			0x5E5F6EC3F27B3679UL, 0x3E3637D4D4EE917DUL, 0x4FE04068CA2A4309UL,
 | 
			
		||||
			0x98C9C17454AAE42DUL, 0x659AE0BDB113BC21UL, 0x4C0BDECB1511AF4CUL,
 | 
			
		||||
			0x17048BFAEAC0006DUL, 0x68F106AADAA64912UL, 0x2286234ECEB7EAF0UL,
 | 
			
		||||
			0x350CD42CAF697E51UL, 0x8DCDE6D1FAC19A9FUL, 0xF97E55A245A8A8A2UL,
 | 
			
		||||
			0xAAE86B2092DA90A3UL, 0x5123E878AA8AEF76UL, 0x022B88B9694A55F6UL,
 | 
			
		||||
			0xC4C1A9B1C0221985UL, 0x20056D91DD5E0FFEUL, 0xF5BF61EC225C9843UL,
 | 
			
		||||
			0x1A315A05BDCF4A31UL, 0x5710A21A8DF4F15FUL, 0x99BD1A0AF97AD027UL,
 | 
			
		||||
			0x7602C5997AD4E12CUL
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		public static bool IsPopularPassword(char[] vPassword)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(PpcTable.Length == (PpcTableSize / 64));
 | 
			
		||||
 | 
			
		||||
			if(vPassword == null) throw new ArgumentNullException("vPassword");
 | 
			
		||||
			if(vPassword.Length == 0) return false;
 | 
			
		||||
 | 
			
		||||
			foreach(char ch in vPassword)
 | 
			
		||||
			{
 | 
			
		||||
				if(!IsPopularChar(ch)) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vPassword);
 | 
			
		||||
 | 
			
		||||
			int[] vIndices = GetTableIndices(pbUtf8, PpcTableSize);
 | 
			
		||||
			Array.Clear(pbUtf8, 0, pbUtf8.Length);
 | 
			
		||||
 | 
			
		||||
			foreach(int iIndex in vIndices)
 | 
			
		||||
			{
 | 
			
		||||
				if(!GetTableBit(PpcTable, iIndex)) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static bool IsPopularChar(char ch)
 | 
			
		||||
		{
 | 
			
		||||
			return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) ||
 | 
			
		||||
				((ch >= '0') && (ch <= '9')) || (ch == '_') || (ch == '!'));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static int[] GetTableIndices(byte[] pbPasswordUtf8, int nTableSize)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((nTableSize >= 2) && (nTableSize <= 0x10000));
 | 
			
		||||
			Debug.Assert((nTableSize % 64) == 0);
 | 
			
		||||
 | 
			
		||||
			SHA512Managed sha = new SHA512Managed();
 | 
			
		||||
			byte[] pbHash = sha.ComputeHash(pbPasswordUtf8);
 | 
			
		||||
 | 
			
		||||
			int[] vIndices = new int[pbHash.Length / 2];
 | 
			
		||||
			for(int i = 0; i < vIndices.Length; ++i)
 | 
			
		||||
				vIndices[i] = ((((int)pbHash[i * 2] << 8) |
 | 
			
		||||
					(int)pbHash[i * 2 + 1]) % nTableSize);
 | 
			
		||||
 | 
			
		||||
			return vIndices;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static bool GetTableBit(ulong[] vTable, int iBit)
 | 
			
		||||
		{
 | 
			
		||||
			return ((vTable[iBit >> 6] & (1UL << (iBit & 0x3F))) != 0UL);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if (DEBUG && !KeePassLibSD)
 | 
			
		||||
		private static bool SetTableBit(ulong[] vTable, int iBit)
 | 
			
		||||
		{
 | 
			
		||||
			if(GetTableBit(vTable, iBit)) return false;
 | 
			
		||||
 | 
			
		||||
			vTable[iBit >> 6] = (vTable[iBit >> 6] | (1UL << (iBit & 0x3F)));
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void MakeList()
 | 
			
		||||
		{
 | 
			
		||||
			string strData = File.ReadAllText("MostPopularPasswords.txt", StrUtil.Utf8);
 | 
			
		||||
			strData += " ";
 | 
			
		||||
			CharStream cs = new CharStream(strData);
 | 
			
		||||
 | 
			
		||||
			List<string> vPasswords = new List<string>();
 | 
			
		||||
			StringBuilder sbPassword = new StringBuilder();
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				char ch = cs.ReadChar();
 | 
			
		||||
				if(ch == char.MinValue) break;
 | 
			
		||||
 | 
			
		||||
				if(char.IsWhiteSpace(ch))
 | 
			
		||||
				{
 | 
			
		||||
					string strPassword = sbPassword.ToString();
 | 
			
		||||
					strPassword = strPassword.ToLower();
 | 
			
		||||
 | 
			
		||||
					if(strPassword.Length > 3)
 | 
			
		||||
					{
 | 
			
		||||
						if(vPasswords.IndexOf(strPassword) < 0)
 | 
			
		||||
							vPasswords.Add(strPassword);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					sbPassword = new StringBuilder();
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Debug.Assert(!char.IsControl(ch) && !char.IsHighSurrogate(ch) &&
 | 
			
		||||
						!char.IsLowSurrogate(ch) && !char.IsSurrogate(ch));
 | 
			
		||||
					Debug.Assert(IsPopularChar(ch));
 | 
			
		||||
					sbPassword.Append(ch);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ulong[] vTable = new ulong[PpcTableSize / 64];
 | 
			
		||||
			Array.Clear(vTable, 0, vTable.Length);
 | 
			
		||||
 | 
			
		||||
			long lBitsInTable = 0;
 | 
			
		||||
			foreach(string strPassword in vPasswords)
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strPassword);
 | 
			
		||||
				int[] vIndices = GetTableIndices(pbUtf8, PpcTableSize);
 | 
			
		||||
 | 
			
		||||
				foreach(int i in vIndices)
 | 
			
		||||
				{
 | 
			
		||||
					if(SetTableBit(vTable, i)) ++lBitsInTable;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
			sb.Append("\t\t\t");
 | 
			
		||||
			for(int i = 0; i < vTable.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(i > 0)
 | 
			
		||||
				{
 | 
			
		||||
					if((i % 3) == 0)
 | 
			
		||||
					{
 | 
			
		||||
						sb.AppendLine(",");
 | 
			
		||||
						sb.Append("\t\t\t");
 | 
			
		||||
					}
 | 
			
		||||
					else sb.Append(", ");
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				sb.Append("0x");
 | 
			
		||||
				sb.Append(vTable[i].ToString("X16"));
 | 
			
		||||
				sb.Append("UL");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sb.AppendLine();
 | 
			
		||||
			sb.AppendLine();
 | 
			
		||||
			sb.AppendLine("Bits set: " + lBitsInTable.ToString() + " of " +
 | 
			
		||||
				PpcTableSize.ToString());
 | 
			
		||||
			int cHashFn = GetTableIndices(StrUtil.Utf8.GetBytes("Dummy"), PpcTableSize).Length;
 | 
			
		||||
			sb.AppendLine("Hash functions: " + cHashFn.ToString());
 | 
			
		||||
			double dblPhi = Math.Pow(1.0 - ((double)cHashFn / PpcTableSize),
 | 
			
		||||
				(double)vPasswords.Count);
 | 
			
		||||
			sb.AppendLine("Phi (bits unset ratio) estimation: " +
 | 
			
		||||
				dblPhi.ToString(CultureInfo.InvariantCulture));
 | 
			
		||||
			dblPhi = ((double)(PpcTableSize - lBitsInTable) / (double)PpcTableSize);
 | 
			
		||||
			sb.AppendLine("Exact Phi: " + dblPhi.ToString(CultureInfo.InvariantCulture));
 | 
			
		||||
			sb.AppendLine("False positives ratio: " + Math.Pow(1.0 - dblPhi,
 | 
			
		||||
				(double)cHashFn).ToString(CultureInfo.InvariantCulture));
 | 
			
		||||
 | 
			
		||||
			File.WriteAllText("Table.txt", sb.ToString());
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										145
									
								
								src/KeePassLib2Android/Cryptography/QualityEstimation.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/KeePassLib2Android/Cryptography/QualityEstimation.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A class that offers static functions to estimate the quality of
 | 
			
		||||
	/// passwords.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class QualityEstimation
 | 
			
		||||
	{
 | 
			
		||||
		private enum CharSpaceBits : uint
 | 
			
		||||
		{
 | 
			
		||||
			Control = 32,
 | 
			
		||||
			Alpha = 26,
 | 
			
		||||
			Number = 10,
 | 
			
		||||
			Special = 33,
 | 
			
		||||
			High = 112
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Estimate the quality of a password.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="vPasswordChars">Password to check.</param>
 | 
			
		||||
		/// <returns>Estimated bit-strength of the password.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public static uint EstimatePasswordBits(char[] vPasswordChars)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(vPasswordChars != null);
 | 
			
		||||
			if(vPasswordChars == null) throw new ArgumentNullException("vPasswordChars");
 | 
			
		||||
 | 
			
		||||
			bool bChLower = false, bChUpper = false, bChNumber = false;
 | 
			
		||||
			bool bChSpecial = false, bChHigh = false, bChControl = false;
 | 
			
		||||
			Dictionary<char, uint> vCharCounts = new Dictionary<char, uint>();
 | 
			
		||||
			Dictionary<int, uint> vDifferences = new Dictionary<int, uint>();
 | 
			
		||||
			double dblEffectiveLength = 0.0;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < vPasswordChars.Length; ++i) // Get character types
 | 
			
		||||
			{
 | 
			
		||||
				char tch = vPasswordChars[i];
 | 
			
		||||
 | 
			
		||||
				if(tch < ' ') bChControl = true;
 | 
			
		||||
				else if((tch >= 'A') && (tch <= 'Z')) bChUpper = true;
 | 
			
		||||
				else if((tch >= 'a') && (tch <= 'z')) bChLower = true;
 | 
			
		||||
				else if((tch >= '0') && (tch <= '9')) bChNumber = true;
 | 
			
		||||
				else if((tch >= ' ') && (tch <= '/')) bChSpecial = true;
 | 
			
		||||
				else if((tch >= ':') && (tch <= '@')) bChSpecial = true;
 | 
			
		||||
				else if((tch >= '[') && (tch <= '`')) bChSpecial = true;
 | 
			
		||||
				else if((tch >= '{') && (tch <= '~')) bChSpecial = true;
 | 
			
		||||
				else if(tch > '~') bChHigh = true;
 | 
			
		||||
 | 
			
		||||
				double dblDiffFactor = 1.0;
 | 
			
		||||
				if(i >= 1)
 | 
			
		||||
				{
 | 
			
		||||
					int iDiff = (int)tch - (int)vPasswordChars[i - 1];
 | 
			
		||||
 | 
			
		||||
					uint uDiffCount;
 | 
			
		||||
					if(vDifferences.TryGetValue(iDiff, out uDiffCount))
 | 
			
		||||
					{
 | 
			
		||||
						++uDiffCount;
 | 
			
		||||
						vDifferences[iDiff] = uDiffCount;
 | 
			
		||||
						dblDiffFactor /= (double)uDiffCount;
 | 
			
		||||
					}
 | 
			
		||||
					else vDifferences.Add(iDiff, 1);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				uint uCharCount;
 | 
			
		||||
				if(vCharCounts.TryGetValue(tch, out uCharCount))
 | 
			
		||||
				{
 | 
			
		||||
					++uCharCount;
 | 
			
		||||
					vCharCounts[tch] = uCharCount;
 | 
			
		||||
					dblEffectiveLength += dblDiffFactor * (1.0 / (double)uCharCount);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					vCharCounts.Add(tch, 1);
 | 
			
		||||
					dblEffectiveLength += dblDiffFactor;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			uint uCharSpace = 0;
 | 
			
		||||
			if(bChControl) uCharSpace += (uint)CharSpaceBits.Control;
 | 
			
		||||
			if(bChUpper) uCharSpace += (uint)CharSpaceBits.Alpha;
 | 
			
		||||
			if(bChLower) uCharSpace += (uint)CharSpaceBits.Alpha;
 | 
			
		||||
			if(bChNumber) uCharSpace += (uint)CharSpaceBits.Number;
 | 
			
		||||
			if(bChSpecial) uCharSpace += (uint)CharSpaceBits.Special;
 | 
			
		||||
			if(bChHigh) uCharSpace += (uint)CharSpaceBits.High;
 | 
			
		||||
 | 
			
		||||
			if(uCharSpace == 0) return 0;
 | 
			
		||||
 | 
			
		||||
			double dblBitsPerChar = Math.Log((double)uCharSpace) / Math.Log(2.0);
 | 
			
		||||
			double dblRating = dblBitsPerChar * dblEffectiveLength;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			char[] vLowerCopy = new char[vPasswordChars.Length];
 | 
			
		||||
			for(int ilc = 0; ilc < vLowerCopy.Length; ++ilc)
 | 
			
		||||
				vLowerCopy[ilc] = char.ToLower(vPasswordChars[ilc]);
 | 
			
		||||
			if(PopularPasswords.IsPopularPassword(vLowerCopy)) dblRating /= 8.0;
 | 
			
		||||
			Array.Clear(vLowerCopy, 0, vLowerCopy.Length);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return (uint)Math.Ceiling(dblRating);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Estimate the quality of a password.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbUnprotectedUtf8">Password to check, UTF-8 encoded.</param>
 | 
			
		||||
		/// <returns>Estimated bit-strength of the password.</returns>
 | 
			
		||||
		public static uint EstimatePasswordBits(byte[] pbUnprotectedUtf8)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbUnprotectedUtf8 == null) { Debug.Assert(false); return 0; }
 | 
			
		||||
 | 
			
		||||
			char[] vChars = StrUtil.Utf8.GetChars(pbUnprotectedUtf8);
 | 
			
		||||
			uint uResult = EstimatePasswordBits(vChars);
 | 
			
		||||
			Array.Clear(vChars, 0, vChars.Length);
 | 
			
		||||
 | 
			
		||||
			return uResult;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										402
									
								
								src/KeePassLib2Android/Cryptography/SelfTest.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								src/KeePassLib2Android/Cryptography/SelfTest.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,402 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography.Cipher;
 | 
			
		||||
using KeePassLib.Keys;
 | 
			
		||||
using KeePassLib.Native;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Cryptography
 | 
			
		||||
{
 | 
			
		||||
/* #pragma warning disable 1591
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Return values of the <c>SelfTest.Perform</c> method.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum SelfTestResult
 | 
			
		||||
	{
 | 
			
		||||
		Success = 0,
 | 
			
		||||
		RijndaelEcbError = 1,
 | 
			
		||||
		Salsa20Error = 2,
 | 
			
		||||
		NativeKeyTransformationError = 3
 | 
			
		||||
	}
 | 
			
		||||
#pragma warning restore 1591 */
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Class containing self-test methods.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class SelfTest
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Perform a self-test.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static void Perform()
 | 
			
		||||
		{
 | 
			
		||||
			TestFipsComplianceProblems(); // Must be the first test
 | 
			
		||||
 | 
			
		||||
			TestRijndael();
 | 
			
		||||
			TestSalsa20();
 | 
			
		||||
			
 | 
			
		||||
			TestNativeKeyTransform();
 | 
			
		||||
			
 | 
			
		||||
			TestHmacOtp();
 | 
			
		||||
 | 
			
		||||
			TestProtectedObjects();
 | 
			
		||||
			TestMemUtil();
 | 
			
		||||
			TestStrUtil();
 | 
			
		||||
			TestUrlUtil();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert((int)PwIcon.World == 1);
 | 
			
		||||
			Debug.Assert((int)PwIcon.Warning == 2);
 | 
			
		||||
			Debug.Assert((int)PwIcon.BlackBerry == 68);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static void TestFipsComplianceProblems()
 | 
			
		||||
		{
 | 
			
		||||
			try { new RijndaelManaged(); }
 | 
			
		||||
			catch(Exception exAes)
 | 
			
		||||
			{
 | 
			
		||||
				throw new SecurityException("AES/Rijndael: " + exAes.Message);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			try { new SHA256Managed(); }
 | 
			
		||||
			catch(Exception exSha256)
 | 
			
		||||
			{
 | 
			
		||||
				throw new SecurityException("SHA-256: " + exSha256.Message);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestRijndael()
 | 
			
		||||
		{
 | 
			
		||||
			// Test vector (official ECB test vector #356)
 | 
			
		||||
			byte[] pbIV = new byte[16];
 | 
			
		||||
			byte[] pbTestKey = new byte[32];
 | 
			
		||||
			byte[] pbTestData = new byte[16];
 | 
			
		||||
			byte[] pbReferenceCT = new byte[16] {
 | 
			
		||||
				0x75, 0xD1, 0x1B, 0x0E, 0x3A, 0x68, 0xC4, 0x22,
 | 
			
		||||
				0x3D, 0x88, 0xDB, 0xF0, 0x17, 0x97, 0x7D, 0xD7 };
 | 
			
		||||
			int i;
 | 
			
		||||
 | 
			
		||||
			for(i = 0; i < 16; ++i) pbIV[i] = 0;
 | 
			
		||||
			for(i = 0; i < 32; ++i) pbTestKey[i] = 0;
 | 
			
		||||
			for(i = 0; i < 16; ++i) pbTestData[i] = 0;
 | 
			
		||||
			pbTestData[0] = 0x04;
 | 
			
		||||
 | 
			
		||||
			RijndaelManaged r = new RijndaelManaged();
 | 
			
		||||
 | 
			
		||||
			if(r.BlockSize != 128) // AES block size
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				r.BlockSize = 128;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			r.IV = pbIV;
 | 
			
		||||
			r.KeySize = 256;
 | 
			
		||||
			r.Key = pbTestKey;
 | 
			
		||||
			r.Mode = CipherMode.ECB;
 | 
			
		||||
			ICryptoTransform iCrypt = r.CreateEncryptor();
 | 
			
		||||
 | 
			
		||||
			iCrypt.TransformBlock(pbTestData, 0, 16, pbTestData, 0);
 | 
			
		||||
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pbTestData, pbReferenceCT))
 | 
			
		||||
				throw new SecurityException(KLRes.EncAlgorithmAes + ".");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestSalsa20()
 | 
			
		||||
		{
 | 
			
		||||
			// Test values from official set 6, vector 3
 | 
			
		||||
			byte[] pbKey= new byte[32] {
 | 
			
		||||
				0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
 | 
			
		||||
				0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
 | 
			
		||||
				0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
 | 
			
		||||
				0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C
 | 
			
		||||
			};
 | 
			
		||||
			byte[] pbIV = new byte[8] { 0x28, 0x8F, 0xF6, 0x5D,
 | 
			
		||||
				0xC4, 0x2B, 0x92, 0xF9 };
 | 
			
		||||
			byte[] pbExpected = new byte[16] {
 | 
			
		||||
				0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03,
 | 
			
		||||
				0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			byte[] pb = new byte[16];
 | 
			
		||||
			Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV);
 | 
			
		||||
			c.Encrypt(pb, pb.Length, false);
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pb, pbExpected))
 | 
			
		||||
				throw new SecurityException("Salsa20.");
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			// Extended test in debug mode
 | 
			
		||||
			byte[] pbExpected2 = new byte[16] {
 | 
			
		||||
				0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
 | 
			
		||||
				0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
 | 
			
		||||
			};
 | 
			
		||||
			byte[] pbExpected3 = new byte[16] {
 | 
			
		||||
				0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97,
 | 
			
		||||
				0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			Random r = new Random();
 | 
			
		||||
			int nPos = Salsa20ToPos(c, r, pb.Length, 65536);
 | 
			
		||||
			c.Encrypt(pb, pb.Length, false);
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pb, pbExpected2))
 | 
			
		||||
				throw new SecurityException("Salsa20-2.");
 | 
			
		||||
 | 
			
		||||
			nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
 | 
			
		||||
			Array.Clear(pb, 0, pb.Length);
 | 
			
		||||
			c.Encrypt(pb, pb.Length, true);
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pb, pbExpected3))
 | 
			
		||||
				throw new SecurityException("Salsa20-3.");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
		private static int Salsa20ToPos(Salsa20Cipher c, Random r, int nPos,
 | 
			
		||||
			int nTargetPos)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = new byte[512];
 | 
			
		||||
 | 
			
		||||
			while(nPos < nTargetPos)
 | 
			
		||||
			{
 | 
			
		||||
				int x = r.Next(1, 513);
 | 
			
		||||
				int nGen = Math.Min(nTargetPos - nPos, x);
 | 
			
		||||
				c.Encrypt(pb, nGen, r.Next(0, 2) == 0);
 | 
			
		||||
				nPos += nGen;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return nTargetPos;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		private static void TestNativeKeyTransform()
 | 
			
		||||
		{
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			byte[] pbOrgKey = CryptoRandom.Instance.GetRandomBytes(32);
 | 
			
		||||
			byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32);
 | 
			
		||||
			ulong uRounds = (ulong)((new Random()).Next(1, 0x3FFF));
 | 
			
		||||
 | 
			
		||||
			byte[] pbManaged = new byte[32];
 | 
			
		||||
			Array.Copy(pbOrgKey, pbManaged, 32);
 | 
			
		||||
			if(CompositeKey.TransformKeyManaged(pbManaged, pbSeed, uRounds) == false)
 | 
			
		||||
				throw new SecurityException("Managed transform.");
 | 
			
		||||
 | 
			
		||||
			byte[] pbNative = new byte[32];
 | 
			
		||||
			Array.Copy(pbOrgKey, pbNative, 32);
 | 
			
		||||
			if(NativeLib.TransformKey256(pbNative, pbSeed, uRounds) == false)
 | 
			
		||||
				return; // Native library not available ("success")
 | 
			
		||||
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pbManaged, pbNative))
 | 
			
		||||
				throw new SecurityException("Native transform.");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestMemUtil()
 | 
			
		||||
		{
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			Random r = new Random();
 | 
			
		||||
			byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next(
 | 
			
		||||
				0, 0x2FFFF));
 | 
			
		||||
 | 
			
		||||
			byte[] pbCompressed = MemUtil.Compress(pb);
 | 
			
		||||
			if(!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb))
 | 
			
		||||
				throw new InvalidOperationException("GZip");
 | 
			
		||||
 | 
			
		||||
			pb = Encoding.ASCII.GetBytes("012345678901234567890a");
 | 
			
		||||
			byte[] pbN = Encoding.ASCII.GetBytes("9012");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) != 9)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-1");
 | 
			
		||||
			pbN = Encoding.ASCII.GetBytes("01234567890123");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) != 0)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-2");
 | 
			
		||||
			pbN = Encoding.ASCII.GetBytes("a");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) != 21)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-3");
 | 
			
		||||
			pbN = Encoding.ASCII.GetBytes("0a");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) != 20)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-4");
 | 
			
		||||
			pbN = Encoding.ASCII.GetBytes("1");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) != 1)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-5");
 | 
			
		||||
			pbN = Encoding.ASCII.GetBytes("b");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-6");
 | 
			
		||||
			pbN = Encoding.ASCII.GetBytes("012b");
 | 
			
		||||
			if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
 | 
			
		||||
				throw new InvalidOperationException("MemUtil-7");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestHmacOtp()
 | 
			
		||||
		{
 | 
			
		||||
#if (DEBUG && !KeePassLibSD)
 | 
			
		||||
			byte[] pbSecret = Encoding.ASCII.GetBytes("12345678901234567890");
 | 
			
		||||
			string[] vExp = new string[]{ "755224", "287082", "359152",
 | 
			
		||||
				"969429", "338314", "254676", "287922", "162583", "399871",
 | 
			
		||||
				"520489" };
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < vExp.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(HmacOtp.Generate(pbSecret, (ulong)i, 6, false, -1) != vExp[i])
 | 
			
		||||
					throw new InvalidOperationException("HmacOtp");
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestProtectedObjects()
 | 
			
		||||
		{
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			byte[] pbData = Encoding.ASCII.GetBytes("Test Test Test Test");
 | 
			
		||||
			ProtectedBinary pb = new ProtectedBinary(true, pbData);
 | 
			
		||||
			if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-1");
 | 
			
		||||
 | 
			
		||||
			byte[] pbDec = pb.ReadData();
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pbData, pbDec))
 | 
			
		||||
				throw new SecurityException("ProtectedBinary-2");
 | 
			
		||||
			if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-3");
 | 
			
		||||
 | 
			
		||||
			byte[] pbData2 = Encoding.ASCII.GetBytes("Test Test Test Test");
 | 
			
		||||
			byte[] pbData3 = Encoding.ASCII.GetBytes("Test Test Test Test Test");
 | 
			
		||||
			ProtectedBinary pb2 = new ProtectedBinary(true, pbData2);
 | 
			
		||||
			ProtectedBinary pb3 = new ProtectedBinary(true, pbData3);
 | 
			
		||||
			if(!pb.Equals(pb2)) throw new SecurityException("ProtectedBinary-4");
 | 
			
		||||
			if(pb.Equals(pb3)) throw new SecurityException("ProtectedBinary-5");
 | 
			
		||||
			if(pb2.Equals(pb3)) throw new SecurityException("ProtectedBinary-6");
 | 
			
		||||
 | 
			
		||||
			if(pb.GetHashCode() != pb2.GetHashCode())
 | 
			
		||||
				throw new SecurityException("ProtectedBinary-7");
 | 
			
		||||
			if(!((object)pb).Equals((object)pb2))
 | 
			
		||||
				throw new SecurityException("ProtectedBinary-8");
 | 
			
		||||
			if(((object)pb).Equals((object)pb3))
 | 
			
		||||
				throw new SecurityException("ProtectedBinary-9");
 | 
			
		||||
			if(((object)pb2).Equals((object)pb3))
 | 
			
		||||
				throw new SecurityException("ProtectedBinary-10");
 | 
			
		||||
 | 
			
		||||
			ProtectedString ps = new ProtectedString();
 | 
			
		||||
			if(ps.Length != 0) throw new SecurityException("ProtectedString-1");
 | 
			
		||||
			if(!ps.IsEmpty) throw new SecurityException("ProtectedString-2");
 | 
			
		||||
			if(ps.ReadString().Length != 0)
 | 
			
		||||
				throw new SecurityException("ProtectedString-3");
 | 
			
		||||
 | 
			
		||||
			ps = new ProtectedString(true, "Test");
 | 
			
		||||
			ProtectedString ps2 = new ProtectedString(true,
 | 
			
		||||
				StrUtil.Utf8.GetBytes("Test"));
 | 
			
		||||
			if(ps.IsEmpty) throw new SecurityException("ProtectedString-4");
 | 
			
		||||
			pbData = ps.ReadUtf8();
 | 
			
		||||
			pbData2 = ps2.ReadUtf8();
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pbData, pbData2))
 | 
			
		||||
				throw new SecurityException("ProtectedString-5");
 | 
			
		||||
			if(pbData.Length != 4)
 | 
			
		||||
				throw new SecurityException("ProtectedString-6");
 | 
			
		||||
			if(ps.ReadString() != ps2.ReadString())
 | 
			
		||||
				throw new SecurityException("ProtectedString-7");
 | 
			
		||||
			pbData = ps.ReadUtf8();
 | 
			
		||||
			pbData2 = ps2.ReadUtf8();
 | 
			
		||||
			if(!MemUtil.ArraysEqual(pbData, pbData2))
 | 
			
		||||
				throw new SecurityException("ProtectedString-8");
 | 
			
		||||
			if(!ps.IsProtected) throw new SecurityException("ProtectedString-9");
 | 
			
		||||
			if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestStrUtil()
 | 
			
		||||
		{
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			string[] vSeps = new string[]{ "ax", "b", "c" };
 | 
			
		||||
			const string str1 = "axbqrstcdeax";
 | 
			
		||||
			List<string> v1 = StrUtil.SplitWithSep(str1, vSeps, true);
 | 
			
		||||
 | 
			
		||||
			if(v1.Count != 9) throw new InvalidOperationException("StrUtil-1");
 | 
			
		||||
			if(v1[0].Length > 0) throw new InvalidOperationException("StrUtil-2");
 | 
			
		||||
			if(!v1[1].Equals("ax")) throw new InvalidOperationException("StrUtil-3");
 | 
			
		||||
			if(v1[2].Length > 0) throw new InvalidOperationException("StrUtil-4");
 | 
			
		||||
			if(!v1[3].Equals("b")) throw new InvalidOperationException("StrUtil-5");
 | 
			
		||||
			if(!v1[4].Equals("qrst")) throw new InvalidOperationException("StrUtil-6");
 | 
			
		||||
			if(!v1[5].Equals("c")) throw new InvalidOperationException("StrUtil-7");
 | 
			
		||||
			if(!v1[6].Equals("de")) throw new InvalidOperationException("StrUtil-8");
 | 
			
		||||
			if(!v1[7].Equals("ax")) throw new InvalidOperationException("StrUtil-9");
 | 
			
		||||
			if(v1[8].Length > 0) throw new InvalidOperationException("StrUtil-10");
 | 
			
		||||
 | 
			
		||||
			const string str2 = "12ab56";
 | 
			
		||||
			List<string> v2 = StrUtil.SplitWithSep(str2, new string[]{ "AB" }, false);
 | 
			
		||||
			if(v2.Count != 3) throw new InvalidOperationException("StrUtil-11");
 | 
			
		||||
			if(!v2[0].Equals("12")) throw new InvalidOperationException("StrUtil-12");
 | 
			
		||||
			if(!v2[1].Equals("AB")) throw new InvalidOperationException("StrUtil-13");
 | 
			
		||||
			if(!v2[2].Equals("56")) throw new InvalidOperationException("StrUtil-14");
 | 
			
		||||
 | 
			
		||||
			List<string> v3 = StrUtil.SplitWithSep("pqrs", vSeps, false);
 | 
			
		||||
			if(v3.Count != 1) throw new InvalidOperationException("StrUtil-15");
 | 
			
		||||
			if(!v3[0].Equals("pqrs")) throw new InvalidOperationException("StrUtil-16");
 | 
			
		||||
 | 
			
		||||
			if(StrUtil.VersionToString(0x000F000E000D000CUL) != "15.14.13.12")
 | 
			
		||||
				throw new InvalidOperationException("StrUtil-V1");
 | 
			
		||||
			if(StrUtil.VersionToString(0x00FF000E00010000UL) != "255.14.1")
 | 
			
		||||
				throw new InvalidOperationException("StrUtil-V2");
 | 
			
		||||
			if(StrUtil.VersionToString(0x000F00FF00000000UL) != "15.255")
 | 
			
		||||
				throw new InvalidOperationException("StrUtil-V3");
 | 
			
		||||
			if(StrUtil.VersionToString(0x00FF000000000000UL) != "255")
 | 
			
		||||
				throw new InvalidOperationException("StrUtil-V4");
 | 
			
		||||
			if(StrUtil.VersionToString(0x00FF000000000000UL, true) != "255.0")
 | 
			
		||||
				throw new InvalidOperationException("StrUtil-V5");
 | 
			
		||||
			if(StrUtil.VersionToString(0x0000000000070000UL, true) != "0.0.7")
 | 
			
		||||
				throw new InvalidOperationException("StrUtil-V6");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void TestUrlUtil()
 | 
			
		||||
		{
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") !=
 | 
			
		||||
				"domain")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H1");
 | 
			
		||||
			if(UrlUtil.GetHost(@"http://example.org:80") != "example.org")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H2");
 | 
			
		||||
			if(UrlUtil.GetHost(@"mailto:bob@example.com") != "example.com")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H3");
 | 
			
		||||
			if(UrlUtil.GetHost(@"ftp://asmith@ftp.example.org") != "ftp.example.org")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H4");
 | 
			
		||||
			if(UrlUtil.GetHost(@"scheme://username:password@domain:port/path?query_string#fragment_id") !=
 | 
			
		||||
				"domain")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H5");
 | 
			
		||||
			if(UrlUtil.GetHost(@"bob@example.com") != "example.com")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H6");
 | 
			
		||||
			if(UrlUtil.GetHost(@"s://u:p@d.tld:p/p?q#f") != "d.tld")
 | 
			
		||||
				throw new InvalidOperationException("UrlUtil-H7");
 | 
			
		||||
 | 
			
		||||
			if(NativeLib.IsUnix()) return;
 | 
			
		||||
 | 
			
		||||
			string strBase = "\\\\HOMESERVER\\Apps\\KeePass\\KeePass.exe";
 | 
			
		||||
			string strDoc = "\\\\HOMESERVER\\Documents\\KeePass\\NewDatabase.kdbx";
 | 
			
		||||
			string strRel = "..\\..\\Documents\\KeePass\\NewDatabase.kdbx";
 | 
			
		||||
 | 
			
		||||
			string str = UrlUtil.MakeRelativePath(strBase, strDoc);
 | 
			
		||||
			if(!str.Equals(strRel)) throw new InvalidOperationException("UrlUtil-R1");
 | 
			
		||||
 | 
			
		||||
			str = UrlUtil.MakeAbsolutePath(strBase, strRel);
 | 
			
		||||
			if(!str.Equals(strDoc)) throw new InvalidOperationException("UrlUtil-R2");
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/KeePassLib2Android/Delegates/Handlers.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/KeePassLib2Android/Delegates/Handlers.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Delegates
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Function definition of a method that performs an action on a group.
 | 
			
		||||
	/// When traversing the internal tree, this function will be invoked
 | 
			
		||||
	/// for all visited groups.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="pg">Currently visited group.</param>
 | 
			
		||||
	/// <returns>You must return <c>true</c> if you want to continue the
 | 
			
		||||
	/// traversal. If you want to immediately stop the whole traversal,
 | 
			
		||||
	/// return <c>false</c>.</returns>
 | 
			
		||||
	public delegate bool GroupHandler(PwGroup pg);
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Function definition of a method that performs an action on an entry.
 | 
			
		||||
	/// When traversing the internal tree, this function will be invoked
 | 
			
		||||
	/// for all visited entries.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <param name="pe">Currently visited entry.</param>
 | 
			
		||||
	/// <returns>You must return <c>true</c> if you want to continue the
 | 
			
		||||
	/// traversal. If you want to immediately stop the whole traversal,
 | 
			
		||||
	/// return <c>false</c>.</returns>
 | 
			
		||||
	public delegate bool EntryHandler(PwEntry pe);
 | 
			
		||||
 | 
			
		||||
	public delegate void VoidDelegate();
 | 
			
		||||
 | 
			
		||||
	public delegate string StrPwEntryDelegate(string str, PwEntry pe);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/KeePassLib2Android/Interfaces/IDeepCloneable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/KeePassLib2Android/Interfaces/IDeepCloneable.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Interfaces
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Interface for objects that are deeply cloneable.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	/// <typeparam name="T">Reference type.</typeparam>
 | 
			
		||||
	public interface IDeepCloneable<T> where T : class
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Deeply clone the object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Cloned object.</returns>
 | 
			
		||||
		T CloneDeep();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								src/KeePassLib2Android/Interfaces/IStatusLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/KeePassLib2Android/Interfaces/IStatusLogger.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Interfaces
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Status message types.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum LogStatusType
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default type: simple information type.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Info = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Warning message.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Warning,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Error message.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Error,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Additional information. Depends on lines above.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		AdditionalInfo
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Status logging interface.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface IStatusLogger
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Function which needs to be called when logging is started.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strOperation">This string should roughly describe
 | 
			
		||||
		/// the operation, of which the status is logged.</param>
 | 
			
		||||
		/// <param name="bWriteOperationToLog">Specifies whether the
 | 
			
		||||
		/// operation is written to the log or not.</param>
 | 
			
		||||
		void StartLogging(string strOperation, bool bWriteOperationToLog);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Function which needs to be called when logging is ended
 | 
			
		||||
		/// (i.e. when no more messages will be logged and when the
 | 
			
		||||
		/// percent value won't change any more).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		void EndLogging();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set the current progress in percent.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uPercent">Percent of work finished.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the caller should continue
 | 
			
		||||
		/// the current work.</returns>
 | 
			
		||||
		bool SetProgress(uint uPercent);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set the current status text.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strNewText">Status text.</param>
 | 
			
		||||
		/// <param name="lsType">Type of the message.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the caller should continue
 | 
			
		||||
		/// the current work.</returns>
 | 
			
		||||
		bool SetText(string strNewText, LogStatusType lsType);
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Check if the user cancelled the current work.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the caller should continue
 | 
			
		||||
		/// the current work.</returns>
 | 
			
		||||
		bool ContinueWork();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class NullStatusLogger : IStatusLogger
 | 
			
		||||
	{
 | 
			
		||||
		public void StartLogging(string strOperation, bool bWriteOperationToLog) { }
 | 
			
		||||
		public void EndLogging() { }
 | 
			
		||||
		public bool SetProgress(uint uPercent) { return true; }
 | 
			
		||||
		public bool SetText(string strNewText, LogStatusType lsType) { return true; }
 | 
			
		||||
		public bool ContinueWork() { return true; }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/KeePassLib2Android/Interfaces/IStructureItem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/KeePassLib2Android/Interfaces/IStructureItem.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Interfaces
 | 
			
		||||
{
 | 
			
		||||
	public interface IStructureItem : ITimeLogger // Provides LocationChanged
 | 
			
		||||
	{
 | 
			
		||||
		PwUuid Uuid
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		PwGroup ParentGroup
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								src/KeePassLib2Android/Interfaces/ITimeLogger.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/KeePassLib2Android/Interfaces/ITimeLogger.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Interfaces
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Interface for objects that support various times (creation time, last
 | 
			
		||||
	/// access time, last modification time and expiry time). Offers
 | 
			
		||||
	/// several helper functions (for example a function to touch the current
 | 
			
		||||
	/// object).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface ITimeLogger
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the object was created.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		DateTime CreationTime
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the object was last accessed.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		DateTime LastAccessTime
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the object was last modified.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		DateTime LastModificationTime
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the object expires.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		DateTime ExpiryTime
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Flag that determines if the object does expire.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		bool Expires
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set the usage count of the object. To increase the usage
 | 
			
		||||
		/// count by one, use the <c>Touch</c> function.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		ulong UsageCount
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the location of the object was last changed.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		DateTime LocationChanged
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
			set;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Touch the object. This function updates the internal last access
 | 
			
		||||
		/// time. If the <paramref name="bModified" /> parameter is <c>true</c>,
 | 
			
		||||
		/// the last modification time gets updated, too. Each time you call
 | 
			
		||||
		/// <c>Touch</c>, the usage count of the object is increased by one.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bModified">Update last modification time.</param>
 | 
			
		||||
		void Touch(bool bModified);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/KeePassLib2Android/Interfaces/IUIOperations.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/KeePassLib2Android/Interfaces/IUIOperations.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Interfaces
 | 
			
		||||
{
 | 
			
		||||
	public interface IUIOperations
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Let the user interface save the current database.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bForceSave">If <c>true</c>, the UI will not ask for
 | 
			
		||||
		/// whether to synchronize or overwrite, it'll simply overwrite the
 | 
			
		||||
		/// file.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the file has been saved.</returns>
 | 
			
		||||
		bool UIFileSave(bool bForceSave);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								src/KeePassLib2Android/Interfaces/IXmlSerializerEx.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/KeePassLib2Android/Interfaces/IXmlSerializerEx.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Interfaces
 | 
			
		||||
{
 | 
			
		||||
	public interface IXmlSerializerEx
 | 
			
		||||
	{
 | 
			
		||||
		void Serialize(XmlWriter xmlWriter, object o);
 | 
			
		||||
		object Deserialize(Stream s);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/KeePassLib2Android/KeePassLib.pfx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/KeePassLib2Android/KeePassLib.pfx
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										140
									
								
								src/KeePassLib2Android/KeePassLib2Android.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/KeePassLib2Android/KeePassLib2Android.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
			
		||||
    <ProductVersion>10.0.0</ProductVersion>
 | 
			
		||||
    <SchemaVersion>2.0</SchemaVersion>
 | 
			
		||||
    <ProjectGuid>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</ProjectGuid>
 | 
			
		||||
    <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
 | 
			
		||||
    <OutputType>Library</OutputType>
 | 
			
		||||
    <RootNamespace>KeePassLib2Android</RootNamespace>
 | 
			
		||||
    <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
 | 
			
		||||
    <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
 | 
			
		||||
    <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
 | 
			
		||||
    <AndroidResgenClass>Resource</AndroidResgenClass>
 | 
			
		||||
    <AssemblyName>KeePassLib2Android</AssemblyName>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>True</DebugSymbols>
 | 
			
		||||
    <DebugType>full</DebugType>
 | 
			
		||||
    <Optimize>False</Optimize>
 | 
			
		||||
    <OutputPath>bin\Debug</OutputPath>
 | 
			
		||||
    <DefineConstants>DEBUG;</DefineConstants>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
    <ConsolePause>False</ConsolePause>
 | 
			
		||||
    <AndroidLinkMode>None</AndroidLinkMode>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
 | 
			
		||||
    <DebugType>none</DebugType>
 | 
			
		||||
    <Optimize>True</Optimize>
 | 
			
		||||
    <OutputPath>bin\Release</OutputPath>
 | 
			
		||||
    <ErrorReport>prompt</ErrorReport>
 | 
			
		||||
    <WarningLevel>4</WarningLevel>
 | 
			
		||||
    <AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
 | 
			
		||||
    <ConsolePause>False</ConsolePause>
 | 
			
		||||
    <AndroidLinkMode>SdkOnly</AndroidLinkMode>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Reference Include="System" />
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
    <Reference Include="Mono.Android" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="Resources\Resource.designer.cs" />
 | 
			
		||||
    <Compile Include="Resources\KLRes.Generated.cs" />
 | 
			
		||||
    <Compile Include="Resources\KSRes.Generated.cs" />
 | 
			
		||||
    <Compile Include="Collections\AutoTypeConfig.cs" />
 | 
			
		||||
    <Compile Include="Collections\ProtectedBinaryDictionary.cs" />
 | 
			
		||||
    <Compile Include="Collections\ProtectedStringDictionary.cs" />
 | 
			
		||||
    <Compile Include="Collections\PwObjectList.cs" />
 | 
			
		||||
    <Compile Include="Collections\PwObjectPool.cs" />
 | 
			
		||||
    <Compile Include="Collections\StringDictionaryEx.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\Cipher\CipherPool.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\Cipher\Salsa20Cipher.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\Cipher\StandardAesEngine.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\CryptoRandom.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\CryptoRandomStream.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\Cipher\ICipherEngine.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\HashingStreamEx.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\HmacOtp.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\CharSetBasedGenerator.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\CustomPwGenerator.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\CustomPwGeneratorPool.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\PatternBasedGenerator.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\PwCharSet.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\PwProfile.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PopularPasswords.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\QualityEstimation.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\SelfTest.cs" />
 | 
			
		||||
    <Compile Include="Cryptography\PasswordGenerator\PwGenerator.cs" />
 | 
			
		||||
    <Compile Include="PwCustomIcon.cs" />
 | 
			
		||||
    <Compile Include="PwDatabase.cs" />
 | 
			
		||||
    <Compile Include="PwDefs.cs" />
 | 
			
		||||
    <Compile Include="PwDeletedObject.cs" />
 | 
			
		||||
    <Compile Include="PwEntry.cs" />
 | 
			
		||||
    <Compile Include="PwEnums.cs" />
 | 
			
		||||
    <Compile Include="PwGroup.cs" />
 | 
			
		||||
    <Compile Include="PwUuid.cs" />
 | 
			
		||||
    <Compile Include="Interfaces\IStructureItem.cs" />
 | 
			
		||||
    <Compile Include="Interfaces\IUIOperations.cs" />
 | 
			
		||||
    <Compile Include="Interfaces\IXmlSerializerEx.cs" />
 | 
			
		||||
    <Compile Include="Interfaces\IDeepCloneable.cs" />
 | 
			
		||||
    <Compile Include="Interfaces\IStatusLogger.cs" />
 | 
			
		||||
    <Compile Include="Interfaces\ITimeLogger.cs" />
 | 
			
		||||
    <Compile Include="Keys\KcpCustomKey.cs" />
 | 
			
		||||
    <Compile Include="Keys\KeyProvider.cs" />
 | 
			
		||||
    <Compile Include="Keys\KeyProviderPool.cs" />
 | 
			
		||||
    <Compile Include="Keys\KeyValidator.cs" />
 | 
			
		||||
    <Compile Include="Keys\KeyValidatorPool.cs" />
 | 
			
		||||
    <Compile Include="Keys\UserKeyType.cs" />
 | 
			
		||||
    <Compile Include="Keys\KcpKeyFile.cs" />
 | 
			
		||||
    <Compile Include="Keys\IUserKey.cs" />
 | 
			
		||||
    <Compile Include="Keys\KcpPassword.cs" />
 | 
			
		||||
    <Compile Include="Keys\KcpUserAccount.cs" />
 | 
			
		||||
    <Compile Include="Keys\CompositeKey.cs" />
 | 
			
		||||
    <Compile Include="Native\NativeMethods.cs" />
 | 
			
		||||
    <Compile Include="Native\NativeLib.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="Security\XorredBuffer.cs" />
 | 
			
		||||
    <Compile Include="Security\ProtectedBinary.cs" />
 | 
			
		||||
    <Compile Include="Security\ProtectedString.cs" />
 | 
			
		||||
    <Compile Include="Serialization\BinaryReaderEx.cs" />
 | 
			
		||||
    <Compile Include="Serialization\FileLock.cs" />
 | 
			
		||||
    <Compile Include="Serialization\FileTransactionEx.cs" />
 | 
			
		||||
    <Compile Include="Serialization\HashedBlockStream.cs" />
 | 
			
		||||
    <Compile Include="Serialization\IOConnection.cs">
 | 
			
		||||
      <SubType>Component</SubType>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="Serialization\KdbxFile.cs" />
 | 
			
		||||
    <Compile Include="Serialization\KdbxFile.Read.cs" />
 | 
			
		||||
    <Compile Include="Serialization\KdbxFile.Read.Streamed.cs" />
 | 
			
		||||
    <Compile Include="Serialization\KdbxFile.Write.cs" />
 | 
			
		||||
    <Compile Include="Serialization\IOConnectionInfo.cs" />
 | 
			
		||||
    <Compile Include="Serialization\OldFormatException.cs" />
 | 
			
		||||
    <Compile Include="Translation\KPControlCustomization.cs" />
 | 
			
		||||
    <Compile Include="Translation\KPFormCustomization.cs" />
 | 
			
		||||
    <Compile Include="Translation\KPStringTable.cs" />
 | 
			
		||||
    <Compile Include="Translation\KPStringTableItem.cs" />
 | 
			
		||||
    <Compile Include="Translation\KPTranslation.cs" />
 | 
			
		||||
    <Compile Include="Translation\KPTranslationProperties.cs" />
 | 
			
		||||
    <Compile Include="Utility\AppLogEx.cs" />
 | 
			
		||||
    <Compile Include="Utility\GfxUtil.cs" />
 | 
			
		||||
    <Compile Include="Utility\MemUtil.cs" />
 | 
			
		||||
    <Compile Include="Utility\MessageService.cs" />
 | 
			
		||||
    <Compile Include="Utility\StrUtil.cs" />
 | 
			
		||||
    <Compile Include="Utility\UrlUtil.cs" />
 | 
			
		||||
    <Compile Include="Utility\TimeUtil.cs" />
 | 
			
		||||
    <Compile Include="Delegates\Handlers.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include="Resources\AboutResources.txt" />
 | 
			
		||||
    <None Include="KeePassLib.pfx" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <AndroidResource Include="Resources\values\Strings.xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" />
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										408
									
								
								src/KeePassLib2Android/Keys/CompositeKey.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										408
									
								
								src/KeePassLib2Android/Keys/CompositeKey.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,408 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Native;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Represents a key. A key can be build up using several user key data sources
 | 
			
		||||
	/// like a password, a key file, the currently logged on user credentials,
 | 
			
		||||
	/// the current computer ID, etc.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class CompositeKey
 | 
			
		||||
	{
 | 
			
		||||
		private List<IUserKey> m_vUserKeys = new List<IUserKey>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// List of all user keys contained in the current composite key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public IEnumerable<IUserKey> UserKeys
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vUserKeys; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public uint UserKeyCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return (uint)m_vUserKeys.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new, empty key object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public CompositeKey()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// /// <summary>
 | 
			
		||||
		// /// Deconstructor, clears up the key.
 | 
			
		||||
		// /// </summary>
 | 
			
		||||
		// ~CompositeKey()
 | 
			
		||||
		// {
 | 
			
		||||
		//	Clear();
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
		// /// <summary>
 | 
			
		||||
		// /// Clears the key. This function also erases all previously stored
 | 
			
		||||
		// /// user key data objects.
 | 
			
		||||
		// /// </summary>
 | 
			
		||||
		// public void Clear()
 | 
			
		||||
		// {
 | 
			
		||||
		//	foreach(IUserKey pKey in m_vUserKeys)
 | 
			
		||||
		//		pKey.Clear();
 | 
			
		||||
		//	m_vUserKeys.Clear();
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Add a user key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pKey">User key to add.</param>
 | 
			
		||||
		public void AddUserKey(IUserKey pKey)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pKey != null); if(pKey == null) throw new ArgumentNullException("pKey");
 | 
			
		||||
 | 
			
		||||
			m_vUserKeys.Add(pKey);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Remove a user key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pKey">User key to remove.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the key was removed successfully.</returns>
 | 
			
		||||
		public bool RemoveUserKey(IUserKey pKey)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pKey != null); if(pKey == null) throw new ArgumentNullException("pKey");
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(m_vUserKeys.IndexOf(pKey) >= 0);
 | 
			
		||||
			return m_vUserKeys.Remove(pKey);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Test whether the composite key contains a specific type of
 | 
			
		||||
		/// user keys (password, key file, ...). If at least one user
 | 
			
		||||
		/// key of that type is present, the function returns <c>true</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="tUserKeyType">User key type.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c>, if the composite key contains
 | 
			
		||||
		/// a user key of the specified type.</returns>
 | 
			
		||||
		public bool ContainsType(Type tUserKeyType)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(tUserKeyType != null);
 | 
			
		||||
			if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType");
 | 
			
		||||
 | 
			
		||||
			foreach(IUserKey pKey in m_vUserKeys)
 | 
			
		||||
			{
 | 
			
		||||
				if(tUserKeyType.IsInstanceOfType(pKey))
 | 
			
		||||
					return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the first user key of a specified type.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="tUserKeyType">Type of the user key to get.</param>
 | 
			
		||||
		/// <returns>Returns the first user key of the specified type
 | 
			
		||||
		/// or <c>null</c> if no key of that type is found.</returns>
 | 
			
		||||
		public IUserKey GetUserKey(Type tUserKeyType)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(tUserKeyType != null);
 | 
			
		||||
			if(tUserKeyType == null) throw new ArgumentNullException("tUserKeyType");
 | 
			
		||||
 | 
			
		||||
			foreach(IUserKey pKey in m_vUserKeys)
 | 
			
		||||
			{
 | 
			
		||||
				if(tUserKeyType.IsInstanceOfType(pKey))
 | 
			
		||||
					return pKey;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Creates the composite key from the supplied user key sources (password,
 | 
			
		||||
		/// key file, user account, computer ID, etc.).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private byte[] CreateRawCompositeKey32()
 | 
			
		||||
		{
 | 
			
		||||
			ValidateUserKeys();
 | 
			
		||||
 | 
			
		||||
			// Concatenate user key data
 | 
			
		||||
			MemoryStream ms = new MemoryStream();
 | 
			
		||||
			foreach(IUserKey pKey in m_vUserKeys)
 | 
			
		||||
			{
 | 
			
		||||
				ProtectedBinary b = pKey.KeyData;
 | 
			
		||||
				if(b != null)
 | 
			
		||||
				{
 | 
			
		||||
					byte[] pbKeyData = b.ReadData();
 | 
			
		||||
					ms.Write(pbKeyData, 0, pbKeyData.Length);
 | 
			
		||||
					MemUtil.ZeroByteArray(pbKeyData);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			byte[] pbHash = sha256.ComputeHash(ms.ToArray());
 | 
			
		||||
			ms.Close();
 | 
			
		||||
			return pbHash;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool EqualsValue(CompositeKey ckOther)
 | 
			
		||||
		{
 | 
			
		||||
			if(ckOther == null) throw new ArgumentNullException("ckOther");
 | 
			
		||||
 | 
			
		||||
			byte[] pbThis = CreateRawCompositeKey32();
 | 
			
		||||
			byte[] pbOther = ckOther.CreateRawCompositeKey32();
 | 
			
		||||
			bool bResult = MemUtil.ArraysEqual(pbThis, pbOther);
 | 
			
		||||
			Array.Clear(pbOther, 0, pbOther.Length);
 | 
			
		||||
			Array.Clear(pbThis, 0, pbThis.Length);
 | 
			
		||||
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Generate a 32-bit wide key out of the composite key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbKeySeed32">Seed used in the key transformation
 | 
			
		||||
		/// rounds. Must be a byte array containing exactly 32 bytes; must
 | 
			
		||||
		/// not be null.</param>
 | 
			
		||||
		/// <param name="uNumRounds">Number of key transformation rounds.</param>
 | 
			
		||||
		/// <returns>Returns a protected binary object that contains the
 | 
			
		||||
		/// resulting 32-bit wide key.</returns>
 | 
			
		||||
		public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pbKeySeed32 != null);
 | 
			
		||||
			if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
 | 
			
		||||
			Debug.Assert(pbKeySeed32.Length == 32);
 | 
			
		||||
			if(pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32");
 | 
			
		||||
 | 
			
		||||
			byte[] pbRaw32 = CreateRawCompositeKey32();
 | 
			
		||||
			if((pbRaw32 == null) || (pbRaw32.Length != 32))
 | 
			
		||||
				{ Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			byte[] pbTrf32 = TransformKey(pbRaw32, pbKeySeed32, uNumRounds);
 | 
			
		||||
			if((pbTrf32 == null) || (pbTrf32.Length != 32))
 | 
			
		||||
				{ Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbTrf32);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbRaw32);
 | 
			
		||||
 | 
			
		||||
			return pbRet;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void ValidateUserKeys()
 | 
			
		||||
		{
 | 
			
		||||
			int nAccounts = 0;
 | 
			
		||||
 | 
			
		||||
			foreach(IUserKey uKey in m_vUserKeys)
 | 
			
		||||
			{
 | 
			
		||||
				if(uKey is KcpUserAccount)
 | 
			
		||||
					++nAccounts;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(nAccounts >= 2)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				throw new InvalidOperationException();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Transform the current key <c>uNumRounds</c> times.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbOriginalKey32">The original key which will be transformed.
 | 
			
		||||
		/// This parameter won't be modified.</param>
 | 
			
		||||
		/// <param name="pbKeySeed32">Seed used for key transformations. Must not
 | 
			
		||||
		/// be <c>null</c>. This parameter won't be modified.</param>
 | 
			
		||||
		/// <param name="uNumRounds">Transformation count.</param>
 | 
			
		||||
		/// <returns>256-bit transformed key.</returns>
 | 
			
		||||
		private static byte[] TransformKey(byte[] pbOriginalKey32, byte[] pbKeySeed32,
 | 
			
		||||
			ulong uNumRounds)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((pbOriginalKey32 != null) && (pbOriginalKey32.Length == 32));
 | 
			
		||||
			if(pbOriginalKey32 == null) throw new ArgumentNullException("pbOriginalKey32");
 | 
			
		||||
			if(pbOriginalKey32.Length != 32) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert((pbKeySeed32 != null) && (pbKeySeed32.Length == 32));
 | 
			
		||||
			if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
 | 
			
		||||
			if(pbKeySeed32.Length != 32) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			byte[] pbNewKey = new byte[32];
 | 
			
		||||
			Array.Copy(pbOriginalKey32, pbNewKey, pbNewKey.Length);
 | 
			
		||||
 | 
			
		||||
			// Try to use the native library first
 | 
			
		||||
			if(NativeLib.TransformKey256(pbNewKey, pbKeySeed32, uNumRounds))
 | 
			
		||||
				return (new SHA256Managed()).ComputeHash(pbNewKey);
 | 
			
		||||
 | 
			
		||||
			if(TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds) == false)
 | 
			
		||||
				return null;
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			return sha256.ComputeHash(pbNewKey);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
 | 
			
		||||
			ulong uNumRounds)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbIV = new byte[16];
 | 
			
		||||
			Array.Clear(pbIV, 0, pbIV.Length);
 | 
			
		||||
 | 
			
		||||
			RijndaelManaged r = new RijndaelManaged();
 | 
			
		||||
			if(r.BlockSize != 128) // AES block size
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				r.BlockSize = 128;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			r.IV = pbIV;
 | 
			
		||||
			r.Mode = CipherMode.ECB;
 | 
			
		||||
			r.KeySize = 256;
 | 
			
		||||
			r.Key = pbKeySeed32;
 | 
			
		||||
			ICryptoTransform iCrypt = r.CreateEncryptor();
 | 
			
		||||
 | 
			
		||||
			// !iCrypt.CanReuseTransform -- doesn't work with Mono
 | 
			
		||||
			if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
 | 
			
		||||
				(iCrypt.OutputBlockSize != 16))
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false, "Invalid ICryptoTransform.");
 | 
			
		||||
				Debug.Assert((iCrypt.InputBlockSize == 16), "Invalid input block size!");
 | 
			
		||||
				Debug.Assert((iCrypt.OutputBlockSize == 16), "Invalid output block size!");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for(ulong i = 0; i < uNumRounds; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				iCrypt.TransformBlock(pbNewKey32, 0, 16, pbNewKey32, 0);
 | 
			
		||||
				iCrypt.TransformBlock(pbNewKey32, 16, 16, pbNewKey32, 16);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Benchmark the <c>TransformKey</c> method. Within
 | 
			
		||||
		/// <paramref name="uMilliseconds"/> ms, random keys will be transformed
 | 
			
		||||
		/// and the number of performed transformations are returned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uMilliseconds">Test duration in ms.</param>
 | 
			
		||||
		/// <param name="uStep">Stepping.
 | 
			
		||||
		/// <paramref name="uStep" /> should be a prime number. For fast processors
 | 
			
		||||
		/// (PCs) a value of <c>3001</c> is recommended, for slower processors (PocketPC)
 | 
			
		||||
		/// a value of <c>401</c> is recommended.</param>
 | 
			
		||||
		/// <returns>Number of transformations performed in the specified
 | 
			
		||||
		/// amount of time. Maximum value is <c>uint.MaxValue</c>.</returns>
 | 
			
		||||
		public static ulong TransformKeyBenchmark(uint uMilliseconds, ulong uStep)
 | 
			
		||||
		{
 | 
			
		||||
			ulong uRounds;
 | 
			
		||||
 | 
			
		||||
			// Try native method
 | 
			
		||||
			if(NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds))
 | 
			
		||||
				return uRounds;
 | 
			
		||||
 | 
			
		||||
			byte[] pbIV = new byte[16];
 | 
			
		||||
			Array.Clear(pbIV, 0, pbIV.Length);
 | 
			
		||||
 | 
			
		||||
			byte[] pbKey = new byte[32];
 | 
			
		||||
			byte[] pbNewKey = new byte[32];
 | 
			
		||||
			for(int i = 0; i < pbKey.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				pbKey[i] = (byte)i;
 | 
			
		||||
				pbNewKey[i] = (byte)i;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			RijndaelManaged r = new RijndaelManaged();
 | 
			
		||||
			if(r.BlockSize != 128) // AES block size
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				r.BlockSize = 128;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			r.IV = pbIV;
 | 
			
		||||
			r.Mode = CipherMode.ECB;
 | 
			
		||||
			r.KeySize = 256;
 | 
			
		||||
			r.Key = pbKey;
 | 
			
		||||
			ICryptoTransform iCrypt = r.CreateEncryptor();
 | 
			
		||||
 | 
			
		||||
			// !iCrypt.CanReuseTransform -- doesn't work with Mono
 | 
			
		||||
			if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
 | 
			
		||||
				(iCrypt.OutputBlockSize != 16))
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false, "Invalid ICryptoTransform.");
 | 
			
		||||
				Debug.Assert(iCrypt.InputBlockSize == 16, "Invalid input block size!");
 | 
			
		||||
				Debug.Assert(iCrypt.OutputBlockSize == 16, "Invalid output block size!");
 | 
			
		||||
				return PwDefs.DefaultKeyEncryptionRounds;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			DateTime dtStart = DateTime.Now;
 | 
			
		||||
			TimeSpan ts;
 | 
			
		||||
			double dblReqMillis = uMilliseconds;
 | 
			
		||||
 | 
			
		||||
			uRounds = 0;
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				for(ulong j = 0; j < uStep; ++j)
 | 
			
		||||
				{
 | 
			
		||||
					iCrypt.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0);
 | 
			
		||||
					iCrypt.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				uRounds += uStep;
 | 
			
		||||
				if(uRounds < uStep) // Overflow check
 | 
			
		||||
				{
 | 
			
		||||
					uRounds = ulong.MaxValue;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				ts = DateTime.Now - dtStart;
 | 
			
		||||
				if(ts.TotalMilliseconds > dblReqMillis) break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return uRounds;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class InvalidCompositeKeyException : Exception
 | 
			
		||||
	{
 | 
			
		||||
		public override string Message
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				return KLRes.InvalidCompositeKey + MessageService.NewParagraph +
 | 
			
		||||
					KLRes.InvalidCompositeKeyHint;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new invalid composite key exception.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public InvalidCompositeKeyException()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								src/KeePassLib2Android/Keys/IUserKey.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/KeePassLib2Android/Keys/IUserKey.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Interface to a user key, like a password, key file data, etc.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public interface IUserKey
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get key data. Querying this property is fast (it returns a
 | 
			
		||||
		/// reference to a cached <c>ProtectedBinary</c> object).
 | 
			
		||||
		/// If no key data is available, <c>null</c> is returned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		ProtectedBinary KeyData
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// /// <summary>
 | 
			
		||||
		// /// Clear the key and securely erase all security-critical information.
 | 
			
		||||
		// /// </summary>
 | 
			
		||||
		// void Clear();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								src/KeePassLib2Android/Keys/KcpCustomKey.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/KeePassLib2Android/Keys/KcpCustomKey.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KcpCustomKey : IUserKey
 | 
			
		||||
	{
 | 
			
		||||
		private readonly string m_strName;
 | 
			
		||||
		private ProtectedBinary m_pbKey;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Name of the provider that generated the custom key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string Name
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strName; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ProtectedBinary KeyData
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbKey; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
			Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
 | 
			
		||||
 | 
			
		||||
			m_strName = strName;
 | 
			
		||||
 | 
			
		||||
			if(bPerformHash)
 | 
			
		||||
			{
 | 
			
		||||
				SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
				byte[] pbRaw = sha256.ComputeHash(pbKeyData);
 | 
			
		||||
				m_pbKey = new ProtectedBinary(true, pbRaw);
 | 
			
		||||
			}
 | 
			
		||||
			else m_pbKey = new ProtectedBinary(true, pbKeyData);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// public void Clear()
 | 
			
		||||
		// {
 | 
			
		||||
		//	m_pbKey = null;
 | 
			
		||||
		// }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										271
									
								
								src/KeePassLib2Android/Keys/KcpKeyFile.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								src/KeePassLib2Android/Keys/KcpKeyFile.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,271 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Serialization;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Key files as provided by the user.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class KcpKeyFile : IUserKey
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strPath;
 | 
			
		||||
		private ProtectedBinary m_pbKeyData;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Path to the key file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string Path
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strPath; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get key data. Querying this property is fast (it returns a
 | 
			
		||||
		/// reference to a cached <c>ProtectedBinary</c> object).
 | 
			
		||||
		/// If no key data is available, <c>null</c> is returned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedBinary KeyData
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbKeyData; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KcpKeyFile(string strKeyFile)
 | 
			
		||||
		{
 | 
			
		||||
			Construct(IOConnectionInfo.FromPath(strKeyFile));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KcpKeyFile(IOConnectionInfo iocKeyFile)
 | 
			
		||||
		{
 | 
			
		||||
			Construct(iocKeyFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Construct(IOConnectionInfo iocFile)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbFileData = IOConnection.ReadFile(iocFile);
 | 
			
		||||
			if(pbFileData == null) throw new FileNotFoundException();
 | 
			
		||||
 | 
			
		||||
			byte[] pbKey = LoadXmlKeyFile(pbFileData);
 | 
			
		||||
			if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
 | 
			
		||||
 | 
			
		||||
			if(pbKey == null) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			m_strPath = iocFile.Path;
 | 
			
		||||
			m_pbKeyData = new ProtectedBinary(true, pbKey);
 | 
			
		||||
 | 
			
		||||
			MemUtil.ZeroByteArray(pbKey);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// public void Clear()
 | 
			
		||||
		// {
 | 
			
		||||
		//	m_strPath = string.Empty;
 | 
			
		||||
		//	m_pbKeyData = null;
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
		private static byte[] LoadKeyFile(byte[] pbFileData)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbFileData == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			int iLength = pbFileData.Length;
 | 
			
		||||
 | 
			
		||||
			byte[] pbKey = null;
 | 
			
		||||
			if(iLength == 32) pbKey = LoadBinaryKey32(pbFileData);
 | 
			
		||||
			else if(iLength == 64) pbKey = LoadHexKey32(pbFileData);
 | 
			
		||||
 | 
			
		||||
			if(pbKey == null)
 | 
			
		||||
			{
 | 
			
		||||
				SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
				pbKey = sha256.ComputeHash(pbFileData);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pbKey;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static byte[] LoadBinaryKey32(byte[] pbFileData)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbFileData == null) { Debug.Assert(false); return null; }
 | 
			
		||||
			if(pbFileData.Length != 32) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			return pbFileData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static byte[] LoadHexKey32(byte[] pbFileData)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbFileData == null) { Debug.Assert(false); return null; }
 | 
			
		||||
			if(pbFileData.Length != 64) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				string strHex = Encoding.ASCII.GetString(pbFileData, 0, 64);
 | 
			
		||||
				if(!StrUtil.IsHexString(strHex, true)) return null;
 | 
			
		||||
 | 
			
		||||
				byte[] pbKey = MemUtil.HexStringToByteArray(strHex);
 | 
			
		||||
				if((pbKey == null) || (pbKey.Length != 32))
 | 
			
		||||
					return null;
 | 
			
		||||
 | 
			
		||||
				return pbKey;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Create a new, random key-file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strFilePath">Path where the key-file should be saved to.
 | 
			
		||||
		/// If the file exists already, it will be overwritten.</param>
 | 
			
		||||
		/// <param name="pbAdditionalEntropy">Additional entropy used to generate
 | 
			
		||||
		/// the random key. May be <c>null</c> (in this case only the KeePass-internal
 | 
			
		||||
		/// random number generator is used).</param>
 | 
			
		||||
		/// <returns>Returns a <c>FileSaveResult</c> error code.</returns>
 | 
			
		||||
		public static void Create(string strFilePath, byte[] pbAdditionalEntropy)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);
 | 
			
		||||
			if(pbKey32 == null) throw new SecurityException();
 | 
			
		||||
 | 
			
		||||
			byte[] pbFinalKey32;
 | 
			
		||||
			if((pbAdditionalEntropy == null) || (pbAdditionalEntropy.Length == 0))
 | 
			
		||||
				pbFinalKey32 = pbKey32;
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				MemoryStream ms = new MemoryStream();
 | 
			
		||||
				ms.Write(pbAdditionalEntropy, 0, pbAdditionalEntropy.Length);
 | 
			
		||||
				ms.Write(pbKey32, 0, 32);
 | 
			
		||||
 | 
			
		||||
				SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
				pbFinalKey32 = sha256.ComputeHash(ms.ToArray());
 | 
			
		||||
				ms.Close();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			CreateXmlKeyFile(strFilePath, pbFinalKey32);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// ================================================================
 | 
			
		||||
		// XML Key Files
 | 
			
		||||
		// ================================================================
 | 
			
		||||
 | 
			
		||||
		// Sample XML file:
 | 
			
		||||
		// <?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
		// <KeyFile>
 | 
			
		||||
		//     <Meta>
 | 
			
		||||
		//         <Version>1.00</Version>
 | 
			
		||||
		//     </Meta>
 | 
			
		||||
		//     <Key>
 | 
			
		||||
		//         <Data>ySFoKuCcJblw8ie6RkMBdVCnAf4EedSch7ItujK6bmI=</Data>
 | 
			
		||||
		//     </Key>
 | 
			
		||||
		// </KeyFile>
 | 
			
		||||
 | 
			
		||||
		private const string RootElementName = "KeyFile";
 | 
			
		||||
		private const string MetaElementName = "Meta";
 | 
			
		||||
		private const string VersionElementName = "Version";
 | 
			
		||||
		private const string KeyElementName = "Key";
 | 
			
		||||
		private const string KeyDataElementName = "Data";
 | 
			
		||||
 | 
			
		||||
		private static byte[] LoadXmlKeyFile(byte[] pbFileData)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbFileData == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			MemoryStream ms = new MemoryStream(pbFileData, false);
 | 
			
		||||
			byte[] pbKeyData = null;
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				XmlDocument doc = new XmlDocument();
 | 
			
		||||
				doc.Load(ms);
 | 
			
		||||
 | 
			
		||||
				XmlElement el = doc.DocumentElement;
 | 
			
		||||
				if((el == null) || !el.Name.Equals(RootElementName)) return null;
 | 
			
		||||
				if(el.ChildNodes.Count < 2) return null;
 | 
			
		||||
 | 
			
		||||
				foreach(XmlNode xmlChild in el.ChildNodes)
 | 
			
		||||
				{
 | 
			
		||||
					if(xmlChild.Name.Equals(MetaElementName)) { } // Ignore Meta
 | 
			
		||||
					else if(xmlChild.Name == KeyElementName)
 | 
			
		||||
					{
 | 
			
		||||
						foreach(XmlNode xmlKeyChild in xmlChild.ChildNodes)
 | 
			
		||||
						{
 | 
			
		||||
							if(xmlKeyChild.Name == KeyDataElementName)
 | 
			
		||||
							{
 | 
			
		||||
								if(pbKeyData == null)
 | 
			
		||||
									pbKeyData = Convert.FromBase64String(xmlKeyChild.InnerText);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { pbKeyData = null; }
 | 
			
		||||
			finally { ms.Close(); }
 | 
			
		||||
 | 
			
		||||
			return pbKeyData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void CreateXmlKeyFile(string strFile, byte[] pbKeyData)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strFile != null);
 | 
			
		||||
			if(strFile == null) throw new ArgumentNullException("strFile");
 | 
			
		||||
			Debug.Assert(pbKeyData != null);
 | 
			
		||||
			if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");
 | 
			
		||||
 | 
			
		||||
			XmlTextWriter xtw = new XmlTextWriter(strFile, StrUtil.Utf8);
 | 
			
		||||
 | 
			
		||||
			xtw.WriteStartDocument();
 | 
			
		||||
			xtw.WriteWhitespace("\r\n");
 | 
			
		||||
			xtw.WriteStartElement(RootElementName); // KeyFile
 | 
			
		||||
			xtw.WriteWhitespace("\r\n\t");
 | 
			
		||||
 | 
			
		||||
			xtw.WriteStartElement(MetaElementName); // Meta
 | 
			
		||||
			xtw.WriteWhitespace("\r\n\t\t");
 | 
			
		||||
			xtw.WriteStartElement(VersionElementName); // Version
 | 
			
		||||
			xtw.WriteString("1.00");
 | 
			
		||||
			xtw.WriteEndElement(); // End Version
 | 
			
		||||
			xtw.WriteWhitespace("\r\n\t");
 | 
			
		||||
			xtw.WriteEndElement(); // End Meta
 | 
			
		||||
			xtw.WriteWhitespace("\r\n\t");
 | 
			
		||||
 | 
			
		||||
			xtw.WriteStartElement(KeyElementName); // Key
 | 
			
		||||
			xtw.WriteWhitespace("\r\n\t\t");
 | 
			
		||||
 | 
			
		||||
			xtw.WriteStartElement(KeyDataElementName); // Data
 | 
			
		||||
			xtw.WriteString(Convert.ToBase64String(pbKeyData));
 | 
			
		||||
			xtw.WriteEndElement(); // End Data
 | 
			
		||||
			xtw.WriteWhitespace("\r\n\t");
 | 
			
		||||
 | 
			
		||||
			xtw.WriteEndElement(); // End Key
 | 
			
		||||
			xtw.WriteWhitespace("\r\n");
 | 
			
		||||
 | 
			
		||||
			xtw.WriteEndElement(); // RootElementName
 | 
			
		||||
			xtw.WriteWhitespace("\r\n");
 | 
			
		||||
			xtw.WriteEndDocument(); // End KeyFile
 | 
			
		||||
			xtw.Close();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								src/KeePassLib2Android/Keys/KcpPassword.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/KeePassLib2Android/Keys/KcpPassword.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Master password / passphrase as provided by the user.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class KcpPassword : IUserKey
 | 
			
		||||
	{
 | 
			
		||||
		private ProtectedString m_psPassword;
 | 
			
		||||
		private ProtectedBinary m_pbKeyData;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the password as protected string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedString Password
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_psPassword; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get key data. Querying this property is fast (it returns a
 | 
			
		||||
		/// reference to a cached <c>ProtectedBinary</c> object).
 | 
			
		||||
		/// If no key data is available, <c>null</c> is returned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedBinary KeyData
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbKeyData; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KcpPassword(byte[] pbPasswordUtf8)
 | 
			
		||||
		{
 | 
			
		||||
			SetKey(pbPasswordUtf8);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KcpPassword(string strPassword)
 | 
			
		||||
		{
 | 
			
		||||
			SetKey(StrUtil.Utf8.GetBytes(strPassword));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void SetKey(byte[] pbPasswordUtf8)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pbPasswordUtf8 != null);
 | 
			
		||||
			if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			byte[] pbRaw = sha256.ComputeHash(pbPasswordUtf8);
 | 
			
		||||
 | 
			
		||||
			m_psPassword = new ProtectedString(true, pbPasswordUtf8);
 | 
			
		||||
			m_pbKeyData = new ProtectedBinary(true, pbRaw);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// public void Clear()
 | 
			
		||||
		// {
 | 
			
		||||
		//	m_psPassword = null;
 | 
			
		||||
		//	m_pbKeyData = null;
 | 
			
		||||
		// }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										148
									
								
								src/KeePassLib2Android/Keys/KcpUserAccount.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								src/KeePassLib2Android/Keys/KcpUserAccount.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A user key depending on the currently logged on Windows user account.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class KcpUserAccount : IUserKey
 | 
			
		||||
	{
 | 
			
		||||
		private ProtectedBinary m_pbKeyData = null;
 | 
			
		||||
 | 
			
		||||
		// Constant initialization vector (unique for KeePass)
 | 
			
		||||
		private static readonly byte[] m_pbEntropy = new byte[]{
 | 
			
		||||
			0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
 | 
			
		||||
			0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		private const string UserKeyFileName = "ProtectedUserKey.bin";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get key data. Querying this property is fast (it returns a
 | 
			
		||||
		/// reference to a cached <c>ProtectedBinary</c> object).
 | 
			
		||||
		/// If no key data is available, <c>null</c> is returned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedBinary KeyData
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbKeyData; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a user account key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public KcpUserAccount()
 | 
			
		||||
		{
 | 
			
		||||
			// Test if ProtectedData is supported -- throws an exception
 | 
			
		||||
			// when running on an old system (Windows 98 / ME).
 | 
			
		||||
			byte[] pbDummyData = new byte[128];
 | 
			
		||||
			ProtectedData.Protect(pbDummyData, m_pbEntropy,
 | 
			
		||||
				DataProtectionScope.CurrentUser);
 | 
			
		||||
 | 
			
		||||
			byte[] pbKey = LoadUserKey(false);
 | 
			
		||||
			if(pbKey == null) pbKey = CreateUserKey();
 | 
			
		||||
			if(pbKey == null) throw new SecurityException(KLRes.UserAccountKeyError);
 | 
			
		||||
 | 
			
		||||
			m_pbKeyData = new ProtectedBinary(true, pbKey);
 | 
			
		||||
			Array.Clear(pbKey, 0, pbKey.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// public void Clear()
 | 
			
		||||
		// {
 | 
			
		||||
		//	m_pbKeyData = null;
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
		private static string GetUserKeyFilePath(bool bCreate)
 | 
			
		||||
		{
 | 
			
		||||
			string strUserDir = Environment.GetFolderPath(
 | 
			
		||||
				Environment.SpecialFolder.ApplicationData);
 | 
			
		||||
 | 
			
		||||
			strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
 | 
			
		||||
			strUserDir += PwDefs.ShortProductName;
 | 
			
		||||
 | 
			
		||||
			if(bCreate && !Directory.Exists(strUserDir))
 | 
			
		||||
				Directory.CreateDirectory(strUserDir);
 | 
			
		||||
 | 
			
		||||
			strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
 | 
			
		||||
			return strUserDir + UserKeyFileName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static byte[] LoadUserKey(bool bShowWarning)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbKey = null;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				string strFilePath = GetUserKeyFilePath(false);
 | 
			
		||||
				byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
 | 
			
		||||
 | 
			
		||||
				pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
 | 
			
		||||
					DataProtectionScope.CurrentUser);
 | 
			
		||||
 | 
			
		||||
				Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception exLoad)
 | 
			
		||||
			{
 | 
			
		||||
				if(bShowWarning) MessageService.ShowWarning(exLoad);
 | 
			
		||||
 | 
			
		||||
				pbKey = null;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return pbKey;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static byte[] CreateUserKey()
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbKey = null;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				string strFilePath = GetUserKeyFilePath(true);
 | 
			
		||||
 | 
			
		||||
				byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64);
 | 
			
		||||
				byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
 | 
			
		||||
					m_pbEntropy, DataProtectionScope.CurrentUser);
 | 
			
		||||
 | 
			
		||||
				File.WriteAllBytes(strFilePath, pbProtectedKey);
 | 
			
		||||
 | 
			
		||||
				Array.Clear(pbProtectedKey, 0, pbProtectedKey.Length);
 | 
			
		||||
				Array.Clear(pbRandomKey, 0, pbRandomKey.Length);
 | 
			
		||||
 | 
			
		||||
				pbKey = LoadUserKey(true);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { pbKey = null; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return pbKey;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										152
									
								
								src/KeePassLib2Android/Keys/KeyProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								src/KeePassLib2Android/Keys/KeyProvider.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KeyProviderQueryContext
 | 
			
		||||
	{
 | 
			
		||||
		private IOConnectionInfo m_ioInfo;
 | 
			
		||||
		public IOConnectionInfo DatabaseIOInfo
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_ioInfo; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string DatabasePath
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_ioInfo.Path; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bCreatingNewKey;
 | 
			
		||||
		public bool CreatingNewKey
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bCreatingNewKey; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSecDesktop;
 | 
			
		||||
		public bool IsOnSecureDesktop
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSecDesktop; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KeyProviderQueryContext(IOConnectionInfo ioInfo, bool bCreatingNewKey,
 | 
			
		||||
			bool bOnSecDesktop)
 | 
			
		||||
		{
 | 
			
		||||
			if(ioInfo == null) throw new ArgumentNullException("ioInfo");
 | 
			
		||||
 | 
			
		||||
			m_ioInfo = ioInfo.CloneDeep();
 | 
			
		||||
			m_bCreatingNewKey = bCreatingNewKey;
 | 
			
		||||
			m_bSecDesktop = bOnSecDesktop;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public abstract class KeyProvider
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Name of your key provider (should be unique).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public abstract string Name
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Property indicating whether the provider is exclusive.
 | 
			
		||||
		/// If the provider is exclusive, KeePass doesn't allow other
 | 
			
		||||
		/// key sources (master password, Windows user account, ...)
 | 
			
		||||
		/// to be combined with the provider.
 | 
			
		||||
		/// Key providers typically should return <c>false</c>
 | 
			
		||||
		/// (to allow non-exclusive use), i.e. don't override this
 | 
			
		||||
		/// property.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public virtual bool Exclusive
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Property that specifies whether the returned key data
 | 
			
		||||
		/// gets hashed by KeePass first or is written directly to
 | 
			
		||||
		/// the user key data stream.
 | 
			
		||||
		/// Standard key provider plugins should return <c>false</c>
 | 
			
		||||
		/// (i.e. don't overwrite this property). Returning <c>true</c>
 | 
			
		||||
		/// may cause severe security problems and is highly
 | 
			
		||||
		/// discouraged.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public virtual bool DirectKey
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// public virtual PwIcon ImageIndex
 | 
			
		||||
		// {
 | 
			
		||||
		//	get { return PwIcon.UserKey; }
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// This property specifies whether the <c>GetKey</c> method might
 | 
			
		||||
		/// show a form or dialog. If there is any chance that the method shows
 | 
			
		||||
		/// one, this property must return <c>true</c>. Only if it's guaranteed
 | 
			
		||||
		/// that the <c>GetKey</c> method doesn't show any form or dialog, this
 | 
			
		||||
		/// property should return <c>false</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public virtual bool GetKeyMightShowGui
 | 
			
		||||
		{
 | 
			
		||||
			get { return true; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// This property specifies whether the key provider is compatible
 | 
			
		||||
		/// with the secure desktop mode. This almost never is the case,
 | 
			
		||||
		/// so you usually won't override this property.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public virtual bool SecureDesktopCompatible
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public abstract byte[] GetKey(KeyProviderQueryContext ctx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
	public sealed class SampleKeyProvider : KeyProvider
 | 
			
		||||
	{
 | 
			
		||||
		public override string Name
 | 
			
		||||
		{
 | 
			
		||||
			get { return "Built-In Sample Key Provider"; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Do not just copy this to your own key provider class! See above.
 | 
			
		||||
		public override bool GetKeyMightShowGui
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override byte[] GetKey(KeyProviderQueryContext ctx)
 | 
			
		||||
		{
 | 
			
		||||
			return new byte[]{ 2, 3, 5, 7, 11, 13 };
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								src/KeePassLib2Android/Keys/KeyProviderPool.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/KeePassLib2Android/Keys/KeyProviderPool.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KeyProviderPool : IEnumerable<KeyProvider>
 | 
			
		||||
	{
 | 
			
		||||
		private List<KeyProvider> m_vProviders = new List<KeyProvider>();
 | 
			
		||||
 | 
			
		||||
		public int Count
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vProviders.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vProviders.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<KeyProvider> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vProviders.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(KeyProvider prov)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov");
 | 
			
		||||
 | 
			
		||||
			m_vProviders.Add(prov);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Remove(KeyProvider prov)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(prov != null); if(prov == null) throw new ArgumentNullException("prov");
 | 
			
		||||
 | 
			
		||||
			return m_vProviders.Remove(prov);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public KeyProvider Get(string strProviderName)
 | 
			
		||||
		{
 | 
			
		||||
			if(strProviderName == null) throw new ArgumentNullException("strProviderName");
 | 
			
		||||
 | 
			
		||||
			foreach(KeyProvider prov in m_vProviders)
 | 
			
		||||
			{
 | 
			
		||||
				if(prov.Name == strProviderName) return prov;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool IsKeyProvider(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
 | 
			
		||||
 | 
			
		||||
			foreach(KeyProvider prov in m_vProviders)
 | 
			
		||||
			{
 | 
			
		||||
				if(prov.Name == strName) return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal byte[] GetKey(string strProviderName, KeyProviderQueryContext ctx,
 | 
			
		||||
			out bool bPerformHash)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strProviderName != null); if(strProviderName == null) throw new ArgumentNullException("strProviderName");
 | 
			
		||||
 | 
			
		||||
			bPerformHash = true;
 | 
			
		||||
 | 
			
		||||
			foreach(KeyProvider prov in m_vProviders)
 | 
			
		||||
			{
 | 
			
		||||
				if(prov.Name == strProviderName)
 | 
			
		||||
				{
 | 
			
		||||
					bPerformHash = !prov.DirectKey;
 | 
			
		||||
					return prov.GetKey(ctx);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								src/KeePassLib2Android/Keys/KeyValidator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/KeePassLib2Android/Keys/KeyValidator.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	public enum KeyValidationType
 | 
			
		||||
	{
 | 
			
		||||
		MasterPassword = 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public abstract class KeyValidator
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Name of your key validator (should be unique).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public abstract string Name
 | 
			
		||||
		{
 | 
			
		||||
			get;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Validate a key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strKey">Key to validate.</param>
 | 
			
		||||
		/// <param name="t">Type of the validation to perform.</param>
 | 
			
		||||
		/// <returns>Returns <c>null</c>, if the validation is successful.
 | 
			
		||||
		/// If there's a problem with the key, the returned string describes
 | 
			
		||||
		/// the problem.</returns>
 | 
			
		||||
		public abstract string Validate(string strKey, KeyValidationType t);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								src/KeePassLib2Android/Keys/KeyValidatorPool.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/KeePassLib2Android/Keys/KeyValidatorPool.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KeyValidatorPool : IEnumerable<KeyValidator>
 | 
			
		||||
	{
 | 
			
		||||
		private List<KeyValidator> m_vValidators = new List<KeyValidator>();
 | 
			
		||||
 | 
			
		||||
		public int Count
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vValidators.Count; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		IEnumerator IEnumerable.GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vValidators.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public IEnumerator<KeyValidator> GetEnumerator()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vValidators.GetEnumerator();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Add(KeyValidator v)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(v != null); if(v == null) throw new ArgumentNullException("v");
 | 
			
		||||
 | 
			
		||||
			m_vValidators.Add(v);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Remove(KeyValidator v)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(v != null); if(v == null) throw new ArgumentNullException("v");
 | 
			
		||||
 | 
			
		||||
			return m_vValidators.Remove(v);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string Validate(string strKey, KeyValidationType t)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strKey != null); if(strKey == null) throw new ArgumentNullException("strKey");
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValidator v in m_vValidators)
 | 
			
		||||
			{
 | 
			
		||||
				string strResult = v.Validate(strKey, t);
 | 
			
		||||
				if(strResult != null) return strResult;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string Validate(byte[] pbKeyUtf8, KeyValidationType t)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pbKeyUtf8 != null); if(pbKeyUtf8 == null) throw new ArgumentNullException("pbKeyUtf8");
 | 
			
		||||
 | 
			
		||||
			if(m_vValidators.Count == 0) return null;
 | 
			
		||||
 | 
			
		||||
			string strKey = StrUtil.Utf8.GetString(pbKeyUtf8, 0, pbKeyUtf8.Length);
 | 
			
		||||
			return Validate(strKey, t);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								src/KeePassLib2Android/Keys/UserKeyType.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/KeePassLib2Android/Keys/UserKeyType.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Keys
 | 
			
		||||
{
 | 
			
		||||
	[Flags]
 | 
			
		||||
	public enum UserKeyType
 | 
			
		||||
	{
 | 
			
		||||
		None = 0,
 | 
			
		||||
		Other = 1,
 | 
			
		||||
		Password = 2,
 | 
			
		||||
		KeyFile = 4,
 | 
			
		||||
		UserAccount = 8
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										234
									
								
								src/KeePassLib2Android/Native/NativeLib.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								src/KeePassLib2Android/Native/NativeLib.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,234 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Native
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Interface to native library (library containing fast versions of
 | 
			
		||||
	/// several cryptographic functions).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class NativeLib
 | 
			
		||||
	{
 | 
			
		||||
		private static bool m_bAllowNative = true;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// If this property is set to <c>true</c>, the native library is used.
 | 
			
		||||
		/// If it is <c>false</c>, all calls to functions in this class will fail.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static bool AllowNative
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bAllowNative; }
 | 
			
		||||
			set { m_bAllowNative = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Determine if the native library is installed.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Returns <c>true</c>, if the native library is installed.</returns>
 | 
			
		||||
		public static bool IsLibraryInstalled()
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pDummy0 = new byte[32];
 | 
			
		||||
			byte[] pDummy1 = new byte[32];
 | 
			
		||||
 | 
			
		||||
			// Save the native state
 | 
			
		||||
			bool bCachedNativeState = m_bAllowNative;
 | 
			
		||||
 | 
			
		||||
			// Temporarily allow native functions and try to load the library
 | 
			
		||||
			m_bAllowNative = true;
 | 
			
		||||
			bool bResult = TransformKey256(pDummy0, pDummy1, 16);
 | 
			
		||||
 | 
			
		||||
			// Pop native state and return result
 | 
			
		||||
			m_bAllowNative = bCachedNativeState;
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static bool? m_bIsUnix = null;
 | 
			
		||||
		public static bool IsUnix()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bIsUnix.HasValue) return m_bIsUnix.Value;
 | 
			
		||||
 | 
			
		||||
			PlatformID p = GetPlatformID();
 | 
			
		||||
 | 
			
		||||
			// Mono defines Unix as 128 in early .NET versions
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			m_bIsUnix = ((p == PlatformID.Unix) || (p == PlatformID.MacOSX) ||
 | 
			
		||||
				((int)p == 128));
 | 
			
		||||
#else
 | 
			
		||||
			m_bIsUnix = (((int)p == 4) || ((int)p == 6) || ((int)p == 128));
 | 
			
		||||
#endif
 | 
			
		||||
			return m_bIsUnix.Value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static PlatformID? m_platID = null;
 | 
			
		||||
		public static PlatformID GetPlatformID()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_platID.HasValue) return m_platID.Value;
 | 
			
		||||
 | 
			
		||||
			m_platID = Environment.OSVersion.Platform;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			// Mono returns PlatformID.Unix on Mac OS X, workaround this
 | 
			
		||||
			if(m_platID.Value == PlatformID.Unix)
 | 
			
		||||
			{
 | 
			
		||||
				if((RunConsoleApp("uname", null) ?? string.Empty).Trim().Equals(
 | 
			
		||||
					"Darwin", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
					m_platID = PlatformID.MacOSX;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return m_platID.Value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		public static string RunConsoleApp(string strAppPath, string strParams)
 | 
			
		||||
		{
 | 
			
		||||
			return RunConsoleApp(strAppPath, strParams, null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string RunConsoleApp(string strAppPath, string strParams,
 | 
			
		||||
			string strStdInput)
 | 
			
		||||
		{
 | 
			
		||||
			if(strAppPath == null) throw new ArgumentNullException("strAppPath");
 | 
			
		||||
			if(strAppPath.Length == 0) throw new ArgumentException("strAppPath");
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				ProcessStartInfo psi = new ProcessStartInfo();
 | 
			
		||||
 | 
			
		||||
				psi.CreateNoWindow = true;
 | 
			
		||||
				psi.FileName = strAppPath;
 | 
			
		||||
				psi.WindowStyle = ProcessWindowStyle.Hidden;
 | 
			
		||||
				psi.UseShellExecute = false;
 | 
			
		||||
				psi.RedirectStandardOutput = true;
 | 
			
		||||
 | 
			
		||||
				if(strStdInput != null) psi.RedirectStandardInput = true;
 | 
			
		||||
 | 
			
		||||
				if(!string.IsNullOrEmpty(strParams)) psi.Arguments = strParams;
 | 
			
		||||
 | 
			
		||||
				Process p = Process.Start(psi);
 | 
			
		||||
 | 
			
		||||
				if(strStdInput != null)
 | 
			
		||||
				{
 | 
			
		||||
					p.StandardInput.Write(strStdInput);
 | 
			
		||||
					p.StandardInput.Close();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				string strOutput = p.StandardOutput.ReadToEnd();
 | 
			
		||||
				p.WaitForExit();
 | 
			
		||||
 | 
			
		||||
				return strOutput;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Transform a key.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pBuf256">Source and destination buffer.</param>
 | 
			
		||||
		/// <param name="pKey256">Key to use in the transformation.</param>
 | 
			
		||||
		/// <param name="uRounds">Number of transformation rounds.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c>, if the key was transformed successfully.</returns>
 | 
			
		||||
		public static bool TransformKey256(byte[] pBuf256, byte[] pKey256,
 | 
			
		||||
			ulong uRounds)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bAllowNative == false) return false;
 | 
			
		||||
 | 
			
		||||
			KeyValuePair<IntPtr, IntPtr> kvp = PrepareArrays256(pBuf256, pKey256);
 | 
			
		||||
			bool bResult = false;
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				bResult = NativeMethods.TransformKey(kvp.Key, kvp.Value, uRounds);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { bResult = false; }
 | 
			
		||||
 | 
			
		||||
			if(bResult) GetBuffers256(kvp, pBuf256, pKey256);
 | 
			
		||||
 | 
			
		||||
			NativeLib.FreeArrays(kvp);
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Benchmark key transformation.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uTimeMs">Number of seconds to perform the benchmark.</param>
 | 
			
		||||
		/// <param name="puRounds">Number of transformations done.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c>, if the benchmark was successful.</returns>
 | 
			
		||||
		public static bool TransformKeyBenchmark256(uint uTimeMs, out ulong puRounds)
 | 
			
		||||
		{
 | 
			
		||||
			puRounds = 0;
 | 
			
		||||
 | 
			
		||||
			if(m_bAllowNative == false) return false;
 | 
			
		||||
 | 
			
		||||
			try { puRounds = NativeMethods.TransformKeyBenchmark(uTimeMs); }
 | 
			
		||||
			catch(Exception) { return false; }
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static KeyValuePair<IntPtr, IntPtr> PrepareArrays256(byte[] pBuf256,
 | 
			
		||||
			byte[] pKey256)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((pBuf256 != null) && (pBuf256.Length == 32));
 | 
			
		||||
			if(pBuf256 == null) throw new ArgumentNullException("pBuf256");
 | 
			
		||||
			if(pBuf256.Length != 32) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert((pKey256 != null) && (pKey256.Length == 32));
 | 
			
		||||
			if(pKey256 == null) throw new ArgumentNullException("pKey256");
 | 
			
		||||
			if(pKey256.Length != 32) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			IntPtr hBuf = Marshal.AllocHGlobal(pBuf256.Length);
 | 
			
		||||
			Marshal.Copy(pBuf256, 0, hBuf, pBuf256.Length);
 | 
			
		||||
 | 
			
		||||
			IntPtr hKey = Marshal.AllocHGlobal(pKey256.Length);
 | 
			
		||||
			Marshal.Copy(pKey256, 0, hKey, pKey256.Length);
 | 
			
		||||
 | 
			
		||||
			return new KeyValuePair<IntPtr, IntPtr>(hBuf, hKey);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void GetBuffers256(KeyValuePair<IntPtr, IntPtr> kvpSource,
 | 
			
		||||
			byte[] pbDestBuf, byte[] pbDestKey)
 | 
			
		||||
		{
 | 
			
		||||
			if(kvpSource.Key != IntPtr.Zero)
 | 
			
		||||
				Marshal.Copy(kvpSource.Key, pbDestBuf, 0, pbDestBuf.Length);
 | 
			
		||||
 | 
			
		||||
			if(kvpSource.Value != IntPtr.Zero)
 | 
			
		||||
				Marshal.Copy(kvpSource.Value, pbDestKey, 0, pbDestKey.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void FreeArrays(KeyValuePair<IntPtr, IntPtr> kvpPointers)
 | 
			
		||||
		{
 | 
			
		||||
			if(kvpPointers.Key != IntPtr.Zero)
 | 
			
		||||
				Marshal.FreeHGlobal(kvpPointers.Key);
 | 
			
		||||
 | 
			
		||||
			if(kvpPointers.Value != IntPtr.Zero)
 | 
			
		||||
				Marshal.FreeHGlobal(kvpPointers.Value);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										179
									
								
								src/KeePassLib2Android/Native/NativeMethods.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								src/KeePassLib2Android/Native/NativeMethods.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Native
 | 
			
		||||
{
 | 
			
		||||
	internal static class NativeMethods
 | 
			
		||||
	{
 | 
			
		||||
		internal const int MAX_PATH = 260;
 | 
			
		||||
 | 
			
		||||
		/* [DllImport("KeePassNtv32.dll", EntryPoint = "TransformKey")]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		private static extern bool TransformKey32(IntPtr pBuf256,
 | 
			
		||||
			IntPtr pKey256, UInt64 uRounds);
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassNtv64.dll", EntryPoint = "TransformKey")]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		private static extern bool TransformKey64(IntPtr pBuf256,
 | 
			
		||||
			IntPtr pKey256, UInt64 uRounds);
 | 
			
		||||
 | 
			
		||||
		internal static bool TransformKey(IntPtr pBuf256, IntPtr pKey256,
 | 
			
		||||
			UInt64 uRounds)
 | 
			
		||||
		{
 | 
			
		||||
			if(Marshal.SizeOf(typeof(IntPtr)) == 8)
 | 
			
		||||
				return TransformKey64(pBuf256, pKey256, uRounds);
 | 
			
		||||
			else
 | 
			
		||||
				return TransformKey32(pBuf256, pKey256, uRounds);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassNtv32.dll", EntryPoint = "TransformKeyTimed")]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		private static extern bool TransformKeyTimed32(IntPtr pBuf256,
 | 
			
		||||
			IntPtr pKey256, ref UInt64 puRounds, UInt32 uSeconds);
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassNtv64.dll", EntryPoint = "TransformKeyTimed")]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		private static extern bool TransformKeyTimed64(IntPtr pBuf256,
 | 
			
		||||
			IntPtr pKey256, ref UInt64 puRounds, UInt32 uSeconds);
 | 
			
		||||
 | 
			
		||||
		internal static bool TransformKeyTimed(IntPtr pBuf256, IntPtr pKey256,
 | 
			
		||||
			ref UInt64 puRounds, UInt32 uSeconds)
 | 
			
		||||
		{
 | 
			
		||||
			if(Marshal.SizeOf(typeof(IntPtr)) == 8)
 | 
			
		||||
				return TransformKeyTimed64(pBuf256, pKey256, ref puRounds, uSeconds);
 | 
			
		||||
			else
 | 
			
		||||
				return TransformKeyTimed32(pBuf256, pKey256, ref puRounds, uSeconds);
 | 
			
		||||
		} */
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassLibC32.dll", EntryPoint = "TransformKey256")]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		private static extern bool TransformKey32(IntPtr pBuf256,
 | 
			
		||||
			IntPtr pKey256, UInt64 uRounds);
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassLibC64.dll", EntryPoint = "TransformKey256")]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		private static extern bool TransformKey64(IntPtr pBuf256,
 | 
			
		||||
			IntPtr pKey256, UInt64 uRounds);
 | 
			
		||||
 | 
			
		||||
		internal static bool TransformKey(IntPtr pBuf256, IntPtr pKey256,
 | 
			
		||||
			UInt64 uRounds)
 | 
			
		||||
		{
 | 
			
		||||
			if(Marshal.SizeOf(typeof(IntPtr)) == 8)
 | 
			
		||||
				return TransformKey64(pBuf256, pKey256, uRounds);
 | 
			
		||||
			else
 | 
			
		||||
				return TransformKey32(pBuf256, pKey256, uRounds);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassLibC32.dll", EntryPoint = "TransformKeyBenchmark256")]
 | 
			
		||||
		private static extern UInt64 TransformKeyBenchmark32(UInt32 uTimeMs);
 | 
			
		||||
 | 
			
		||||
		[DllImport("KeePassLibC64.dll", EntryPoint = "TransformKeyBenchmark256")]
 | 
			
		||||
		private static extern UInt64 TransformKeyBenchmark64(UInt32 uTimeMs);
 | 
			
		||||
 | 
			
		||||
		internal static UInt64 TransformKeyBenchmark(UInt32 uTimeMs)
 | 
			
		||||
		{
 | 
			
		||||
			if(Marshal.SizeOf(typeof(IntPtr)) == 8)
 | 
			
		||||
				return TransformKeyBenchmark64(uTimeMs);
 | 
			
		||||
			else
 | 
			
		||||
				return TransformKeyBenchmark32(uTimeMs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		[DllImport("ShlWApi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
 | 
			
		||||
		internal static extern int StrCmpLogicalW(string x, string y);
 | 
			
		||||
 | 
			
		||||
		[DllImport("ShlWApi.dll", CharSet = CharSet.Auto)]
 | 
			
		||||
		[return: MarshalAs(UnmanagedType.Bool)]
 | 
			
		||||
		internal static extern bool PathRelativePathTo([Out] StringBuilder pszPath,
 | 
			
		||||
			[In] string pszFrom, [In] uint dwAttrFrom, [In] string pszTo,
 | 
			
		||||
			[In] uint dwAttrTo);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		private static bool? m_bSupportsLogicalCmp = null;
 | 
			
		||||
 | 
			
		||||
		private static void TestNaturalComparisonsSupport()
 | 
			
		||||
		{
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
#warning No native natural comparisons supported.
 | 
			
		||||
			m_bSupportsLogicalCmp = false;
 | 
			
		||||
#else
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				StrCmpLogicalW("0", "0"); // Throws exception if unsupported
 | 
			
		||||
				m_bSupportsLogicalCmp = true;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { m_bSupportsLogicalCmp = false; }
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static bool SupportsStrCmpNaturally
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if(m_bSupportsLogicalCmp.HasValue == false)
 | 
			
		||||
					TestNaturalComparisonsSupport();
 | 
			
		||||
 | 
			
		||||
				return m_bSupportsLogicalCmp.Value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static int StrCmpNaturally(string x, string y)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bSupportsLogicalCmp.HasValue == false) TestNaturalComparisonsSupport();
 | 
			
		||||
			if(m_bSupportsLogicalCmp.Value == false) return 0;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
#warning No native natural comparisons supported.
 | 
			
		||||
			return x.CompareTo(y);
 | 
			
		||||
#else
 | 
			
		||||
			return StrCmpLogicalW(x, y);
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static string GetUserRuntimeDir()
 | 
			
		||||
		{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			string strRtDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
 | 
			
		||||
			if(string.IsNullOrEmpty(strRtDir))
 | 
			
		||||
				strRtDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
 | 
			
		||||
			if(string.IsNullOrEmpty(strRtDir))
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				return Path.GetTempPath(); // Not UrlUtil (otherwise cyclic)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			strRtDir = UrlUtil.EnsureTerminatingSeparator(strRtDir, false);
 | 
			
		||||
			strRtDir += PwDefs.ShortProductName;
 | 
			
		||||
 | 
			
		||||
			return strRtDir;
 | 
			
		||||
#else
 | 
			
		||||
			return Path.GetTempPath();
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/KeePassLib2Android/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/KeePassLib2Android/Properties/AssemblyInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using System.Runtime.CompilerServices;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
 | 
			
		||||
// General assembly properties
 | 
			
		||||
[assembly: AssemblyTitle("KeePassLib")]
 | 
			
		||||
[assembly: AssemblyDescription("KeePass Password Management Library")]
 | 
			
		||||
[assembly: AssemblyConfiguration("")]
 | 
			
		||||
[assembly: AssemblyCompany("Dominik Reichl")]
 | 
			
		||||
[assembly: AssemblyProduct("KeePassLib")]
 | 
			
		||||
[assembly: AssemblyCopyright("Copyright © 2003-2012 Dominik Reichl")]
 | 
			
		||||
[assembly: AssemblyTrademark("")]
 | 
			
		||||
[assembly: AssemblyCulture("")]
 | 
			
		||||
 | 
			
		||||
// COM settings
 | 
			
		||||
[assembly: ComVisible(false)]
 | 
			
		||||
 | 
			
		||||
// Assembly GUID
 | 
			
		||||
[assembly: Guid("395f6eec-a1e0-4438-aa82-b75099348134")]
 | 
			
		||||
 | 
			
		||||
// Assembly version information
 | 
			
		||||
[assembly: AssemblyVersion("2.20.1.*")]
 | 
			
		||||
[assembly: AssemblyFileVersion("2.20.1.0")]
 | 
			
		||||
							
								
								
									
										76
									
								
								src/KeePassLib2Android/PwCustomIcon.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/KeePassLib2Android/PwCustomIcon.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Custom icon. <c>PwCustomIcon</c> objects are immutable.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class PwCustomIcon
 | 
			
		||||
	{
 | 
			
		||||
		private PwUuid m_pwUuid;
 | 
			
		||||
		private byte[] m_pbImageDataPng;
 | 
			
		||||
		private Image m_pCachedImage;
 | 
			
		||||
 | 
			
		||||
		public PwUuid Uuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pwUuid; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public byte[] ImageDataPng
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbImageDataPng; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Image Image
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pCachedImage; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwCustomIcon(PwUuid pwUuid, byte[] pbImageDataPng)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwUuid != null);
 | 
			
		||||
			if(pwUuid == null) throw new ArgumentNullException("pwUuid");
 | 
			
		||||
			Debug.Assert(pwUuid != PwUuid.Zero);
 | 
			
		||||
			if(pwUuid == PwUuid.Zero) throw new ArgumentException("pwUuid == 0");
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pbImageDataPng != null);
 | 
			
		||||
			if(pbImageDataPng == null) throw new ArgumentNullException("pbImageDataPng");
 | 
			
		||||
 | 
			
		||||
			m_pwUuid = pwUuid;
 | 
			
		||||
			m_pbImageDataPng = pbImageDataPng;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			// MemoryStream ms = new MemoryStream(m_pbImageDataPng, false);
 | 
			
		||||
			// m_pCachedImage = Image.FromStream(ms);
 | 
			
		||||
			// ms.Close();
 | 
			
		||||
			m_pCachedImage = GfxUtil.LoadImage(m_pbImageDataPng);
 | 
			
		||||
#else
 | 
			
		||||
			m_pCachedImage = null;
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1759
									
								
								src/KeePassLib2Android/PwDatabase.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1759
									
								
								src/KeePassLib2Android/PwDatabase.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										461
									
								
								src/KeePassLib2Android/PwDefs.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										461
									
								
								src/KeePassLib2Android/PwDefs.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,461 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Delegates;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Contains KeePassLib-global definitions and enums.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class PwDefs
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The product name.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string ProductName = "KeePass Password Safe";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A short, simple string representing the product name. The string
 | 
			
		||||
		/// should contain no spaces, directory separator characters, etc.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string ShortProductName = "KeePass";
 | 
			
		||||
 | 
			
		||||
		internal const string UnixName = "keepass2";
 | 
			
		||||
		internal const string ResClass = "KeePass2"; // With initial capital
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Version, encoded as 32-bit unsigned integer.
 | 
			
		||||
		/// 2.00 = 0x02000000, 2.01 = 0x02000100, ..., 2.18 = 0x02010800.
 | 
			
		||||
		/// As of 2.19, the version is encoded component-wise per byte,
 | 
			
		||||
		/// e.g. 2.19 = 0x02130000.
 | 
			
		||||
		/// It is highly recommended to use <c>FileVersion64</c> instead.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const uint Version32 = 0x02140100;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Version, encoded as 64-bit unsigned integer
 | 
			
		||||
		/// (component-wise, 16 bits per component).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const ulong FileVersion64 = 0x0002001400010000UL;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Version, encoded as string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string VersionString = "2.20.1";
 | 
			
		||||
 | 
			
		||||
		public const string Copyright = @"Copyright <20> 2003-2012 Dominik Reichl";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Product website URL. Terminated by a forward slash.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string HomepageUrl = "http://keepass.info/";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Product donations URL.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string DonationsUrl = "http://keepass.info/donate.html";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// URL to the online plugins page.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string PluginsUrl = "http://keepass.info/plugins.html";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// URL to the online translations page.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string TranslationsUrl = "http://keepass.info/translations.html";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// URL to a TXT file (eventually compressed) that contains information
 | 
			
		||||
		/// about the latest KeePass version available on the website.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string VersionUrl = "http://keepass.info/update/version2x.txt.gz";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// URL to the root path of the online KeePass help. Terminated by
 | 
			
		||||
		/// a forward slash.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string HelpUrl = "http://keepass.info/help/";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A <c>DateTime</c> object that represents the time when the assembly
 | 
			
		||||
		/// was loaded.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static readonly DateTime DtDefaultNow = DateTime.Now;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default number of master key encryption/transformation rounds (making dictionary attacks harder).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const ulong DefaultKeyEncryptionRounds = 6000;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default identifier string for the title field. Should not contain
 | 
			
		||||
		/// spaces, tabs or other whitespace.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string TitleField = "Title";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default identifier string for the user name field. Should not contain
 | 
			
		||||
		/// spaces, tabs or other whitespace.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string UserNameField = "UserName";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default identifier string for the password field. Should not contain
 | 
			
		||||
		/// spaces, tabs or other whitespace.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string PasswordField = "Password";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default identifier string for the URL field. Should not contain
 | 
			
		||||
		/// spaces, tabs or other whitespace.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string UrlField = "URL";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default identifier string for the notes field. Should not contain
 | 
			
		||||
		/// spaces, tabs or other whitespace.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string NotesField = "Notes";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default identifier string for the field which will contain TAN indices.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string TanIndexField = UserNameField;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default title of an entry that is really a TAN entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string TanTitle = @"<TAN>";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Prefix of a custom auto-type string field.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string AutoTypeStringPrefix = "S:";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default string representing a hidden password.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string HiddenPassword = "********";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default auto-type keystroke sequence. If no custom sequence is
 | 
			
		||||
		/// specified, this sequence is used.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string DefaultAutoTypeSequence = @"{USERNAME}{TAB}{PASSWORD}{ENTER}";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default auto-type keystroke sequence for TAN entries. If no custom
 | 
			
		||||
		/// sequence is specified, this sequence is used.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const string DefaultAutoTypeSequenceTan = @"{PASSWORD}";
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Check if a name is a standard field name.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strFieldName">Input field name.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c>, if the field name is a standard
 | 
			
		||||
		/// field name (title, user name, password, ...), otherwise <c>false</c>.</returns>
 | 
			
		||||
		public static bool IsStandardField(string strFieldName)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strFieldName != null); if(strFieldName == null) return false;
 | 
			
		||||
 | 
			
		||||
			if(strFieldName.Equals(TitleField)) return true;
 | 
			
		||||
			if(strFieldName.Equals(UserNameField)) return true;
 | 
			
		||||
			if(strFieldName.Equals(PasswordField)) return true;
 | 
			
		||||
			if(strFieldName.Equals(UrlField)) return true;
 | 
			
		||||
			if(strFieldName.Equals(NotesField)) return true;
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static List<string> GetStandardFields()
 | 
			
		||||
		{
 | 
			
		||||
			List<string> l = new List<string>();
 | 
			
		||||
 | 
			
		||||
			l.Add(TitleField);
 | 
			
		||||
			l.Add(UserNameField);
 | 
			
		||||
			l.Add(PasswordField);
 | 
			
		||||
			l.Add(UrlField);
 | 
			
		||||
			l.Add(NotesField);
 | 
			
		||||
 | 
			
		||||
			return l;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Check if an entry is a TAN.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pe">Password entry.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the entry is a TAN.</returns>
 | 
			
		||||
		public static bool IsTanEntry(PwEntry pe)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pe != null); if(pe == null) return false;
 | 
			
		||||
 | 
			
		||||
			return (pe.Strings.ReadSafe(PwDefs.TitleField) == TanTitle);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#pragma warning disable 1591 // Missing XML comments warning
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Search parameters for group and entry searches.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class SearchParameters
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strText = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string SearchString
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strText; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strText = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bRegex = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool RegularExpression
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bRegex; }
 | 
			
		||||
			set { m_bRegex = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInTitles = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool SearchInTitles
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInTitles; }
 | 
			
		||||
			set { m_bSearchInTitles = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInUserNames = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool SearchInUserNames
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInUserNames; }
 | 
			
		||||
			set { m_bSearchInUserNames = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInPasswords = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool SearchInPasswords
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInPasswords; }
 | 
			
		||||
			set { m_bSearchInPasswords = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInUrls = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool SearchInUrls
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInUrls; }
 | 
			
		||||
			set { m_bSearchInUrls = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInNotes = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool SearchInNotes
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInNotes; }
 | 
			
		||||
			set { m_bSearchInNotes = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInOther = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool SearchInOther
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInOther; }
 | 
			
		||||
			set { m_bSearchInOther = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInUuids = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool SearchInUuids
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInUuids; }
 | 
			
		||||
			set { m_bSearchInUuids = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInGroupNames = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool SearchInGroupNames
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInGroupNames; }
 | 
			
		||||
			set { m_bSearchInGroupNames = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bSearchInTags = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool SearchInTags
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bSearchInTags; }
 | 
			
		||||
			set { m_bSearchInTags = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private StringComparison m_scType = StringComparison.InvariantCultureIgnoreCase;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// String comparison type. Specifies the condition when the specified
 | 
			
		||||
		/// text matches a group/entry string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public StringComparison ComparisonMode
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_scType; }
 | 
			
		||||
			set { m_scType = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bExcludeExpired = false;
 | 
			
		||||
		[DefaultValue(false)]
 | 
			
		||||
		public bool ExcludeExpired
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bExcludeExpired; }
 | 
			
		||||
			set { m_bExcludeExpired = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bRespectEntrySearchingDisabled = true;
 | 
			
		||||
		[DefaultValue(true)]
 | 
			
		||||
		public bool RespectEntrySearchingDisabled
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bRespectEntrySearchingDisabled; }
 | 
			
		||||
			set { m_bRespectEntrySearchingDisabled = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private StrPwEntryDelegate m_fnDataTrf = null;
 | 
			
		||||
		[XmlIgnore]
 | 
			
		||||
		public StrPwEntryDelegate DataTransformationFn
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_fnDataTrf; }
 | 
			
		||||
			set { m_fnDataTrf = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strDataTrf = string.Empty;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Only for serialization.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string DataTransformation
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strDataTrf; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strDataTrf = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[XmlIgnore]
 | 
			
		||||
		public static SearchParameters None
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				SearchParameters sp = new SearchParameters();
 | 
			
		||||
 | 
			
		||||
				// sp.m_strText = string.Empty;
 | 
			
		||||
				// sp.m_bRegex = false;
 | 
			
		||||
				sp.m_bSearchInTitles = false;
 | 
			
		||||
				sp.m_bSearchInUserNames = false;
 | 
			
		||||
				// sp.m_bSearchInPasswords = false;
 | 
			
		||||
				sp.m_bSearchInUrls = false;
 | 
			
		||||
				sp.m_bSearchInNotes = false;
 | 
			
		||||
				sp.m_bSearchInOther = false;
 | 
			
		||||
				// sp.m_bSearchInUuids = false;
 | 
			
		||||
				// sp.SearchInGroupNames = false;
 | 
			
		||||
				sp.m_bSearchInTags = false;
 | 
			
		||||
				// sp.m_scType = StringComparison.InvariantCultureIgnoreCase;
 | 
			
		||||
				// sp.m_bExcludeExpired = false;
 | 
			
		||||
				// m_bRespectEntrySearchingDisabled = true;
 | 
			
		||||
 | 
			
		||||
				return sp;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new search parameters object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public SearchParameters()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public SearchParameters Clone()
 | 
			
		||||
		{
 | 
			
		||||
			return (SearchParameters)this.MemberwiseClone();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	#pragma warning restore 1591 // Missing XML comments warning
 | 
			
		||||
 | 
			
		||||
	#pragma warning disable 1591 // Missing XML comments warning
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Memory protection configuration structure (for default fields).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class MemoryProtectionConfig : IDeepCloneable<MemoryProtectionConfig>
 | 
			
		||||
	{
 | 
			
		||||
		public bool ProtectTitle = false;
 | 
			
		||||
		public bool ProtectUserName = false;
 | 
			
		||||
		public bool ProtectPassword = true;
 | 
			
		||||
		public bool ProtectUrl = false;
 | 
			
		||||
		public bool ProtectNotes = false;
 | 
			
		||||
 | 
			
		||||
		// public bool AutoEnableVisualHiding = false;
 | 
			
		||||
 | 
			
		||||
		public MemoryProtectionConfig CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			return (MemoryProtectionConfig)this.MemberwiseClone();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool GetProtection(string strField)
 | 
			
		||||
		{
 | 
			
		||||
			if(strField == PwDefs.TitleField) return this.ProtectTitle;
 | 
			
		||||
			if(strField == PwDefs.UserNameField) return this.ProtectUserName;
 | 
			
		||||
			if(strField == PwDefs.PasswordField) return this.ProtectPassword;
 | 
			
		||||
			if(strField == PwDefs.UrlField) return this.ProtectUrl;
 | 
			
		||||
			if(strField == PwDefs.NotesField) return this.ProtectNotes;
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	#pragma warning restore 1591 // Missing XML comments warning
 | 
			
		||||
 | 
			
		||||
	public sealed class ObjectTouchedEventArgs : EventArgs
 | 
			
		||||
	{
 | 
			
		||||
		private object m_o;
 | 
			
		||||
		public object Object { get { return m_o; } }
 | 
			
		||||
 | 
			
		||||
		private bool m_bModified;
 | 
			
		||||
		public bool Modified { get { return m_bModified; } }
 | 
			
		||||
 | 
			
		||||
		private bool m_bParentsTouched;
 | 
			
		||||
		public bool ParentsTouched { get { return m_bParentsTouched; } }
 | 
			
		||||
 | 
			
		||||
		public ObjectTouchedEventArgs(object o, bool bModified,
 | 
			
		||||
			bool bParentsTouched)
 | 
			
		||||
		{
 | 
			
		||||
			m_o = o;
 | 
			
		||||
			m_bModified = bModified;
 | 
			
		||||
			m_bParentsTouched = bParentsTouched;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								src/KeePassLib2Android/PwDeletedObject.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/KeePassLib2Android/PwDeletedObject.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Represents an object that has been deleted.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class PwDeletedObject : IDeepCloneable<PwDeletedObject>
 | 
			
		||||
	{
 | 
			
		||||
		private PwUuid m_uuid = PwUuid.Zero;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// UUID of the entry that has been deleted.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwUuid Uuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_uuid; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_uuid = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private DateTime m_dtDeletionTime = PwDefs.DtDefaultNow;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the entry has been deleted.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public DateTime DeletionTime
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_dtDeletionTime; }
 | 
			
		||||
			set { m_dtDeletionTime = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new <c>PwDeletedObject</c> object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwDeletedObject()
 | 
			
		||||
		{
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwDeletedObject(PwUuid uuid, DateTime dtDeletionTime)
 | 
			
		||||
		{
 | 
			
		||||
			if(uuid == null) throw new ArgumentNullException("uuid");
 | 
			
		||||
 | 
			
		||||
			m_uuid = uuid;
 | 
			
		||||
			m_dtDeletionTime = dtDeletionTime;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Clone the object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Value copy of the current object.</returns>
 | 
			
		||||
		public PwDeletedObject CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			PwDeletedObject pdo = new PwDeletedObject();
 | 
			
		||||
 | 
			
		||||
			pdo.m_uuid = m_uuid; // PwUuid objects are immutable
 | 
			
		||||
			pdo.m_dtDeletionTime = m_dtDeletionTime;
 | 
			
		||||
 | 
			
		||||
			return pdo;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										874
									
								
								src/KeePassLib2Android/PwEntry.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										874
									
								
								src/KeePassLib2Android/PwEntry.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,874 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Collections;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A class representing a password entry. A password entry consists of several
 | 
			
		||||
	/// fields like title, user name, password, etc. Each password entry has a
 | 
			
		||||
	/// unique ID (UUID).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class PwEntry : ITimeLogger, IStructureItem, IDeepCloneable<PwEntry>
 | 
			
		||||
	{
 | 
			
		||||
		private PwUuid m_uuid = PwUuid.Zero;
 | 
			
		||||
		private PwGroup m_pParentGroup = null;
 | 
			
		||||
		private DateTime m_tParentGroupLastMod = PwDefs.DtDefaultNow;
 | 
			
		||||
 | 
			
		||||
		private ProtectedStringDictionary m_listStrings = new ProtectedStringDictionary();
 | 
			
		||||
		private ProtectedBinaryDictionary m_listBinaries = new ProtectedBinaryDictionary();
 | 
			
		||||
		private AutoTypeConfig m_listAutoType = new AutoTypeConfig();
 | 
			
		||||
		private PwObjectList<PwEntry> m_listHistory = new PwObjectList<PwEntry>();
 | 
			
		||||
 | 
			
		||||
		private PwIcon m_pwIcon = PwIcon.Key;
 | 
			
		||||
		private PwUuid m_pwCustomIconID = PwUuid.Zero;
 | 
			
		||||
 | 
			
		||||
		private Color m_clrForeground = Color.Empty;
 | 
			
		||||
		private Color m_clrBackground = Color.Empty;
 | 
			
		||||
 | 
			
		||||
		private DateTime m_tCreation = PwDefs.DtDefaultNow;
 | 
			
		||||
		private DateTime m_tLastMod = PwDefs.DtDefaultNow;
 | 
			
		||||
		private DateTime m_tLastAccess = PwDefs.DtDefaultNow;
 | 
			
		||||
		private DateTime m_tExpire = PwDefs.DtDefaultNow;
 | 
			
		||||
		private bool m_bExpires = false;
 | 
			
		||||
		private ulong m_uUsageCount = 0;
 | 
			
		||||
 | 
			
		||||
		private string m_strOverrideUrl = string.Empty;
 | 
			
		||||
 | 
			
		||||
		private List<string> m_vTags = new List<string>();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// UUID of this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwUuid Uuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_uuid; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_uuid = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Reference to a group which contains the current entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwGroup ParentGroup
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pParentGroup; }
 | 
			
		||||
 | 
			
		||||
			/// Plugins: use <c>PwGroup.AddEntry</c> instead.
 | 
			
		||||
			internal set { m_pParentGroup = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when the location of the object was last changed.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public DateTime LocationChanged
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_tParentGroupLastMod; }
 | 
			
		||||
			set { m_tParentGroupLastMod = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set all entry strings.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedStringDictionary Strings
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_listStrings; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_listStrings = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set all entry binaries.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedBinaryDictionary Binaries
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_listBinaries; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_listBinaries = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set all auto-type window/keystroke sequence associations.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public AutoTypeConfig AutoType
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_listAutoType; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_listAutoType = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get all previous versions of this entry (backups).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwObjectList<PwEntry> History
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_listHistory; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_listHistory = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Image ID specifying the icon that will be used for this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwIcon IconId
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pwIcon; }
 | 
			
		||||
			set { m_pwIcon = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the custom icon ID. This value is 0, if no custom icon is
 | 
			
		||||
		/// being used (i.e. the icon specified by the <c>IconID</c> property
 | 
			
		||||
		/// should be displayed).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public PwUuid CustomIconUuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pwCustomIconID; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_pwCustomIconID = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set the foreground color of this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public Color ForegroundColor
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_clrForeground; }
 | 
			
		||||
			set { m_clrForeground = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set the background color of this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public Color BackgroundColor
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_clrBackground; }
 | 
			
		||||
			set { m_clrBackground = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when this entry was created.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public DateTime CreationTime
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_tCreation; }
 | 
			
		||||
			set { m_tCreation = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when this entry was last accessed (read).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public DateTime LastAccessTime
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_tLastAccess; }
 | 
			
		||||
			set { m_tLastAccess = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when this entry was last modified.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public DateTime LastModificationTime
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_tLastMod; }
 | 
			
		||||
			set { m_tLastMod = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The date/time when this entry expires. Use the <c>Expires</c> property
 | 
			
		||||
		/// to specify if the entry does actually expire or not.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public DateTime ExpiryTime
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_tExpire; }
 | 
			
		||||
			set { m_tExpire = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Specifies whether the entry expires or not.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool Expires
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bExpires; }
 | 
			
		||||
			set { m_bExpires = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get or set the usage count of the entry. To increase the usage
 | 
			
		||||
		/// count by one, use the <c>Touch</c> function.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ulong UsageCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_uUsageCount; }
 | 
			
		||||
			set { m_uUsageCount = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Entry-specific override URL. If this string is non-empty,
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string OverrideUrl
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strOverrideUrl; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strOverrideUrl = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// List of tags associated with this entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public List<string> Tags
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vTags; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_vTags = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static EventHandler<ObjectTouchedEventArgs> EntryTouched;
 | 
			
		||||
		public EventHandler<ObjectTouchedEventArgs> Touched;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new, empty password entry. Member variables will be initialized
 | 
			
		||||
		/// to their default values.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bCreateNewUuid">If <c>true</c>, a new UUID will be created
 | 
			
		||||
		/// for this entry. If <c>false</c>, the UUID is zero and you must set it
 | 
			
		||||
		/// manually later.</param>
 | 
			
		||||
		/// <param name="bSetTimes">If <c>true</c>, the creation, last modification
 | 
			
		||||
		/// and last access times will be set to the current system time.</param>
 | 
			
		||||
		public PwEntry(bool bCreateNewUuid, bool bSetTimes)
 | 
			
		||||
		{
 | 
			
		||||
			if(bCreateNewUuid) m_uuid = new PwUuid(true);
 | 
			
		||||
 | 
			
		||||
			if(bSetTimes)
 | 
			
		||||
			{
 | 
			
		||||
				m_tCreation = m_tLastMod = m_tLastAccess =
 | 
			
		||||
					m_tParentGroupLastMod = DateTime.Now;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new, empty password entry. Member variables will be initialized
 | 
			
		||||
		/// to their default values.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pwParentGroup">Reference to the containing group, this
 | 
			
		||||
		/// parameter may be <c>null</c> and set later manually.</param>
 | 
			
		||||
		/// <param name="bCreateNewUuid">If <c>true</c>, a new UUID will be created
 | 
			
		||||
		/// for this entry. If <c>false</c>, the UUID is zero and you must set it
 | 
			
		||||
		/// manually later.</param>
 | 
			
		||||
		/// <param name="bSetTimes">If <c>true</c>, the creation, last modification
 | 
			
		||||
		/// and last access times will be set to the current system time.</param>
 | 
			
		||||
		[Obsolete("Use a different constructor. To add an entry to a group, use AddEntry of PwGroup.")]
 | 
			
		||||
		public PwEntry(PwGroup pwParentGroup, bool bCreateNewUuid, bool bSetTimes)
 | 
			
		||||
		{
 | 
			
		||||
			m_pParentGroup = pwParentGroup;
 | 
			
		||||
 | 
			
		||||
			if(bCreateNewUuid) m_uuid = new PwUuid(true);
 | 
			
		||||
 | 
			
		||||
			if(bSetTimes)
 | 
			
		||||
			{
 | 
			
		||||
				m_tCreation = m_tLastMod = m_tLastAccess =
 | 
			
		||||
					m_tParentGroupLastMod = DateTime.Now;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Clone the current entry. The returned entry is an exact value copy
 | 
			
		||||
		/// of the current entry (including UUID and parent group reference).
 | 
			
		||||
		/// All mutable members are cloned.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Exact value clone. All references to mutable values changed.</returns>
 | 
			
		||||
		public PwEntry CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			PwEntry peNew = new PwEntry(false, false);
 | 
			
		||||
 | 
			
		||||
			peNew.m_uuid = m_uuid; // PwUuid is immutable
 | 
			
		||||
			peNew.m_pParentGroup = m_pParentGroup;
 | 
			
		||||
			peNew.m_tParentGroupLastMod = m_tParentGroupLastMod;
 | 
			
		||||
 | 
			
		||||
			peNew.m_listStrings = m_listStrings.CloneDeep();
 | 
			
		||||
			peNew.m_listBinaries = m_listBinaries.CloneDeep();
 | 
			
		||||
			peNew.m_listAutoType = m_listAutoType.CloneDeep();
 | 
			
		||||
			peNew.m_listHistory = m_listHistory.CloneDeep();
 | 
			
		||||
 | 
			
		||||
			peNew.m_pwIcon = m_pwIcon;
 | 
			
		||||
			peNew.m_pwCustomIconID = m_pwCustomIconID;
 | 
			
		||||
 | 
			
		||||
			peNew.m_clrForeground = m_clrForeground;
 | 
			
		||||
			peNew.m_clrBackground = m_clrBackground;
 | 
			
		||||
 | 
			
		||||
			peNew.m_tCreation = m_tCreation;
 | 
			
		||||
			peNew.m_tLastMod = m_tLastMod;
 | 
			
		||||
			peNew.m_tLastAccess = m_tLastAccess;
 | 
			
		||||
			peNew.m_tExpire = m_tExpire;
 | 
			
		||||
			peNew.m_bExpires = m_bExpires;
 | 
			
		||||
			peNew.m_uUsageCount = m_uUsageCount;
 | 
			
		||||
 | 
			
		||||
			peNew.m_strOverrideUrl = m_strOverrideUrl;
 | 
			
		||||
 | 
			
		||||
			peNew.m_vTags = new List<string>(m_vTags);
 | 
			
		||||
 | 
			
		||||
			return peNew;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public PwEntry CloneStructure()
 | 
			
		||||
		{
 | 
			
		||||
			PwEntry peNew = new PwEntry(false, false);
 | 
			
		||||
 | 
			
		||||
			peNew.m_uuid = m_uuid; // PwUuid is immutable
 | 
			
		||||
			peNew.m_tParentGroupLastMod = m_tParentGroupLastMod;
 | 
			
		||||
			// Do not assign m_pParentGroup
 | 
			
		||||
 | 
			
		||||
			return peNew;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static PwCompareOptions BuildCmpOpt(bool bIgnoreParentGroup,
 | 
			
		||||
			bool bIgnoreLastMod, bool bIgnoreLastAccess, bool bIgnoreHistory,
 | 
			
		||||
			bool bIgnoreThisLastBackup)
 | 
			
		||||
		{
 | 
			
		||||
			PwCompareOptions pwOpt = PwCompareOptions.None;
 | 
			
		||||
			if(bIgnoreParentGroup) pwOpt |= PwCompareOptions.IgnoreParentGroup;
 | 
			
		||||
			if(bIgnoreLastMod) pwOpt |= PwCompareOptions.IgnoreLastMod;
 | 
			
		||||
			if(bIgnoreLastAccess) pwOpt |= PwCompareOptions.IgnoreLastAccess;
 | 
			
		||||
			if(bIgnoreHistory) pwOpt |= PwCompareOptions.IgnoreHistory;
 | 
			
		||||
			if(bIgnoreThisLastBackup) pwOpt |= PwCompareOptions.IgnoreLastBackup;
 | 
			
		||||
			return pwOpt;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public bool EqualsEntry(PwEntry pe, bool bIgnoreParentGroup, bool bIgnoreLastMod,
 | 
			
		||||
			bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup)
 | 
			
		||||
		{
 | 
			
		||||
			return EqualsEntry(pe, BuildCmpOpt(bIgnoreParentGroup, bIgnoreLastMod,
 | 
			
		||||
				bIgnoreLastAccess, bIgnoreHistory, bIgnoreThisLastBackup),
 | 
			
		||||
				MemProtCmpMode.None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public bool EqualsEntry(PwEntry pe, bool bIgnoreParentGroup, bool bIgnoreLastMod,
 | 
			
		||||
			bool bIgnoreLastAccess, bool bIgnoreHistory, bool bIgnoreThisLastBackup,
 | 
			
		||||
			MemProtCmpMode mpCmpStr)
 | 
			
		||||
		{
 | 
			
		||||
			return EqualsEntry(pe, BuildCmpOpt(bIgnoreParentGroup, bIgnoreLastMod,
 | 
			
		||||
				bIgnoreLastAccess, bIgnoreHistory, bIgnoreThisLastBackup), mpCmpStr);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool EqualsEntry(PwEntry pe, PwCompareOptions pwOpt,
 | 
			
		||||
			MemProtCmpMode mpCmpStr)
 | 
			
		||||
		{
 | 
			
		||||
			if(pe == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			bool bNeEqStd = ((pwOpt & PwCompareOptions.NullEmptyEquivStd) !=
 | 
			
		||||
				PwCompareOptions.None);
 | 
			
		||||
			bool bIgnoreLastAccess = ((pwOpt & PwCompareOptions.IgnoreLastAccess) !=
 | 
			
		||||
				PwCompareOptions.None);
 | 
			
		||||
			bool bIgnoreLastMod = ((pwOpt & PwCompareOptions.IgnoreLastMod) !=
 | 
			
		||||
				PwCompareOptions.None);
 | 
			
		||||
 | 
			
		||||
			if(!m_uuid.EqualsValue(pe.m_uuid)) return false;
 | 
			
		||||
			if((pwOpt & PwCompareOptions.IgnoreParentGroup) == PwCompareOptions.None)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_pParentGroup != pe.m_pParentGroup) return false;
 | 
			
		||||
				if(!bIgnoreLastMod && (m_tParentGroupLastMod != pe.m_tParentGroupLastMod))
 | 
			
		||||
					return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(!m_listStrings.EqualsDictionary(pe.m_listStrings, pwOpt, mpCmpStr))
 | 
			
		||||
				return false;
 | 
			
		||||
			if(!m_listBinaries.EqualsDictionary(pe.m_listBinaries)) return false;
 | 
			
		||||
 | 
			
		||||
			if(!m_listAutoType.Equals(pe.m_listAutoType)) return false;
 | 
			
		||||
 | 
			
		||||
			if((pwOpt & PwCompareOptions.IgnoreHistory) == PwCompareOptions.None)
 | 
			
		||||
			{
 | 
			
		||||
				bool bIgnoreLastBackup = ((pwOpt & PwCompareOptions.IgnoreLastBackup) !=
 | 
			
		||||
					PwCompareOptions.None);
 | 
			
		||||
 | 
			
		||||
				if(!bIgnoreLastBackup && (m_listHistory.UCount != pe.m_listHistory.UCount))
 | 
			
		||||
					return false;
 | 
			
		||||
				if(bIgnoreLastBackup && (m_listHistory.UCount == 0))
 | 
			
		||||
				{
 | 
			
		||||
					Debug.Assert(false);
 | 
			
		||||
					return false;
 | 
			
		||||
				}
 | 
			
		||||
				if(bIgnoreLastBackup && ((m_listHistory.UCount - 1) != pe.m_listHistory.UCount))
 | 
			
		||||
					return false;
 | 
			
		||||
 | 
			
		||||
				PwCompareOptions cmpSub = PwCompareOptions.IgnoreParentGroup;
 | 
			
		||||
				if(bNeEqStd) cmpSub |= PwCompareOptions.NullEmptyEquivStd;
 | 
			
		||||
				if(bIgnoreLastMod) cmpSub |= PwCompareOptions.IgnoreLastMod;
 | 
			
		||||
				if(bIgnoreLastAccess) cmpSub |= PwCompareOptions.IgnoreLastAccess;
 | 
			
		||||
 | 
			
		||||
				for(uint uHist = 0; uHist < pe.m_listHistory.UCount; ++uHist)
 | 
			
		||||
				{
 | 
			
		||||
					if(!m_listHistory.GetAt(uHist).EqualsEntry(pe.m_listHistory.GetAt(
 | 
			
		||||
						uHist), cmpSub, MemProtCmpMode.None))
 | 
			
		||||
						return false;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(m_pwIcon != pe.m_pwIcon) return false;
 | 
			
		||||
			if(!m_pwCustomIconID.EqualsValue(pe.m_pwCustomIconID)) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_clrForeground != pe.m_clrForeground) return false;
 | 
			
		||||
			if(m_clrBackground != pe.m_clrBackground) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_tCreation != pe.m_tCreation) return false;
 | 
			
		||||
			if(!bIgnoreLastMod && (m_tLastMod != pe.m_tLastMod)) return false;
 | 
			
		||||
			if(!bIgnoreLastAccess && (m_tLastAccess != pe.m_tLastAccess)) return false;
 | 
			
		||||
			if(m_tExpire != pe.m_tExpire) return false;
 | 
			
		||||
			if(m_bExpires != pe.m_bExpires) return false;
 | 
			
		||||
			if(!bIgnoreLastAccess && (m_uUsageCount != pe.m_uUsageCount)) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_strOverrideUrl != pe.m_strOverrideUrl) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_vTags.Count != pe.m_vTags.Count) return false;
 | 
			
		||||
			for(int iTag = 0; iTag < m_vTags.Count; ++iTag)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_vTags[iTag] != pe.m_vTags[iTag]) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Assign properties to the current entry based on a template entry.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="peTemplate">Template entry. Must not be <c>null</c>.</param>
 | 
			
		||||
		/// <param name="bOnlyIfNewer">Only set the properties of the template entry
 | 
			
		||||
		/// if it is newer than the current one.</param>
 | 
			
		||||
		/// <param name="bIncludeHistory">If <c>true</c>, the history will be
 | 
			
		||||
		/// copied, too.</param>
 | 
			
		||||
		/// <param name="bAssignLocationChanged">If <c>true</c>, the
 | 
			
		||||
		/// <c>LocationChanged</c> property is copied, otherwise not.</param>
 | 
			
		||||
		public void AssignProperties(PwEntry peTemplate, bool bOnlyIfNewer,
 | 
			
		||||
			bool bIncludeHistory, bool bAssignLocationChanged)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(peTemplate != null); if(peTemplate == null) throw new ArgumentNullException("peTemplate");
 | 
			
		||||
 | 
			
		||||
			if(bOnlyIfNewer && (peTemplate.m_tLastMod < m_tLastMod)) return;
 | 
			
		||||
 | 
			
		||||
			// Template UUID should be the same as the current one
 | 
			
		||||
			Debug.Assert(m_uuid.EqualsValue(peTemplate.m_uuid));
 | 
			
		||||
			m_uuid = peTemplate.m_uuid;
 | 
			
		||||
 | 
			
		||||
			if(bAssignLocationChanged)
 | 
			
		||||
				m_tParentGroupLastMod = peTemplate.m_tParentGroupLastMod;
 | 
			
		||||
 | 
			
		||||
			m_listStrings = peTemplate.m_listStrings;
 | 
			
		||||
			m_listBinaries = peTemplate.m_listBinaries;
 | 
			
		||||
			m_listAutoType = peTemplate.m_listAutoType;
 | 
			
		||||
			if(bIncludeHistory) m_listHistory = peTemplate.m_listHistory;
 | 
			
		||||
 | 
			
		||||
			m_pwIcon = peTemplate.m_pwIcon;
 | 
			
		||||
			m_pwCustomIconID = peTemplate.m_pwCustomIconID; // Immutable
 | 
			
		||||
 | 
			
		||||
			m_clrForeground = peTemplate.m_clrForeground;
 | 
			
		||||
			m_clrBackground = peTemplate.m_clrBackground;
 | 
			
		||||
 | 
			
		||||
			m_tCreation = peTemplate.m_tCreation;
 | 
			
		||||
			m_tLastMod = peTemplate.m_tLastMod;
 | 
			
		||||
			m_tLastAccess = peTemplate.m_tLastAccess;
 | 
			
		||||
			m_tExpire = peTemplate.m_tExpire;
 | 
			
		||||
			m_bExpires = peTemplate.m_bExpires;
 | 
			
		||||
			m_uUsageCount = peTemplate.m_uUsageCount;
 | 
			
		||||
 | 
			
		||||
			m_strOverrideUrl = peTemplate.m_strOverrideUrl;
 | 
			
		||||
 | 
			
		||||
			m_vTags = new List<string>(peTemplate.m_vTags);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Touch the entry. This function updates the internal last access
 | 
			
		||||
		/// time. If the <paramref name="bModified" /> parameter is <c>true</c>,
 | 
			
		||||
		/// the last modification time gets updated, too.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bModified">Modify last modification time.</param>
 | 
			
		||||
		public void Touch(bool bModified)
 | 
			
		||||
		{
 | 
			
		||||
			Touch(bModified, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Touch the entry. This function updates the internal last access
 | 
			
		||||
		/// time. If the <paramref name="bModified" /> parameter is <c>true</c>,
 | 
			
		||||
		/// the last modification time gets updated, too.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bModified">Modify last modification time.</param>
 | 
			
		||||
		/// <param name="bTouchParents">If <c>true</c>, all parent objects
 | 
			
		||||
		/// get touched, too.</param>
 | 
			
		||||
		public void Touch(bool bModified, bool bTouchParents)
 | 
			
		||||
		{
 | 
			
		||||
			m_tLastAccess = DateTime.Now;
 | 
			
		||||
			++m_uUsageCount;
 | 
			
		||||
 | 
			
		||||
			if(bModified) m_tLastMod = m_tLastAccess;
 | 
			
		||||
 | 
			
		||||
			if(this.Touched != null)
 | 
			
		||||
				this.Touched(this, new ObjectTouchedEventArgs(this,
 | 
			
		||||
					bModified, bTouchParents));
 | 
			
		||||
			if(PwEntry.EntryTouched != null)
 | 
			
		||||
				PwEntry.EntryTouched(this, new ObjectTouchedEventArgs(this,
 | 
			
		||||
					bModified, bTouchParents));
 | 
			
		||||
 | 
			
		||||
			if(bTouchParents && (m_pParentGroup != null))
 | 
			
		||||
				m_pParentGroup.Touch(bModified, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Create a backup of this entry. The backup item doesn't contain any
 | 
			
		||||
		/// history items.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public void CreateBackup()
 | 
			
		||||
		{
 | 
			
		||||
			CreateBackup(null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Create a backup of this entry. The backup item doesn't contain any
 | 
			
		||||
		/// history items.
 | 
			
		||||
		/// <param name="pwHistMntcSettings">If this parameter isn't <c>null</c>,
 | 
			
		||||
		/// the history list is maintained automatically (i.e. old backups are
 | 
			
		||||
		/// deleted if there are too many or the history size is too large).
 | 
			
		||||
		/// This parameter may be <c>null</c> (no maintenance then).</param>
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public void CreateBackup(PwDatabase pwHistMntcSettings)
 | 
			
		||||
		{
 | 
			
		||||
			PwEntry peCopy = CloneDeep();
 | 
			
		||||
			peCopy.History = new PwObjectList<PwEntry>(); // Remove history
 | 
			
		||||
 | 
			
		||||
			m_listHistory.Add(peCopy); // Must be added at end, see EqualsEntry
 | 
			
		||||
 | 
			
		||||
			if(pwHistMntcSettings != null) MaintainBackups(pwHistMntcSettings);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Restore an entry snapshot from backups.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uBackupIndex">Index of the backup item, to which
 | 
			
		||||
		/// should be reverted.</param>
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public void RestoreFromBackup(uint uBackupIndex)
 | 
			
		||||
		{
 | 
			
		||||
			RestoreFromBackup(uBackupIndex, null);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Restore an entry snapshot from backups.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uBackupIndex">Index of the backup item, to which
 | 
			
		||||
		/// should be reverted.</param>
 | 
			
		||||
		/// <param name="pwHistMntcSettings">If this parameter isn't <c>null</c>,
 | 
			
		||||
		/// the history list is maintained automatically (i.e. old backups are
 | 
			
		||||
		/// deleted if there are too many or the history size is too large).
 | 
			
		||||
		/// This parameter may be <c>null</c> (no maintenance then).</param>
 | 
			
		||||
		public void RestoreFromBackup(uint uBackupIndex, PwDatabase pwHistMntcSettings)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(uBackupIndex < m_listHistory.UCount);
 | 
			
		||||
			if(uBackupIndex >= m_listHistory.UCount)
 | 
			
		||||
				throw new ArgumentOutOfRangeException("uBackupIndex");
 | 
			
		||||
 | 
			
		||||
			PwEntry pe = m_listHistory.GetAt(uBackupIndex);
 | 
			
		||||
			Debug.Assert(pe != null); if(pe == null) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			CreateBackup(pwHistMntcSettings); // Backup current data before restoring
 | 
			
		||||
			AssignProperties(pe, false, false, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool HasBackupOfData(PwEntry peData, bool bIgnoreLastMod,
 | 
			
		||||
			bool bIgnoreLastAccess)
 | 
			
		||||
		{
 | 
			
		||||
			if(peData == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			PwCompareOptions cmpOpt = (PwCompareOptions.IgnoreParentGroup |
 | 
			
		||||
				PwCompareOptions.IgnoreHistory | PwCompareOptions.NullEmptyEquivStd);
 | 
			
		||||
			if(bIgnoreLastMod) cmpOpt |= PwCompareOptions.IgnoreLastMod;
 | 
			
		||||
			if(bIgnoreLastAccess) cmpOpt |= PwCompareOptions.IgnoreLastAccess;
 | 
			
		||||
 | 
			
		||||
			foreach(PwEntry pe in m_listHistory)
 | 
			
		||||
			{
 | 
			
		||||
				if(pe.EqualsEntry(peData, cmpOpt, MemProtCmpMode.None)) return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Delete old history items if there are too many or the history
 | 
			
		||||
		/// size is too large.
 | 
			
		||||
		/// <returns>If one or more history items have been deleted, <c>true</c>
 | 
			
		||||
		/// is returned. Otherwise <c>false</c>.</returns>
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool MaintainBackups(PwDatabase pwSettings)
 | 
			
		||||
		{
 | 
			
		||||
			if(pwSettings == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			bool bDeleted = false;
 | 
			
		||||
 | 
			
		||||
			int nMaxItems = pwSettings.HistoryMaxItems;
 | 
			
		||||
			if(nMaxItems >= 0)
 | 
			
		||||
			{
 | 
			
		||||
				while(m_listHistory.UCount > (uint)nMaxItems)
 | 
			
		||||
				{
 | 
			
		||||
					RemoveOldestBackup();
 | 
			
		||||
					bDeleted = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			long lMaxSize = pwSettings.HistoryMaxSize;
 | 
			
		||||
			if(lMaxSize >= 0)
 | 
			
		||||
			{
 | 
			
		||||
				while(true)
 | 
			
		||||
				{
 | 
			
		||||
					ulong uHistSize = 0;
 | 
			
		||||
					foreach(PwEntry pe in m_listHistory) { uHistSize += pe.GetSize(); }
 | 
			
		||||
 | 
			
		||||
					if(uHistSize > (ulong)lMaxSize)
 | 
			
		||||
					{
 | 
			
		||||
						RemoveOldestBackup();
 | 
			
		||||
						bDeleted = true;
 | 
			
		||||
					}
 | 
			
		||||
					else break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return bDeleted;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void RemoveOldestBackup()
 | 
			
		||||
		{
 | 
			
		||||
			DateTime dtMin = DateTime.MaxValue;
 | 
			
		||||
			uint idxRemove = uint.MaxValue;
 | 
			
		||||
 | 
			
		||||
			for(uint u = 0; u < m_listHistory.UCount; ++u)
 | 
			
		||||
			{
 | 
			
		||||
				PwEntry pe = m_listHistory.GetAt(u);
 | 
			
		||||
				if(pe.LastModificationTime < dtMin)
 | 
			
		||||
				{
 | 
			
		||||
					idxRemove = u;
 | 
			
		||||
					dtMin = pe.LastModificationTime;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(idxRemove != uint.MaxValue) m_listHistory.RemoveAt(idxRemove);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool GetAutoTypeEnabled()
 | 
			
		||||
		{
 | 
			
		||||
			if(!m_listAutoType.Enabled) return false;
 | 
			
		||||
 | 
			
		||||
			if(m_pParentGroup != null)
 | 
			
		||||
				return m_pParentGroup.GetAutoTypeEnabledInherited();
 | 
			
		||||
 | 
			
		||||
			return PwGroup.DefaultAutoTypeEnabled;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public string GetAutoTypeSequence()
 | 
			
		||||
		{
 | 
			
		||||
			string strSeq = m_listAutoType.DefaultSequence;
 | 
			
		||||
 | 
			
		||||
			PwGroup pg = m_pParentGroup;
 | 
			
		||||
			while(pg != null)
 | 
			
		||||
			{
 | 
			
		||||
				if(strSeq.Length != 0) break;
 | 
			
		||||
 | 
			
		||||
				strSeq = pg.DefaultAutoTypeSequence;
 | 
			
		||||
				pg = pg.ParentGroup;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(strSeq.Length != 0) return strSeq;
 | 
			
		||||
 | 
			
		||||
			if(PwDefs.IsTanEntry(this)) return PwDefs.DefaultAutoTypeSequenceTan;
 | 
			
		||||
			return PwDefs.DefaultAutoTypeSequence;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool GetSearchingEnabled()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_pParentGroup != null)
 | 
			
		||||
				return m_pParentGroup.GetSearchingEnabledInherited();
 | 
			
		||||
 | 
			
		||||
			return PwGroup.DefaultSearchingEnabled;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Approximate the total size of this entry in bytes (including
 | 
			
		||||
		/// strings, binaries and history entries).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Size in bytes.</returns>
 | 
			
		||||
		public ulong GetSize()
 | 
			
		||||
		{
 | 
			
		||||
			ulong uSize = 128; // Approx fixed length data
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedString> kvpStr in m_listStrings)
 | 
			
		||||
			{
 | 
			
		||||
				uSize += (ulong)kvpStr.Key.Length;
 | 
			
		||||
				uSize += (ulong)kvpStr.Value.Length;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvpBin in m_listBinaries)
 | 
			
		||||
			{
 | 
			
		||||
				uSize += (ulong)kvpBin.Key.Length;
 | 
			
		||||
				uSize += kvpBin.Value.Length;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			uSize += (ulong)m_listAutoType.DefaultSequence.Length;
 | 
			
		||||
			foreach(AutoTypeAssociation a in m_listAutoType.Associations)
 | 
			
		||||
			{
 | 
			
		||||
				uSize += (ulong)a.WindowName.Length;
 | 
			
		||||
				uSize += (ulong)a.Sequence.Length;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			foreach(PwEntry peHistory in m_listHistory)
 | 
			
		||||
				uSize += peHistory.GetSize();
 | 
			
		||||
 | 
			
		||||
			uSize += (ulong)m_strOverrideUrl.Length;
 | 
			
		||||
 | 
			
		||||
			foreach(string strTag in m_vTags)
 | 
			
		||||
				uSize += (ulong)strTag.Length;
 | 
			
		||||
 | 
			
		||||
			return uSize;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool HasTag(string strTag)
 | 
			
		||||
		{
 | 
			
		||||
			if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_vTags.Count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp)) return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool AddTag(string strTag)
 | 
			
		||||
		{
 | 
			
		||||
			if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_vTags.Count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp)) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_vTags.Add(strTag);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool RemoveTag(string strTag)
 | 
			
		||||
		{
 | 
			
		||||
			if(string.IsNullOrEmpty(strTag)) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_vTags.Count; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_vTags[i].Equals(strTag, StrUtil.CaseIgnoreCmp))
 | 
			
		||||
				{
 | 
			
		||||
					m_vTags.RemoveAt(i);
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool IsContainedIn(PwGroup pgContainer)
 | 
			
		||||
		{
 | 
			
		||||
			PwGroup pgCur = m_pParentGroup;
 | 
			
		||||
			while(pgCur != null)
 | 
			
		||||
			{
 | 
			
		||||
				if(pgCur == pgContainer) return true;
 | 
			
		||||
 | 
			
		||||
				pgCur = pgCur.ParentGroup;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void SetUuid(PwUuid pwNewUuid, bool bAlsoChangeHistoryUuids)
 | 
			
		||||
		{
 | 
			
		||||
			this.Uuid = pwNewUuid;
 | 
			
		||||
 | 
			
		||||
			if(bAlsoChangeHistoryUuids)
 | 
			
		||||
			{
 | 
			
		||||
				foreach(PwEntry peHist in m_listHistory)
 | 
			
		||||
				{
 | 
			
		||||
					peHist.Uuid = pwNewUuid;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class PwEntryComparer : IComparer<PwEntry>
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strFieldName;
 | 
			
		||||
		private bool m_bCaseInsensitive;
 | 
			
		||||
		private bool m_bCompareNaturally;
 | 
			
		||||
 | 
			
		||||
		public PwEntryComparer(string strFieldName, bool bCaseInsensitive,
 | 
			
		||||
			bool bCompareNaturally)
 | 
			
		||||
		{
 | 
			
		||||
			if(strFieldName == null) throw new ArgumentNullException("strFieldName");
 | 
			
		||||
 | 
			
		||||
			m_strFieldName = strFieldName;
 | 
			
		||||
			m_bCaseInsensitive = bCaseInsensitive;
 | 
			
		||||
			m_bCompareNaturally = bCompareNaturally;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int Compare(PwEntry a, PwEntry b)
 | 
			
		||||
		{
 | 
			
		||||
			string strA = a.Strings.ReadSafe(m_strFieldName);
 | 
			
		||||
			string strB = b.Strings.ReadSafe(m_strFieldName);
 | 
			
		||||
 | 
			
		||||
			if(m_bCompareNaturally) return StrUtil.CompareNaturally(strA, strB);
 | 
			
		||||
			return string.Compare(strA, strB, m_bCaseInsensitive);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										207
									
								
								src/KeePassLib2Android/PwEnums.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								src/KeePassLib2Android/PwEnums.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,207 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Compression algorithm specifiers.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum PwCompressionAlgorithm
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// No compression.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		None = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// GZip compression.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		GZip = 1,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Virtual field: currently known number of algorithms. Should not be used
 | 
			
		||||
		/// by plugins or libraries -- it's used internally only.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Count = 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Tree traversal methods.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum TraversalMethod
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Don't traverse the tree.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		None = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Traverse the tree in pre-order mode, i.e. first visit all items
 | 
			
		||||
		/// in the current node, then visit all subnodes.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		PreOrder = 1
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Methods for merging password databases/entries.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum PwMergeMethod
 | 
			
		||||
	{
 | 
			
		||||
		None = 0,
 | 
			
		||||
		OverwriteExisting = 1,
 | 
			
		||||
		KeepExisting = 2,
 | 
			
		||||
		OverwriteIfNewer = 3,
 | 
			
		||||
		CreateNewUuids = 4,
 | 
			
		||||
		Synchronize = 5
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Icon identifiers for groups and password entries.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum PwIcon
 | 
			
		||||
	{
 | 
			
		||||
		Key = 0,
 | 
			
		||||
		World,
 | 
			
		||||
		Warning,
 | 
			
		||||
		NetworkServer,
 | 
			
		||||
		MarkedDirectory,
 | 
			
		||||
		UserCommunication,
 | 
			
		||||
		Parts,
 | 
			
		||||
		Notepad,
 | 
			
		||||
		WorldSocket,
 | 
			
		||||
		Identity,
 | 
			
		||||
		PaperReady,
 | 
			
		||||
		Digicam,
 | 
			
		||||
		IRCommunication,
 | 
			
		||||
		MultiKeys,
 | 
			
		||||
		Energy,
 | 
			
		||||
		Scanner,
 | 
			
		||||
		WorldStar,
 | 
			
		||||
		CDRom,
 | 
			
		||||
		Monitor,
 | 
			
		||||
		EMail,
 | 
			
		||||
		Configuration,
 | 
			
		||||
		ClipboardReady,
 | 
			
		||||
		PaperNew,
 | 
			
		||||
		Screen,
 | 
			
		||||
		EnergyCareful,
 | 
			
		||||
		EMailBox,
 | 
			
		||||
		Disk,
 | 
			
		||||
		Drive,
 | 
			
		||||
		PaperQ,
 | 
			
		||||
		TerminalEncrypted,
 | 
			
		||||
		Console,
 | 
			
		||||
		Printer,
 | 
			
		||||
		ProgramIcons,
 | 
			
		||||
		Run,
 | 
			
		||||
		Settings,
 | 
			
		||||
		WorldComputer,
 | 
			
		||||
		Archive,
 | 
			
		||||
		Homebanking,
 | 
			
		||||
		DriveWindows,
 | 
			
		||||
		Clock,
 | 
			
		||||
		EMailSearch,
 | 
			
		||||
		PaperFlag,
 | 
			
		||||
		Memory,
 | 
			
		||||
		TrashBin,
 | 
			
		||||
		Note,
 | 
			
		||||
		Expired,
 | 
			
		||||
		Info,
 | 
			
		||||
		Package,
 | 
			
		||||
		Folder,
 | 
			
		||||
		FolderOpen,
 | 
			
		||||
		FolderPackage,
 | 
			
		||||
		LockOpen,
 | 
			
		||||
		PaperLocked,
 | 
			
		||||
		Checked,
 | 
			
		||||
		Pen,
 | 
			
		||||
		Thumbnail,
 | 
			
		||||
		Book,
 | 
			
		||||
		List,
 | 
			
		||||
		UserKey,
 | 
			
		||||
		Tool,
 | 
			
		||||
		Home,
 | 
			
		||||
		Star,
 | 
			
		||||
		Tux,
 | 
			
		||||
		Feather,
 | 
			
		||||
		Apple,
 | 
			
		||||
		Wiki,
 | 
			
		||||
		Money,
 | 
			
		||||
		Certificate,
 | 
			
		||||
		BlackBerry,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Virtual identifier -- represents the number of icons.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Count
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public enum ProxyServerType
 | 
			
		||||
	{
 | 
			
		||||
		None = 0,
 | 
			
		||||
		System = 1,
 | 
			
		||||
		Manual = 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Comparison modes for in-memory protected objects.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum MemProtCmpMode
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Ignore the in-memory protection states.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		None = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Ignore the in-memory protection states of standard
 | 
			
		||||
		/// objects; do compare in-memory protection states of
 | 
			
		||||
		/// custom objects.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		CustomOnly,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Compare in-memory protection states.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Full
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[Flags]
 | 
			
		||||
	public enum PwCompareOptions
 | 
			
		||||
	{
 | 
			
		||||
		None = 0x0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Empty standard string fields are considered to be the
 | 
			
		||||
		/// same as non-existing standard string fields.
 | 
			
		||||
		/// This doesn't affect custom string comparisons.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		NullEmptyEquivStd = 0x1,
 | 
			
		||||
 | 
			
		||||
		IgnoreParentGroup = 0x2,
 | 
			
		||||
		IgnoreLastAccess = 0x4,
 | 
			
		||||
		IgnoreLastMod = 0x8,
 | 
			
		||||
		IgnoreHistory = 0x10,
 | 
			
		||||
		IgnoreLastBackup = 0x20,
 | 
			
		||||
 | 
			
		||||
		IgnoreTimes = (IgnoreLastAccess | IgnoreLastMod)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1438
									
								
								src/KeePassLib2Android/PwGroup.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1438
									
								
								src/KeePassLib2Android/PwGroup.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										179
									
								
								src/KeePassLib2Android/PwUuid.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								src/KeePassLib2Android/PwUuid.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,179 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib
 | 
			
		||||
{
 | 
			
		||||
	// [ImmutableObject(true)]
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Represents an UUID of a password entry or group. Once created, <c>PwUuid</c>
 | 
			
		||||
	/// objects aren't modifyable anymore (immutable).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class PwUuid
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Standard size in bytes of a UUID.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const uint UuidSize = 16;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Zero UUID (all bytes are zero).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static readonly PwUuid Zero = new PwUuid();
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbUuid = new byte[UuidSize];
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the 16 UUID bytes.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public byte[] UuidBytes
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbUuid; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new UUID object. Its value is initialized to zero.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private PwUuid()
 | 
			
		||||
		{
 | 
			
		||||
			SetZero();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new UUID object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bCreateNew">If this parameter is <c>true</c>, a new
 | 
			
		||||
		/// UUID is generated. If it is <c>false</c>, the UUID is initialized
 | 
			
		||||
		/// to zero.</param>
 | 
			
		||||
		public PwUuid(bool bCreateNew)
 | 
			
		||||
		{
 | 
			
		||||
			if(bCreateNew) CreateNew();
 | 
			
		||||
			else SetZero();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new UUID object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uuidBytes">Initial value of the <c>PwUuid</c> object.</param>
 | 
			
		||||
		public PwUuid(byte[] uuidBytes)
 | 
			
		||||
		{
 | 
			
		||||
			SetValue(uuidBytes);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Create a new, random UUID.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if a random UUID has been generated,
 | 
			
		||||
		/// otherwise it returns <c>false</c>.</returns>
 | 
			
		||||
		private void CreateNew()
 | 
			
		||||
		{
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				m_pbUuid = Guid.NewGuid().ToByteArray();
 | 
			
		||||
 | 
			
		||||
				if((m_pbUuid == null) || (m_pbUuid.Length != UuidSize))
 | 
			
		||||
					throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
				// Zero is a reserved value -- do not generate Zero
 | 
			
		||||
				if(this.EqualsValue(PwUuid.Zero) == false)
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Compare this UUID with another.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uuid">Second UUID object.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if both PwUuid object contain the same
 | 
			
		||||
		/// value, otherwise <c>false</c> is returned.</returns>
 | 
			
		||||
		public bool EqualsValue(PwUuid uuid)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(uuid != null);
 | 
			
		||||
			if(uuid == null) throw new ArgumentNullException("uuid");
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < UuidSize; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_pbUuid[i] != uuid.m_pbUuid[i]) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert the UUID to its string representation.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>String containing the UUID value.</returns>
 | 
			
		||||
		public string ToHexString()
 | 
			
		||||
		{
 | 
			
		||||
			return MemUtil.ByteArrayToHexString(m_pbUuid);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set the UUID value. The input parameter will not be modified.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uuidBytes">UUID bytes. The byte array must contain
 | 
			
		||||
		/// exactly <c>UUIDSize</c> bytes, otherwise the function will fail.</param>
 | 
			
		||||
		private void SetValue(byte[] uuidBytes)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((uuidBytes != null) && (uuidBytes.Length == UuidSize));
 | 
			
		||||
			if(uuidBytes == null) throw new ArgumentNullException("uuidBytes");
 | 
			
		||||
			if(uuidBytes.Length != UuidSize) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			Array.Copy(uuidBytes, m_pbUuid, (int)UuidSize);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set the UUID value to zero.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private void SetZero()
 | 
			
		||||
		{
 | 
			
		||||
			Array.Clear(m_pbUuid, 0, (int)UuidSize);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class PwUuidComparable : IComparable<PwUuidComparable>
 | 
			
		||||
	{
 | 
			
		||||
		private byte[] m_pbUuid = new byte[PwUuid.UuidSize];
 | 
			
		||||
 | 
			
		||||
		public PwUuidComparable(PwUuid pwUuid)
 | 
			
		||||
		{
 | 
			
		||||
			if(pwUuid == null) throw new ArgumentNullException("pwUuid");
 | 
			
		||||
 | 
			
		||||
			Array.Copy(pwUuid.UuidBytes, m_pbUuid, (int)PwUuid.UuidSize);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int CompareTo(PwUuidComparable other)
 | 
			
		||||
		{
 | 
			
		||||
			if(other == null) throw new ArgumentNullException("other");
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < (int)PwUuid.UuidSize; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_pbUuid[i] < other.m_pbUuid[i]) return -1;
 | 
			
		||||
				if(m_pbUuid[i] > other.m_pbUuid[i]) return 1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								src/KeePassLib2Android/Resources/AboutResources.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/KeePassLib2Android/Resources/AboutResources.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
Images, layout descriptions, binary blobs and string dictionaries can be included 
 | 
			
		||||
in your application as resource files.  Various Android APIs are designed to 
 | 
			
		||||
operate on the resource IDs instead of dealing with images, strings or binary blobs 
 | 
			
		||||
directly.
 | 
			
		||||
 | 
			
		||||
For example, a sample Android app that contains a user interface layout (main.axml),
 | 
			
		||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 
 | 
			
		||||
would keep its resources in the "Resources" directory of the application:
 | 
			
		||||
 | 
			
		||||
Resources/
 | 
			
		||||
    drawable/
 | 
			
		||||
        icon.png
 | 
			
		||||
 | 
			
		||||
    layout/
 | 
			
		||||
        main.axml
 | 
			
		||||
 | 
			
		||||
    values/
 | 
			
		||||
        strings.xml
 | 
			
		||||
 | 
			
		||||
In order to get the build system to recognize Android resources, set the build action to
 | 
			
		||||
"AndroidResource".  The native Android APIs do not operate directly with filenames, but 
 | 
			
		||||
instead operate on resource IDs.  When you compile an Android application that uses resources, 
 | 
			
		||||
the build system will package the resources for distribution and generate a class called "R" 
 | 
			
		||||
(this is an Android convention) that contains the tokens for each one of the resources 
 | 
			
		||||
included. For example, for the above Resources layout, this is what the R class would expose:
 | 
			
		||||
 | 
			
		||||
public class R {
 | 
			
		||||
    public class drawable {
 | 
			
		||||
        public const int icon = 0x123;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class layout {
 | 
			
		||||
        public const int main = 0x456;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class strings {
 | 
			
		||||
        public const int first_string = 0xabc;
 | 
			
		||||
        public const int second_string = 0xbcd;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 
 | 
			
		||||
to reference the layout/main.axml file, or R.strings.first_string to reference the first 
 | 
			
		||||
string in the dictionary file values/strings.xml.
 | 
			
		||||
							
								
								
									
										390
									
								
								src/KeePassLib2Android/Resources/KLRes.Generated.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								src/KeePassLib2Android/Resources/KLRes.Generated.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,390 @@
 | 
			
		||||
// This is a generated file!
 | 
			
		||||
// Do not edit manually, changes will be overwritten.
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Resources
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A strongly-typed resource class, for looking up localized strings, etc.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class KLRes
 | 
			
		||||
	{
 | 
			
		||||
		private static string TryGetEx(Dictionary<string, string> dictNew,
 | 
			
		||||
			string strName, string strDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string strTemp;
 | 
			
		||||
 | 
			
		||||
			if(dictNew.TryGetValue(strName, out strTemp))
 | 
			
		||||
				return strTemp;
 | 
			
		||||
 | 
			
		||||
			return strDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void SetTranslatedStrings(Dictionary<string, string> dictNew)
 | 
			
		||||
		{
 | 
			
		||||
			if(dictNew == null) throw new ArgumentNullException("dictNew");
 | 
			
		||||
 | 
			
		||||
			m_strCryptoStreamFailed = TryGetEx(dictNew, "CryptoStreamFailed", m_strCryptoStreamFailed);
 | 
			
		||||
			m_strEncAlgorithmAes = TryGetEx(dictNew, "EncAlgorithmAes", m_strEncAlgorithmAes);
 | 
			
		||||
			m_strErrorInClipboard = TryGetEx(dictNew, "ErrorInClipboard", m_strErrorInClipboard);
 | 
			
		||||
			m_strFatalError = TryGetEx(dictNew, "FatalError", m_strFatalError);
 | 
			
		||||
			m_strFatalErrorText = TryGetEx(dictNew, "FatalErrorText", m_strFatalErrorText);
 | 
			
		||||
			m_strFileCorrupted = TryGetEx(dictNew, "FileCorrupted", m_strFileCorrupted);
 | 
			
		||||
			m_strFileHeaderEndEarly = TryGetEx(dictNew, "FileHeaderEndEarly", m_strFileHeaderEndEarly);
 | 
			
		||||
			m_strFileLoadFailed = TryGetEx(dictNew, "FileLoadFailed", m_strFileLoadFailed);
 | 
			
		||||
			m_strFileLockedWrite = TryGetEx(dictNew, "FileLockedWrite", m_strFileLockedWrite);
 | 
			
		||||
			m_strFileNewVerReq = TryGetEx(dictNew, "FileNewVerReq", m_strFileNewVerReq);
 | 
			
		||||
			m_strFileSaveCorruptionWarning = TryGetEx(dictNew, "FileSaveCorruptionWarning", m_strFileSaveCorruptionWarning);
 | 
			
		||||
			m_strFileSaveFailed = TryGetEx(dictNew, "FileSaveFailed", m_strFileSaveFailed);
 | 
			
		||||
			m_strFileSigInvalid = TryGetEx(dictNew, "FileSigInvalid", m_strFileSigInvalid);
 | 
			
		||||
			m_strFileUnknownCipher = TryGetEx(dictNew, "FileUnknownCipher", m_strFileUnknownCipher);
 | 
			
		||||
			m_strFileUnknownCompression = TryGetEx(dictNew, "FileUnknownCompression", m_strFileUnknownCompression);
 | 
			
		||||
			m_strFileVersionUnsupported = TryGetEx(dictNew, "FileVersionUnsupported", m_strFileVersionUnsupported);
 | 
			
		||||
			m_strFinalKeyCreationFailed = TryGetEx(dictNew, "FinalKeyCreationFailed", m_strFinalKeyCreationFailed);
 | 
			
		||||
			m_strFrameworkNotImplExcp = TryGetEx(dictNew, "FrameworkNotImplExcp", m_strFrameworkNotImplExcp);
 | 
			
		||||
			m_strInvalidCompositeKey = TryGetEx(dictNew, "InvalidCompositeKey", m_strInvalidCompositeKey);
 | 
			
		||||
			m_strInvalidCompositeKeyHint = TryGetEx(dictNew, "InvalidCompositeKeyHint", m_strInvalidCompositeKeyHint);
 | 
			
		||||
			m_strInvalidDataWhileDecoding = TryGetEx(dictNew, "InvalidDataWhileDecoding", m_strInvalidDataWhileDecoding);
 | 
			
		||||
			m_strKeePass1xHint = TryGetEx(dictNew, "KeePass1xHint", m_strKeePass1xHint);
 | 
			
		||||
			m_strMasterSeedLengthInvalid = TryGetEx(dictNew, "MasterSeedLengthInvalid", m_strMasterSeedLengthInvalid);
 | 
			
		||||
			m_strOldFormat = TryGetEx(dictNew, "OldFormat", m_strOldFormat);
 | 
			
		||||
			m_strTryAgainSecs = TryGetEx(dictNew, "TryAgainSecs", m_strTryAgainSecs);
 | 
			
		||||
			m_strUnknownHeaderId = TryGetEx(dictNew, "UnknownHeaderId", m_strUnknownHeaderId);
 | 
			
		||||
			m_strUserAccountKeyError = TryGetEx(dictNew, "UserAccountKeyError", m_strUserAccountKeyError);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static readonly string[] m_vKeyNames = {
 | 
			
		||||
			"CryptoStreamFailed",
 | 
			
		||||
			"EncAlgorithmAes",
 | 
			
		||||
			"ErrorInClipboard",
 | 
			
		||||
			"FatalError",
 | 
			
		||||
			"FatalErrorText",
 | 
			
		||||
			"FileCorrupted",
 | 
			
		||||
			"FileHeaderEndEarly",
 | 
			
		||||
			"FileLoadFailed",
 | 
			
		||||
			"FileLockedWrite",
 | 
			
		||||
			"FileNewVerReq",
 | 
			
		||||
			"FileSaveCorruptionWarning",
 | 
			
		||||
			"FileSaveFailed",
 | 
			
		||||
			"FileSigInvalid",
 | 
			
		||||
			"FileUnknownCipher",
 | 
			
		||||
			"FileUnknownCompression",
 | 
			
		||||
			"FileVersionUnsupported",
 | 
			
		||||
			"FinalKeyCreationFailed",
 | 
			
		||||
			"FrameworkNotImplExcp",
 | 
			
		||||
			"InvalidCompositeKey",
 | 
			
		||||
			"InvalidCompositeKeyHint",
 | 
			
		||||
			"InvalidDataWhileDecoding",
 | 
			
		||||
			"KeePass1xHint",
 | 
			
		||||
			"MasterSeedLengthInvalid",
 | 
			
		||||
			"OldFormat",
 | 
			
		||||
			"TryAgainSecs",
 | 
			
		||||
			"UnknownHeaderId",
 | 
			
		||||
			"UserAccountKeyError"
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		public static string[] GetKeyNames()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vKeyNames;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strCryptoStreamFailed =
 | 
			
		||||
			@"Failed to initialize encryption/decryption stream!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Failed to initialize encryption/decryption stream!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string CryptoStreamFailed
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strCryptoStreamFailed; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strEncAlgorithmAes =
 | 
			
		||||
			@"AES/Rijndael (256-Bit Key)";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'AES/Rijndael (256-Bit Key)'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string EncAlgorithmAes
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strEncAlgorithmAes; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strErrorInClipboard =
 | 
			
		||||
			@"An extended error report has been copied to the clipboard.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'An extended error report has been copied to the clipboard.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string ErrorInClipboard
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strErrorInClipboard; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFatalError =
 | 
			
		||||
			@"Fatal Error";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Fatal Error'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FatalError
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFatalError; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFatalErrorText =
 | 
			
		||||
			@"A fatal error has occurred!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'A fatal error has occurred!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FatalErrorText
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFatalErrorText; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileCorrupted =
 | 
			
		||||
			@"The file is corrupted.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file is corrupted.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileCorrupted
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileCorrupted; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileHeaderEndEarly =
 | 
			
		||||
			@"The file header is corrupted! Some header data was declared but is not present.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file header is corrupted! Some header data was declared but is not present.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileHeaderEndEarly
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileHeaderEndEarly; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileLoadFailed =
 | 
			
		||||
			@"Failed to load the specified file!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Failed to load the specified file!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileLoadFailed
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileLoadFailed; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileLockedWrite =
 | 
			
		||||
			@"The file is locked, because the following user is currently writing to it:";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file is locked, because the following user is currently writing to it:'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileLockedWrite
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileLockedWrite; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileNewVerReq =
 | 
			
		||||
			@"A newer KeePass version is required to open this file.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'A newer KeePass version is required to open this file.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileNewVerReq
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileNewVerReq; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileSaveCorruptionWarning =
 | 
			
		||||
			@"The target file might be corrupted. Please try saving again. If that fails, save the database to a different location.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The target file might be corrupted. Please try saving again. If that fails, save the database to a different location.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileSaveCorruptionWarning
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileSaveCorruptionWarning; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileSaveFailed =
 | 
			
		||||
			@"Failed to save the current database to the specified location!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Failed to save the current database to the specified location!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileSaveFailed
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileSaveFailed; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileSigInvalid =
 | 
			
		||||
			@"The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file signature is invalid. Either the file isn't a KeePass database file at all or it is corrupted.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileSigInvalid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileSigInvalid; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileUnknownCipher =
 | 
			
		||||
			@"The file is encrypted using an unknown encryption algorithm!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file is encrypted using an unknown encryption algorithm!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileUnknownCipher
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileUnknownCipher; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileUnknownCompression =
 | 
			
		||||
			@"The file is compressed using an unknown compression algorithm!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file is compressed using an unknown compression algorithm!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileUnknownCompression
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileUnknownCompression; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFileVersionUnsupported =
 | 
			
		||||
			@"The file version is unsupported.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The file version is unsupported.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FileVersionUnsupported
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFileVersionUnsupported; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFinalKeyCreationFailed =
 | 
			
		||||
			@"Failed to create the final encryption/decryption key!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Failed to create the final encryption/decryption key!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FinalKeyCreationFailed
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFinalKeyCreationFailed; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strFrameworkNotImplExcp =
 | 
			
		||||
			@"The .NET framework/runtime under which KeePass is currently running does not support this operation.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The .NET framework/runtime under which KeePass is currently running does not support this operation.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string FrameworkNotImplExcp
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFrameworkNotImplExcp; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strInvalidCompositeKey =
 | 
			
		||||
			@"The composite key is invalid!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The composite key is invalid!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string InvalidCompositeKey
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strInvalidCompositeKey; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strInvalidCompositeKeyHint =
 | 
			
		||||
			@"Make sure the composite key is correct and try again.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Make sure the composite key is correct and try again.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string InvalidCompositeKeyHint
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strInvalidCompositeKeyHint; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strInvalidDataWhileDecoding =
 | 
			
		||||
			@"Found invalid data while decoding.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Found invalid data while decoding.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string InvalidDataWhileDecoding
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strInvalidDataWhileDecoding; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strKeePass1xHint =
 | 
			
		||||
			@"In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'In order to import KeePass 1.x KDB files, create a new 2.x database file and click 'File' -> 'Import' in the main menu. In the import dialog, choose 'KeePass KDB (1.x)' as file format.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string KeePass1xHint
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strKeePass1xHint; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strMasterSeedLengthInvalid =
 | 
			
		||||
			@"The length of the master key seed is invalid!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The length of the master key seed is invalid!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string MasterSeedLengthInvalid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strMasterSeedLengthInvalid; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strOldFormat =
 | 
			
		||||
			@"The selected file appears to be an old format";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The selected file appears to be an old format'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string OldFormat
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strOldFormat; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strTryAgainSecs =
 | 
			
		||||
			@"Please try it again in a few seconds.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Please try it again in a few seconds.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string TryAgainSecs
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strTryAgainSecs; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strUnknownHeaderId =
 | 
			
		||||
			@"Unknown header ID!";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Unknown header ID!'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string UnknownHeaderId
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strUnknownHeaderId; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strUserAccountKeyError =
 | 
			
		||||
			@"The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored.";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'The operating system did not grant KeePass read/write access to the user profile folder, where the protected user key is stored.'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string UserAccountKeyError
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strUserAccountKeyError; }
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								src/KeePassLib2Android/Resources/KSRes.Generated.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/KeePassLib2Android/Resources/KSRes.Generated.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
// This is a generated file!
 | 
			
		||||
// Do not edit manually, changes will be overwritten.
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Resources
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A strongly-typed resource class, for looking up localized strings, etc.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class KSRes
 | 
			
		||||
	{
 | 
			
		||||
		private static string TryGetEx(Dictionary<string, string> dictNew,
 | 
			
		||||
			string strName, string strDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string strTemp;
 | 
			
		||||
 | 
			
		||||
			if(dictNew.TryGetValue(strName, out strTemp))
 | 
			
		||||
				return strTemp;
 | 
			
		||||
 | 
			
		||||
			return strDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void SetTranslatedStrings(Dictionary<string, string> dictNew)
 | 
			
		||||
		{
 | 
			
		||||
			if(dictNew == null) throw new ArgumentNullException("dictNew");
 | 
			
		||||
 | 
			
		||||
			m_strTest = TryGetEx(dictNew, "Test", m_strTest);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static readonly string[] m_vKeyNames = {
 | 
			
		||||
			"Test"
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		public static string[] GetKeyNames()
 | 
			
		||||
		{
 | 
			
		||||
			return m_vKeyNames;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string m_strTest =
 | 
			
		||||
			@"Test";
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Look up a localized string similar to
 | 
			
		||||
		/// 'Test'.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static string Test
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strTest; }
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/KeePassLib2Android/Resources/Resource.designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/KeePassLib2Android/Resources/Resource.designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// <auto-generated>
 | 
			
		||||
//     Dieser Code wurde von einem Tool generiert.
 | 
			
		||||
//     Laufzeitversion:4.0.30319.296
 | 
			
		||||
//
 | 
			
		||||
//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
 | 
			
		||||
//     der Code erneut generiert wird.
 | 
			
		||||
// </auto-generated>
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib2Android
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public partial class Resource
 | 
			
		||||
	{
 | 
			
		||||
		
 | 
			
		||||
		public partial class Attribute
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			private Attribute()
 | 
			
		||||
			{
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public partial class String
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			// aapt resource value: 0x7f020000
 | 
			
		||||
			public const int library_name = 2130837504;
 | 
			
		||||
			
 | 
			
		||||
			private String()
 | 
			
		||||
			{
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/KeePassLib2Android/Resources/values/Strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/KeePassLib2Android/Resources/values/Strings.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<resources>
 | 
			
		||||
	<string name="library_name">KeePassLib2Android</string>
 | 
			
		||||
</resources>
 | 
			
		||||
							
								
								
									
										242
									
								
								src/KeePassLib2Android/Security/ProtectedBinary.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								src/KeePassLib2Android/Security/ProtectedBinary.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,242 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Security
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Represents a protected binary, i.e. a byte array that is encrypted
 | 
			
		||||
	/// in memory. A <c>ProtectedBinary</c> object is immutable and
 | 
			
		||||
	/// thread-safe.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class ProtectedBinary : IEquatable<ProtectedBinary>
 | 
			
		||||
	{
 | 
			
		||||
		private const int PmBlockSize = 16;
 | 
			
		||||
 | 
			
		||||
		// In-memory protection is supported only on Windows 2000 SP3 and
 | 
			
		||||
		// higher.
 | 
			
		||||
		private static bool m_bProtectionSupported;
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbData; // Never null
 | 
			
		||||
 | 
			
		||||
		// The real length of the data. This value can be different than
 | 
			
		||||
		// m_pbData.Length, as the length of m_pbData always is a multiple
 | 
			
		||||
		// of PmBlockSize (required for fast in-memory protection).
 | 
			
		||||
		private uint m_uDataLen;
 | 
			
		||||
 | 
			
		||||
		private bool m_bProtected;
 | 
			
		||||
 | 
			
		||||
		private object m_objSync = new object();
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A flag specifying whether the <c>ProtectedBinary</c> object has
 | 
			
		||||
		/// turned on in-memory protection or not.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool IsProtected
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bProtected; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Length of the stored data.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public uint Length
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_uDataLen; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static ProtectedBinary()
 | 
			
		||||
		{
 | 
			
		||||
			try // Test whether ProtectedMemory is supported
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbDummy = new byte[PmBlockSize * 2];
 | 
			
		||||
				ProtectedMemory.Protect(pbDummy, MemoryProtectionScope.SameProcess);
 | 
			
		||||
				m_bProtectionSupported = true;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) // Windows 98 / ME
 | 
			
		||||
			{
 | 
			
		||||
				m_bProtectionSupported = false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new, empty protected binary data object. Protection
 | 
			
		||||
		/// is disabled.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedBinary()
 | 
			
		||||
		{
 | 
			
		||||
			Init(false, new byte[0]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new protected binary data object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bEnableProtection">If this paremeter is <c>true</c>,
 | 
			
		||||
		/// the data will be encrypted in memory. If it is <c>false</c>, the
 | 
			
		||||
		/// data is stored in plain-text in the process memory.</param>
 | 
			
		||||
		/// <param name="pbData">Value of the protected object.
 | 
			
		||||
		/// The input parameter is not modified and
 | 
			
		||||
		/// <c>ProtectedBinary</c> doesn't take ownership of the data,
 | 
			
		||||
		/// i.e. the caller is responsible for clearing it.</param>
 | 
			
		||||
		public ProtectedBinary(bool bEnableProtection, byte[] pbData)
 | 
			
		||||
		{
 | 
			
		||||
			Init(bEnableProtection, pbData);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new protected binary data object. Copy the data from
 | 
			
		||||
		/// a <c>XorredBuffer</c> object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bEnableProtection">Enable protection or not.</param>
 | 
			
		||||
		/// <param name="xbProtected"><c>XorredBuffer</c> object used to
 | 
			
		||||
		/// initialize the <c>ProtectedBinary</c> object.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public ProtectedBinary(bool bEnableProtection, XorredBuffer xbProtected)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(xbProtected != null); if(xbProtected == null) throw new ArgumentNullException("xbProtected");
 | 
			
		||||
 | 
			
		||||
			byte[] pb = xbProtected.ReadPlainText();
 | 
			
		||||
			Init(bEnableProtection, pb);
 | 
			
		||||
			MemUtil.ZeroByteArray(pb);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Init(bool bEnableProtection, byte[] pbData)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbData == null) throw new ArgumentNullException("pbData");
 | 
			
		||||
 | 
			
		||||
			m_bProtected = bEnableProtection;
 | 
			
		||||
			m_uDataLen = (uint)pbData.Length;
 | 
			
		||||
 | 
			
		||||
			int nBlocks = (int)m_uDataLen / PmBlockSize;
 | 
			
		||||
			if((nBlocks * PmBlockSize) < (int)m_uDataLen) ++nBlocks;
 | 
			
		||||
			Debug.Assert((nBlocks * PmBlockSize) >= (int)m_uDataLen);
 | 
			
		||||
 | 
			
		||||
			m_pbData = new byte[nBlocks * PmBlockSize];
 | 
			
		||||
			Array.Copy(pbData, m_pbData, (int)m_uDataLen);
 | 
			
		||||
 | 
			
		||||
			// Data size must be > 0, otherwise 'Protect' throws
 | 
			
		||||
			if(m_bProtected && m_bProtectionSupported && (m_uDataLen > 0))
 | 
			
		||||
				ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a copy of the protected data as a byte array.
 | 
			
		||||
		/// Please note that the returned byte array is not protected and
 | 
			
		||||
		/// can therefore been read by any other application.
 | 
			
		||||
		/// Make sure that your clear it properly after usage.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Unprotected byte array. This is always a copy of the internal
 | 
			
		||||
		/// protected data and can therefore be cleared safely.</returns>
 | 
			
		||||
		public byte[] ReadData()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_uDataLen == 0) return new byte[0];
 | 
			
		||||
 | 
			
		||||
			byte[] pbReturn = new byte[m_uDataLen];
 | 
			
		||||
 | 
			
		||||
			if(m_bProtected && m_bProtectionSupported)
 | 
			
		||||
			{
 | 
			
		||||
				lock(m_objSync)
 | 
			
		||||
				{
 | 
			
		||||
					ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess);
 | 
			
		||||
					Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
 | 
			
		||||
					ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else Array.Copy(m_pbData, pbReturn, (int)m_uDataLen);
 | 
			
		||||
 | 
			
		||||
			return pbReturn;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Read the protected data and return it protected with a sequence
 | 
			
		||||
		/// of bytes generated by a random stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="crsRandomSource">Random number source.</param>
 | 
			
		||||
		/// <returns>Protected data.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public byte[] ReadXorredData(CryptoRandomStream crsRandomSource)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(crsRandomSource != null);
 | 
			
		||||
			if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
 | 
			
		||||
 | 
			
		||||
			byte[] pbData = ReadData();
 | 
			
		||||
			uint uLen = (uint)pbData.Length;
 | 
			
		||||
 | 
			
		||||
			byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
 | 
			
		||||
			Debug.Assert(randomPad.Length == uLen);
 | 
			
		||||
 | 
			
		||||
			for(uint i = 0; i < uLen; ++i)
 | 
			
		||||
				pbData[i] ^= randomPad[i];
 | 
			
		||||
 | 
			
		||||
			return pbData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override int GetHashCode()
 | 
			
		||||
		{
 | 
			
		||||
			int h = (m_bProtected ? 0x7B11D289 : 0);
 | 
			
		||||
 | 
			
		||||
			byte[] pb = ReadData();
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				for(int i = 0; i < pb.Length; ++i)
 | 
			
		||||
					h = (h << 3) + h + (int)pb[i];
 | 
			
		||||
			}
 | 
			
		||||
			MemUtil.ZeroByteArray(pb);
 | 
			
		||||
 | 
			
		||||
			return h;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool Equals(object obj)
 | 
			
		||||
		{
 | 
			
		||||
			return Equals(obj as ProtectedBinary);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool Equals(ProtectedBinary other)
 | 
			
		||||
		{
 | 
			
		||||
			if(other == null) return false; // No assert
 | 
			
		||||
 | 
			
		||||
			if(m_bProtected != other.m_bProtected) return false;
 | 
			
		||||
			if(m_uDataLen != other.m_uDataLen) return false;
 | 
			
		||||
 | 
			
		||||
			byte[] pbL = ReadData();
 | 
			
		||||
			byte[] pbR = other.ReadData();
 | 
			
		||||
			bool bEq = MemUtil.ArraysEqual(pbL, pbR);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbL);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbR);
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
			if(bEq) { Debug.Assert(GetHashCode() == other.GetHashCode()); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return bEq;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										253
									
								
								src/KeePassLib2Android/Security/ProtectedString.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								src/KeePassLib2Android/Security/ProtectedString.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,253 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// SecureString objects are limited to 65536 characters, don't use
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Security
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Represents an in-memory encrypted string.
 | 
			
		||||
	/// <c>ProtectedString</c> objects are immutable and thread-safe.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
#if (DEBUG && !KeePassLibSD)
 | 
			
		||||
	[DebuggerDisplay(@"{ReadString()}")]
 | 
			
		||||
#endif
 | 
			
		||||
	public sealed class ProtectedString
 | 
			
		||||
	{
 | 
			
		||||
		// Exactly one of the following will be non-null
 | 
			
		||||
		private ProtectedBinary m_pbUtf8 = null;
 | 
			
		||||
		private string m_strPlainText = null;
 | 
			
		||||
 | 
			
		||||
		private bool m_bIsProtected;
 | 
			
		||||
 | 
			
		||||
		private static ProtectedString m_psEmpty = new ProtectedString();
 | 
			
		||||
		public static ProtectedString Empty
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_psEmpty; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// A flag specifying whether the <c>ProtectedString</c> object
 | 
			
		||||
		/// has turned on in-memory protection or not.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public bool IsProtected
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bIsProtected; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool IsEmpty
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
 | 
			
		||||
				if(pBin != null) return (pBin.Length == 0);
 | 
			
		||||
 | 
			
		||||
				Debug.Assert(m_strPlainText != null);
 | 
			
		||||
				return (m_strPlainText.Length == 0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private int m_nCachedLength = -1;
 | 
			
		||||
		public int Length
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				if(m_nCachedLength >= 0) return m_nCachedLength;
 | 
			
		||||
 | 
			
		||||
				ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
 | 
			
		||||
				if(pBin != null)
 | 
			
		||||
				{
 | 
			
		||||
					byte[] pbPlain = pBin.ReadData();
 | 
			
		||||
					m_nCachedLength = StrUtil.Utf8.GetCharCount(pbPlain);
 | 
			
		||||
					MemUtil.ZeroByteArray(pbPlain);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Debug.Assert(m_strPlainText != null);
 | 
			
		||||
					m_nCachedLength = m_strPlainText.Length;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return m_nCachedLength;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new protected string object. Protection is
 | 
			
		||||
		/// disabled.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public ProtectedString()
 | 
			
		||||
		{
 | 
			
		||||
			Init(false, string.Empty);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new protected string. The string is initialized
 | 
			
		||||
		/// to the value supplied in the parameters.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bEnableProtection">If this parameter is <c>true</c>,
 | 
			
		||||
		/// the string will be protected in-memory (encrypted). If it
 | 
			
		||||
		/// is <c>false</c>, the string will be stored as plain-text.</param>
 | 
			
		||||
		/// <param name="strValue">The initial string value. This
 | 
			
		||||
		/// parameter won't be modified.</param>
 | 
			
		||||
		public ProtectedString(bool bEnableProtection, string strValue)
 | 
			
		||||
		{
 | 
			
		||||
			Init(bEnableProtection, strValue);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new protected string. The string is initialized
 | 
			
		||||
		/// to the value supplied in the parameters (UTF-8 encoded string).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bEnableProtection">If this parameter is <c>true</c>,
 | 
			
		||||
		/// the string will be protected in-memory (encrypted). If it
 | 
			
		||||
		/// is <c>false</c>, the string will be stored as plain-text.</param>
 | 
			
		||||
		/// <param name="vUtf8Value">The initial string value, encoded as
 | 
			
		||||
		/// UTF-8 byte array. This parameter won't be modified; the caller
 | 
			
		||||
		/// is responsible for clearing it.</param>
 | 
			
		||||
		public ProtectedString(bool bEnableProtection, byte[] vUtf8Value)
 | 
			
		||||
		{
 | 
			
		||||
			Init(bEnableProtection, vUtf8Value);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new protected string. The string is initialized
 | 
			
		||||
		/// to the value passed in the <c>XorredBuffer</c> object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="bEnableProtection">Enable protection or not.</param>
 | 
			
		||||
		/// <param name="xbProtected"><c>XorredBuffer</c> object containing the
 | 
			
		||||
		/// string in UTF-8 representation. The UTF-8 string must not
 | 
			
		||||
		/// be <c>null</c>-terminated.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public ProtectedString(bool bEnableProtection, XorredBuffer xbProtected)
 | 
			
		||||
		{
 | 
			
		||||
			if(xbProtected == null) throw new ArgumentNullException("xbProtected");
 | 
			
		||||
 | 
			
		||||
			byte[] pb = xbProtected.ReadPlainText();
 | 
			
		||||
			Init(bEnableProtection, pb);
 | 
			
		||||
			MemUtil.ZeroByteArray(pb);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Init(bool bEnableProtection, string str)
 | 
			
		||||
		{
 | 
			
		||||
			if(str == null) throw new ArgumentNullException("str");
 | 
			
		||||
 | 
			
		||||
			m_bIsProtected = bEnableProtection;
 | 
			
		||||
 | 
			
		||||
			// The string already is in memory and immutable,
 | 
			
		||||
			// protection would be useless
 | 
			
		||||
			m_strPlainText = str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Init(bool bEnableProtection, byte[] pbUtf8)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8");
 | 
			
		||||
 | 
			
		||||
			m_bIsProtected = bEnableProtection;
 | 
			
		||||
 | 
			
		||||
			if(bEnableProtection)
 | 
			
		||||
				m_pbUtf8 = new ProtectedBinary(true, pbUtf8);
 | 
			
		||||
			else
 | 
			
		||||
				m_strPlainText = StrUtil.Utf8.GetString(pbUtf8, 0, pbUtf8.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert the protected string to a normal string object.
 | 
			
		||||
		/// Be careful with this function, the returned string object
 | 
			
		||||
		/// isn't protected anymore and stored in plain-text in the
 | 
			
		||||
		/// process memory.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Plain-text string. Is never <c>null</c>.</returns>
 | 
			
		||||
		public string ReadString()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_strPlainText != null) return m_strPlainText;
 | 
			
		||||
 | 
			
		||||
			byte[] pb = ReadUtf8();
 | 
			
		||||
			string str = ((pb.Length == 0) ? string.Empty :
 | 
			
		||||
				StrUtil.Utf8.GetString(pb, 0, pb.Length));
 | 
			
		||||
			// No need to clear pb
 | 
			
		||||
 | 
			
		||||
			// As the text is now visible in process memory anyway,
 | 
			
		||||
			// there's no need to protect it anymore
 | 
			
		||||
			m_strPlainText = str;
 | 
			
		||||
			m_pbUtf8 = null; // Thread-safe order
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Read out the string and return a byte array that contains the
 | 
			
		||||
		/// string encoded using UTF-8. The returned string is not protected
 | 
			
		||||
		/// anymore!
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Plain-text UTF-8 byte array.</returns>
 | 
			
		||||
		public byte[] ReadUtf8()
 | 
			
		||||
		{
 | 
			
		||||
			ProtectedBinary pBin = m_pbUtf8; // Local ref for thread-safety
 | 
			
		||||
			if(pBin != null) return pBin.ReadData();
 | 
			
		||||
 | 
			
		||||
			return StrUtil.Utf8.GetBytes(m_strPlainText);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Read the protected string and return it protected with a sequence
 | 
			
		||||
		/// of bytes generated by a random stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="crsRandomSource">Random number source.</param>
 | 
			
		||||
		/// <returns>Protected string.</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if the input
 | 
			
		||||
		/// parameter is <c>null</c>.</exception>
 | 
			
		||||
		public byte[] ReadXorredString(CryptoRandomStream crsRandomSource)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) throw new ArgumentNullException("crsRandomSource");
 | 
			
		||||
 | 
			
		||||
			byte[] pbData = ReadUtf8();
 | 
			
		||||
			uint uLen = (uint)pbData.Length;
 | 
			
		||||
 | 
			
		||||
			byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
 | 
			
		||||
			Debug.Assert(randomPad.Length == uLen);
 | 
			
		||||
 | 
			
		||||
			for(uint i = 0; i < uLen; ++i)
 | 
			
		||||
				pbData[i] ^= randomPad[i];
 | 
			
		||||
 | 
			
		||||
			return pbData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public ProtectedString WithProtection(bool bProtect)
 | 
			
		||||
		{
 | 
			
		||||
			if(bProtect == m_bIsProtected) return this;
 | 
			
		||||
 | 
			
		||||
			byte[] pb = ReadUtf8();
 | 
			
		||||
			ProtectedString ps = new ProtectedString(bProtect, pb);
 | 
			
		||||
			MemUtil.ZeroByteArray(pb);
 | 
			
		||||
			return ps;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										116
									
								
								src/KeePassLib2Android/Security/XorredBuffer.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								src/KeePassLib2Android/Security/XorredBuffer.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,116 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Security
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Represents an object that is encrypted using a XOR pad until
 | 
			
		||||
	/// it is read. <c>XorredBuffer</c> objects are immutable and
 | 
			
		||||
	/// thread-safe.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed class XorredBuffer
 | 
			
		||||
	{
 | 
			
		||||
		private byte[] m_pbData; // Never null
 | 
			
		||||
		private byte[] m_pbXorPad; // Always valid for m_pbData
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Length of the protected data in bytes.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public uint Length
 | 
			
		||||
		{
 | 
			
		||||
			get { return (uint)m_pbData.Length; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Construct a new XOR-protected object using a protected byte array
 | 
			
		||||
		/// and a XOR pad that decrypts the protected data. The
 | 
			
		||||
		/// <paramref name="pbProtectedData" /> byte array must have the same size
 | 
			
		||||
		/// as the <paramref name="pbXorPad" /> byte array.
 | 
			
		||||
		/// The <c>XorredBuffer</c> object takes ownership of the two byte
 | 
			
		||||
		/// arrays, i.e. the caller must not use or modify them afterwards.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbProtectedData">Protected data (XOR pad applied).</param>
 | 
			
		||||
		/// <param name="pbXorPad">XOR pad that can be used to decrypt the
 | 
			
		||||
		/// <paramref name="pbProtectedData" /> parameter.</param>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if one of the input
 | 
			
		||||
		/// parameters is <c>null</c>.</exception>
 | 
			
		||||
		/// <exception cref="System.ArgumentException">Thrown if the byte arrays are
 | 
			
		||||
		/// of different size.</exception>
 | 
			
		||||
		public XorredBuffer(byte[] pbProtectedData, byte[] pbXorPad)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbProtectedData == null) { Debug.Assert(false); throw new ArgumentNullException("pbProtectedData"); }
 | 
			
		||||
			if(pbXorPad == null) { Debug.Assert(false); throw new ArgumentNullException("pbXorPad"); }
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pbProtectedData.Length == pbXorPad.Length);
 | 
			
		||||
			if(pbProtectedData.Length != pbXorPad.Length) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			m_pbData = pbProtectedData;
 | 
			
		||||
			m_pbXorPad = pbXorPad;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get a copy of the plain-text. The caller is responsible
 | 
			
		||||
		/// for clearing the byte array safely after using it.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <returns>Unprotected plain-text byte array.</returns>
 | 
			
		||||
		public byte[] ReadPlainText()
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pbPlain = new byte[m_pbData.Length];
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < pbPlain.Length; ++i)
 | 
			
		||||
				pbPlain[i] = (byte)(m_pbData[i] ^ m_pbXorPad[i]);
 | 
			
		||||
 | 
			
		||||
			return pbPlain;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* public bool EqualsValue(XorredBuffer xb)
 | 
			
		||||
		{
 | 
			
		||||
			if(xb == null) { Debug.Assert(false); throw new ArgumentNullException("xb"); }
 | 
			
		||||
 | 
			
		||||
			if(xb.m_pbData.Length != m_pbData.Length) return false;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_pbData.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				byte bt1 = (byte)(m_pbData[i] ^ m_pbXorPad[i]);
 | 
			
		||||
				byte bt2 = (byte)(xb.m_pbData[i] ^ xb.m_pbXorPad[i]);
 | 
			
		||||
 | 
			
		||||
				if(bt1 != bt2) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool EqualsValue(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			if(pb == null) { Debug.Assert(false); throw new ArgumentNullException("pb"); }
 | 
			
		||||
 | 
			
		||||
			if(pb.Length != m_pbData.Length) return false;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_pbData.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if((byte)(m_pbData[i] ^ m_pbXorPad[i]) != pb[i]) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		} */
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										90
									
								
								src/KeePassLib2Android/Serialization/BinaryReaderEx.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/KeePassLib2Android/Serialization/BinaryReaderEx.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	public sealed class BinaryReaderEx
 | 
			
		||||
	{
 | 
			
		||||
		private Stream m_s;
 | 
			
		||||
		private Encoding m_enc;
 | 
			
		||||
 | 
			
		||||
		private string m_strReadExcp;
 | 
			
		||||
		public string ReadExceptionText
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strReadExcp; }
 | 
			
		||||
			set { m_strReadExcp = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private Stream m_sCopyTo = null;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// If this property is set to a non-null stream, all data that
 | 
			
		||||
		/// is read from the input stream is automatically written to
 | 
			
		||||
		/// the copy stream (before returning the read data).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public Stream CopyDataTo
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_sCopyTo; }
 | 
			
		||||
			set { m_sCopyTo = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public BinaryReaderEx(Stream input, Encoding encoding,
 | 
			
		||||
			string strReadExceptionText)
 | 
			
		||||
		{
 | 
			
		||||
			if(input == null) throw new ArgumentNullException("input");
 | 
			
		||||
 | 
			
		||||
			m_s = input;
 | 
			
		||||
			m_enc = encoding;
 | 
			
		||||
			m_strReadExcp = strReadExceptionText;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public byte[] ReadBytes(int nCount)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pb = MemUtil.Read(m_s, nCount);
 | 
			
		||||
				if((pb == null) || (pb.Length != nCount))
 | 
			
		||||
				{
 | 
			
		||||
					if(m_strReadExcp != null) throw new IOException(m_strReadExcp);
 | 
			
		||||
					else throw new EndOfStreamException();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if(m_sCopyTo != null) m_sCopyTo.Write(pb, 0, pb.Length);
 | 
			
		||||
				return pb;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_strReadExcp != null) throw new IOException(m_strReadExcp);
 | 
			
		||||
				else throw;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public byte ReadByte()
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = ReadBytes(1);
 | 
			
		||||
			return pb[0];
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										260
									
								
								src/KeePassLib2Android/Serialization/FileLock.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								src/KeePassLib2Android/Serialization/FileLock.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	public sealed class FileLockException : Exception
 | 
			
		||||
	{
 | 
			
		||||
		private readonly string m_strMsg;
 | 
			
		||||
 | 
			
		||||
		public override string Message
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strMsg; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public FileLockException(string strBaseFile, string strUser)
 | 
			
		||||
		{
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
			if(!string.IsNullOrEmpty(strBaseFile))
 | 
			
		||||
			{
 | 
			
		||||
				sb.Append(strBaseFile);
 | 
			
		||||
				sb.Append(MessageService.NewParagraph);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sb.Append(KLRes.FileLockedWrite);
 | 
			
		||||
			sb.Append(MessageService.NewLine);
 | 
			
		||||
 | 
			
		||||
			if(!string.IsNullOrEmpty(strUser)) sb.Append(strUser);
 | 
			
		||||
			else sb.Append("?");
 | 
			
		||||
 | 
			
		||||
			sb.Append(MessageService.NewParagraph);
 | 
			
		||||
			sb.Append(KLRes.TryAgainSecs);
 | 
			
		||||
 | 
			
		||||
			m_strMsg = sb.ToString();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class FileLock : IDisposable
 | 
			
		||||
	{
 | 
			
		||||
		private const string LockFileExt = ".lock";
 | 
			
		||||
		private const string LockFileHeader = "KeePass Lock File";
 | 
			
		||||
 | 
			
		||||
		private IOConnectionInfo m_iocLockFile;
 | 
			
		||||
 | 
			
		||||
		private sealed class LockFileInfo
 | 
			
		||||
		{
 | 
			
		||||
			public readonly string ID;
 | 
			
		||||
			public readonly DateTime Time;
 | 
			
		||||
			public readonly string UserName;
 | 
			
		||||
			public readonly string Machine;
 | 
			
		||||
			public readonly string Domain;
 | 
			
		||||
 | 
			
		||||
			private LockFileInfo(string strID, string strTime, string strUserName,
 | 
			
		||||
				string strMachine, string strDomain)
 | 
			
		||||
			{
 | 
			
		||||
				this.ID = (strID ?? string.Empty).Trim();
 | 
			
		||||
 | 
			
		||||
				DateTime dt;
 | 
			
		||||
				if(TimeUtil.TryDeserializeUtc(strTime.Trim(), out dt))
 | 
			
		||||
					this.Time = dt;
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Debug.Assert(false);
 | 
			
		||||
					this.Time = DateTime.UtcNow;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				this.UserName = (strUserName ?? string.Empty).Trim();
 | 
			
		||||
				this.Machine = (strMachine ?? string.Empty).Trim();
 | 
			
		||||
				this.Domain = (strDomain ?? string.Empty).Trim();
 | 
			
		||||
 | 
			
		||||
				if(this.Domain.Equals(this.Machine, StrUtil.CaseIgnoreCmp))
 | 
			
		||||
					this.Domain = string.Empty;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			public string GetOwner()
 | 
			
		||||
			{
 | 
			
		||||
				StringBuilder sb = new StringBuilder();
 | 
			
		||||
				sb.Append((this.UserName.Length > 0) ? this.UserName : "?");
 | 
			
		||||
 | 
			
		||||
				bool bMachine = (this.Machine.Length > 0);
 | 
			
		||||
				bool bDomain = (this.Domain.Length > 0);
 | 
			
		||||
				if(bMachine || bDomain)
 | 
			
		||||
				{
 | 
			
		||||
					sb.Append(" (");
 | 
			
		||||
					sb.Append(this.Machine);
 | 
			
		||||
					if(bMachine && bDomain) sb.Append(" @ ");
 | 
			
		||||
					sb.Append(this.Domain);
 | 
			
		||||
					sb.Append(")");
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return sb.ToString();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			public static LockFileInfo Load(IOConnectionInfo iocLockFile)
 | 
			
		||||
			{
 | 
			
		||||
				Stream s = null;
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					s = IOConnection.OpenRead(iocLockFile);
 | 
			
		||||
					if(s == null) return null;
 | 
			
		||||
					StreamReader sr = new StreamReader(s, StrUtil.Utf8);
 | 
			
		||||
					string str = sr.ReadToEnd();
 | 
			
		||||
					sr.Close();
 | 
			
		||||
					if(str == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
					str = StrUtil.NormalizeNewLines(str, false);
 | 
			
		||||
					string[] v = str.Split('\n');
 | 
			
		||||
					if((v == null) || (v.Length < 6)) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
					if(!v[0].StartsWith(LockFileHeader)) { Debug.Assert(false); return null; }
 | 
			
		||||
					return new LockFileInfo(v[1], v[2], v[3], v[4], v[5]);
 | 
			
		||||
				}
 | 
			
		||||
				catch(FileNotFoundException) { }
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
				finally { if(s != null) s.Close(); }
 | 
			
		||||
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Throws on error
 | 
			
		||||
			public static LockFileInfo Create(IOConnectionInfo iocLockFile)
 | 
			
		||||
			{
 | 
			
		||||
				LockFileInfo lfi;
 | 
			
		||||
				Stream s = null;
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					byte[] pbID = CryptoRandom.Instance.GetRandomBytes(16);
 | 
			
		||||
					string strTime = TimeUtil.SerializeUtc(DateTime.Now);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
					lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
 | 
			
		||||
						Environment.UserName, Environment.MachineName,
 | 
			
		||||
						Environment.UserDomainName);
 | 
			
		||||
#else
 | 
			
		||||
					lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
 | 
			
		||||
						string.Empty, string.Empty, string.Empty);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
					StringBuilder sb = new StringBuilder();
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
					sb.AppendLine(LockFileHeader);
 | 
			
		||||
					sb.AppendLine(lfi.ID);
 | 
			
		||||
					sb.AppendLine(strTime);
 | 
			
		||||
					sb.AppendLine(lfi.UserName);
 | 
			
		||||
					sb.AppendLine(lfi.Machine);
 | 
			
		||||
					sb.AppendLine(lfi.Domain);
 | 
			
		||||
#else
 | 
			
		||||
					sb.Append(LockFileHeader + MessageService.NewLine);
 | 
			
		||||
					sb.Append(lfi.ID + MessageService.NewLine);
 | 
			
		||||
					sb.Append(strTime + MessageService.NewLine);
 | 
			
		||||
					sb.Append(lfi.UserName + MessageService.NewLine);
 | 
			
		||||
					sb.Append(lfi.Machine + MessageService.NewLine);
 | 
			
		||||
					sb.Append(lfi.Domain + MessageService.NewLine);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
					byte[] pbFile = StrUtil.Utf8.GetBytes(sb.ToString());
 | 
			
		||||
 | 
			
		||||
					s = IOConnection.OpenWrite(iocLockFile);
 | 
			
		||||
					if(s == null) throw new IOException(iocLockFile.GetDisplayName());
 | 
			
		||||
					s.Write(pbFile, 0, pbFile.Length);
 | 
			
		||||
				}
 | 
			
		||||
				finally { if(s != null) s.Close(); }
 | 
			
		||||
 | 
			
		||||
				return lfi;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public FileLock(IOConnectionInfo iocBaseFile)
 | 
			
		||||
		{
 | 
			
		||||
			if(iocBaseFile == null) throw new ArgumentNullException("strBaseFile");
 | 
			
		||||
 | 
			
		||||
			m_iocLockFile = iocBaseFile.CloneDeep();
 | 
			
		||||
			m_iocLockFile.Path += LockFileExt;
 | 
			
		||||
 | 
			
		||||
			LockFileInfo lfiEx = LockFileInfo.Load(m_iocLockFile);
 | 
			
		||||
			if(lfiEx != null)
 | 
			
		||||
			{
 | 
			
		||||
				m_iocLockFile = null; // Otherwise Dispose deletes the existing one
 | 
			
		||||
				throw new FileLockException(iocBaseFile.GetDisplayName(),
 | 
			
		||||
					lfiEx.GetOwner());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			LockFileInfo.Create(m_iocLockFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		~FileLock()
 | 
			
		||||
		{
 | 
			
		||||
			Dispose(false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Dispose()
 | 
			
		||||
		{
 | 
			
		||||
			Dispose(true);
 | 
			
		||||
			GC.SuppressFinalize(this);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Dispose(bool bDisposing)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_iocLockFile == null) return;
 | 
			
		||||
 | 
			
		||||
			bool bFileDeleted = false;
 | 
			
		||||
			for(int r = 0; r < 5; ++r)
 | 
			
		||||
			{
 | 
			
		||||
				// if(!OwnLockFile()) { bFileDeleted = true; break; }
 | 
			
		||||
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					IOConnection.DeleteFile(m_iocLockFile);
 | 
			
		||||
					bFileDeleted = true;
 | 
			
		||||
				}
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
				if(bFileDeleted) break;
 | 
			
		||||
 | 
			
		||||
				if(bDisposing) Thread.Sleep(50);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(bDisposing && !bFileDeleted)
 | 
			
		||||
				IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception
 | 
			
		||||
 | 
			
		||||
			m_iocLockFile = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// private bool OwnLockFile()
 | 
			
		||||
		// {
 | 
			
		||||
		//	if(m_iocLockFile == null) { Debug.Assert(false); return false; }
 | 
			
		||||
		//	if(m_strLockID == null) { Debug.Assert(false); return false; }
 | 
			
		||||
		//	LockFileInfo lfi = LockFileInfo.Load(m_iocLockFile);
 | 
			
		||||
		//	if(lfi == null) return false;
 | 
			
		||||
		//	return m_strLockID.Equals(lfi.ID);
 | 
			
		||||
		// }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										144
									
								
								src/KeePassLib2Android/Serialization/FileTransactionEx.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								src/KeePassLib2Android/Serialization/FileTransactionEx.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.Security.AccessControl;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	public sealed class FileTransactionEx
 | 
			
		||||
	{
 | 
			
		||||
		private bool m_bTransacted;
 | 
			
		||||
		private IOConnectionInfo m_iocBase;
 | 
			
		||||
		private IOConnectionInfo m_iocTemp;
 | 
			
		||||
 | 
			
		||||
		private bool m_bMadeUnhidden = false;
 | 
			
		||||
 | 
			
		||||
		private const string StrTempSuffix = ".tmp";
 | 
			
		||||
 | 
			
		||||
		public FileTransactionEx(IOConnectionInfo iocBaseFile)
 | 
			
		||||
		{
 | 
			
		||||
			Initialize(iocBaseFile, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public FileTransactionEx(IOConnectionInfo iocBaseFile, bool bTransacted)
 | 
			
		||||
		{
 | 
			
		||||
			Initialize(iocBaseFile, bTransacted);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Initialize(IOConnectionInfo iocBaseFile, bool bTransacted)
 | 
			
		||||
		{
 | 
			
		||||
			if(iocBaseFile == null) throw new ArgumentNullException("iocBaseFile");
 | 
			
		||||
 | 
			
		||||
			m_bTransacted = bTransacted;
 | 
			
		||||
			m_iocBase = iocBaseFile.CloneDeep();
 | 
			
		||||
 | 
			
		||||
			if(m_bTransacted)
 | 
			
		||||
			{
 | 
			
		||||
				m_iocTemp = m_iocBase.CloneDeep();
 | 
			
		||||
				m_iocTemp.Path += StrTempSuffix;
 | 
			
		||||
			}
 | 
			
		||||
			else m_iocTemp = m_iocBase;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Stream OpenWrite()
 | 
			
		||||
		{
 | 
			
		||||
			if(!m_bTransacted) m_bMadeUnhidden = UrlUtil.UnhideFile(m_iocTemp.Path);
 | 
			
		||||
			else // m_bTransacted
 | 
			
		||||
			{
 | 
			
		||||
				try { IOConnection.DeleteFile(m_iocTemp); }
 | 
			
		||||
				catch(Exception) { }
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return IOConnection.OpenWrite(m_iocTemp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void CommitWrite()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bTransacted) CommitWriteTransaction();
 | 
			
		||||
			else // !m_bTransacted
 | 
			
		||||
			{
 | 
			
		||||
				if(m_bMadeUnhidden) UrlUtil.HideFile(m_iocTemp.Path, true); // Hide again
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void CommitWriteTransaction()
 | 
			
		||||
		{
 | 
			
		||||
			bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			FileSecurity bkSecurity = null;
 | 
			
		||||
			bool bEfsEncrypted = false;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			if(IOConnection.FileExists(m_iocBase))
 | 
			
		||||
			{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				if(m_iocBase.IsLocalFile())
 | 
			
		||||
				{
 | 
			
		||||
					try
 | 
			
		||||
					{
 | 
			
		||||
						FileAttributes faBase = File.GetAttributes(m_iocBase.Path);
 | 
			
		||||
						bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);
 | 
			
		||||
 | 
			
		||||
						DateTime tCreation = File.GetCreationTime(m_iocBase.Path);
 | 
			
		||||
						bkSecurity = File.GetAccessControl(m_iocBase.Path);
 | 
			
		||||
 | 
			
		||||
						File.SetCreationTime(m_iocTemp.Path, tCreation);
 | 
			
		||||
					}
 | 
			
		||||
					catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				IOConnection.DeleteFile(m_iocBase);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			IOConnection.RenameFile(m_iocTemp, m_iocBase);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			if(m_iocBase.IsLocalFile())
 | 
			
		||||
			{
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					if(bEfsEncrypted)
 | 
			
		||||
					{
 | 
			
		||||
						try { File.Encrypt(m_iocBase.Path); }
 | 
			
		||||
						catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if(bkSecurity != null)
 | 
			
		||||
						File.SetAccessControl(m_iocBase.Path, bkSecurity);
 | 
			
		||||
				}
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			if(bMadeUnhidden) UrlUtil.HideFile(m_iocBase.Path, true); // Hide again
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										316
									
								
								src/KeePassLib2Android/Serialization/HashedBlockStream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								src/KeePassLib2Android/Serialization/HashedBlockStream.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,316 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Native;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	public sealed class HashedBlockStream : Stream
 | 
			
		||||
	{
 | 
			
		||||
		private const int m_nDefaultBufferSize = 1024 * 1024; // 1 MB
 | 
			
		||||
 | 
			
		||||
		private Stream m_sBaseStream;
 | 
			
		||||
		private bool m_bWriting;
 | 
			
		||||
		private bool m_bVerify;
 | 
			
		||||
		private bool m_bEos = false;
 | 
			
		||||
 | 
			
		||||
		private BinaryReader m_brInput;
 | 
			
		||||
		private BinaryWriter m_bwOutput;
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbBuffer;
 | 
			
		||||
		private int m_nBufferPos = 0;
 | 
			
		||||
 | 
			
		||||
		private uint m_uBufferIndex = 0;
 | 
			
		||||
 | 
			
		||||
		public override bool CanRead
 | 
			
		||||
		{
 | 
			
		||||
			get { return !m_bWriting; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool CanSeek
 | 
			
		||||
		{
 | 
			
		||||
			get { return false; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override bool CanWrite
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bWriting; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override long Length
 | 
			
		||||
		{
 | 
			
		||||
			get { throw new NotSupportedException(); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override long Position
 | 
			
		||||
		{
 | 
			
		||||
			get { throw new NotSupportedException(); }
 | 
			
		||||
			set { throw new NotSupportedException(); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public HashedBlockStream(Stream sBaseStream, bool bWriting)
 | 
			
		||||
		{
 | 
			
		||||
			Initialize(sBaseStream, bWriting, 0, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public HashedBlockStream(Stream sBaseStream, bool bWriting, int nBufferSize)
 | 
			
		||||
		{
 | 
			
		||||
			Initialize(sBaseStream, bWriting, nBufferSize, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public HashedBlockStream(Stream sBaseStream, bool bWriting, int nBufferSize,
 | 
			
		||||
			bool bVerify)
 | 
			
		||||
		{
 | 
			
		||||
			Initialize(sBaseStream, bWriting, nBufferSize, bVerify);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void Initialize(Stream sBaseStream, bool bWriting, int nBufferSize,
 | 
			
		||||
			bool bVerify)
 | 
			
		||||
		{
 | 
			
		||||
			if(sBaseStream == null) throw new ArgumentNullException("sBaseStream");
 | 
			
		||||
			if(nBufferSize < 0) throw new ArgumentOutOfRangeException("nBufferSize");
 | 
			
		||||
 | 
			
		||||
			if(nBufferSize == 0) nBufferSize = m_nDefaultBufferSize;
 | 
			
		||||
 | 
			
		||||
			m_sBaseStream = sBaseStream;
 | 
			
		||||
			m_bWriting = bWriting;
 | 
			
		||||
			m_bVerify = bVerify;
 | 
			
		||||
 | 
			
		||||
			UTF8Encoding utf8 = StrUtil.Utf8;
 | 
			
		||||
			if(m_bWriting == false) // Reading mode
 | 
			
		||||
			{
 | 
			
		||||
				if(m_sBaseStream.CanRead == false)
 | 
			
		||||
					throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
				m_brInput = new BinaryReader(sBaseStream, utf8);
 | 
			
		||||
 | 
			
		||||
				m_pbBuffer = new byte[0];
 | 
			
		||||
			}
 | 
			
		||||
			else // Writing mode
 | 
			
		||||
			{
 | 
			
		||||
				if(m_sBaseStream.CanWrite == false)
 | 
			
		||||
					throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
				m_bwOutput = new BinaryWriter(sBaseStream, utf8);
 | 
			
		||||
 | 
			
		||||
				m_pbBuffer = new byte[nBufferSize];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Flush()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bWriting) m_bwOutput.Flush();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Close()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_sBaseStream != null)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_bWriting == false) // Reading mode
 | 
			
		||||
				{
 | 
			
		||||
					m_brInput.Close();
 | 
			
		||||
					m_brInput = null;
 | 
			
		||||
				}
 | 
			
		||||
				else // Writing mode
 | 
			
		||||
				{
 | 
			
		||||
					if(m_nBufferPos == 0) // No data left in buffer
 | 
			
		||||
						WriteHashedBlock(); // Write terminating block
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						WriteHashedBlock(); // Write remaining buffered data
 | 
			
		||||
						WriteHashedBlock(); // Write terminating block
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					Flush();
 | 
			
		||||
					m_bwOutput.Close();
 | 
			
		||||
					m_bwOutput = null;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				m_sBaseStream.Close();
 | 
			
		||||
				m_sBaseStream = null;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override long Seek(long lOffset, SeekOrigin soOrigin)
 | 
			
		||||
		{
 | 
			
		||||
			throw new NotSupportedException();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void SetLength(long lValue)
 | 
			
		||||
		{
 | 
			
		||||
			throw new NotSupportedException();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override int Read(byte[] pbBuffer, int nOffset, int nCount)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bWriting) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			int nRemaining = nCount;
 | 
			
		||||
			while(nRemaining > 0)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_nBufferPos == m_pbBuffer.Length)
 | 
			
		||||
				{
 | 
			
		||||
					if(ReadHashedBlock() == false)
 | 
			
		||||
						return nCount - nRemaining; // Bytes actually read
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				int nCopy = Math.Min(m_pbBuffer.Length - m_nBufferPos, nRemaining);
 | 
			
		||||
 | 
			
		||||
				Array.Copy(m_pbBuffer, m_nBufferPos, pbBuffer, nOffset, nCopy);
 | 
			
		||||
 | 
			
		||||
				nOffset += nCopy;
 | 
			
		||||
				m_nBufferPos += nCopy;
 | 
			
		||||
 | 
			
		||||
				nRemaining -= nCopy;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return nCount;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool ReadHashedBlock()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_bEos) return false; // End of stream reached already
 | 
			
		||||
 | 
			
		||||
			m_nBufferPos = 0;
 | 
			
		||||
 | 
			
		||||
			if(m_brInput.ReadUInt32() != m_uBufferIndex)
 | 
			
		||||
				throw new InvalidDataException();
 | 
			
		||||
			++m_uBufferIndex;
 | 
			
		||||
 | 
			
		||||
			byte[] pbStoredHash = m_brInput.ReadBytes(32);
 | 
			
		||||
			if((pbStoredHash == null) || (pbStoredHash.Length != 32))
 | 
			
		||||
				throw new InvalidDataException();
 | 
			
		||||
 | 
			
		||||
			int nBufferSize = 0;
 | 
			
		||||
			try { nBufferSize = m_brInput.ReadInt32(); }
 | 
			
		||||
			catch(NullReferenceException) // Mono bug workaround (LaunchPad 783268)
 | 
			
		||||
			{
 | 
			
		||||
				if(!NativeLib.IsUnix()) throw;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(nBufferSize < 0)
 | 
			
		||||
				throw new InvalidDataException();
 | 
			
		||||
 | 
			
		||||
			if(nBufferSize == 0)
 | 
			
		||||
			{
 | 
			
		||||
				for(int iHash = 0; iHash < 32; ++iHash)
 | 
			
		||||
				{
 | 
			
		||||
					if(pbStoredHash[iHash] != 0)
 | 
			
		||||
						throw new InvalidDataException();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				m_bEos = true;
 | 
			
		||||
				m_pbBuffer = new byte[0];
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_pbBuffer = m_brInput.ReadBytes(nBufferSize);
 | 
			
		||||
			if((m_pbBuffer == null) || ((m_pbBuffer.Length != nBufferSize) && m_bVerify))
 | 
			
		||||
				throw new InvalidDataException();
 | 
			
		||||
 | 
			
		||||
			if(m_bVerify)
 | 
			
		||||
			{
 | 
			
		||||
				SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
				byte[] pbComputedHash = sha256.ComputeHash(m_pbBuffer);
 | 
			
		||||
				if((pbComputedHash == null) || (pbComputedHash.Length != 32))
 | 
			
		||||
					throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
				for(int iHashPos = 0; iHashPos < 32; ++iHashPos)
 | 
			
		||||
				{
 | 
			
		||||
					if(pbStoredHash[iHashPos] != pbComputedHash[iHashPos])
 | 
			
		||||
						throw new InvalidDataException();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override void Write(byte[] pbBuffer, int nOffset, int nCount)
 | 
			
		||||
		{
 | 
			
		||||
			if(!m_bWriting) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			while(nCount > 0)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_nBufferPos == m_pbBuffer.Length)
 | 
			
		||||
					WriteHashedBlock();
 | 
			
		||||
 | 
			
		||||
				int nCopy = Math.Min(m_pbBuffer.Length - m_nBufferPos, nCount);
 | 
			
		||||
 | 
			
		||||
				Array.Copy(pbBuffer, nOffset, m_pbBuffer, m_nBufferPos, nCopy);
 | 
			
		||||
 | 
			
		||||
				nOffset += nCopy;
 | 
			
		||||
				m_nBufferPos += nCopy;
 | 
			
		||||
 | 
			
		||||
				nCount -= nCopy;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteHashedBlock()
 | 
			
		||||
		{
 | 
			
		||||
			m_bwOutput.Write(m_uBufferIndex);
 | 
			
		||||
			++m_uBufferIndex;
 | 
			
		||||
 | 
			
		||||
			if(m_nBufferPos > 0)
 | 
			
		||||
			{
 | 
			
		||||
				SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				byte[] pbHash = sha256.ComputeHash(m_pbBuffer, 0, m_nBufferPos);
 | 
			
		||||
#else
 | 
			
		||||
				byte[] pbHash;
 | 
			
		||||
				if(m_nBufferPos == m_pbBuffer.Length)
 | 
			
		||||
					pbHash = sha256.ComputeHash(m_pbBuffer);
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					byte[] pbData = new byte[m_nBufferPos];
 | 
			
		||||
					Array.Copy(m_pbBuffer, 0, pbData, 0, m_nBufferPos);
 | 
			
		||||
					pbHash = sha256.ComputeHash(pbData);
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				m_bwOutput.Write(pbHash);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				m_bwOutput.Write((ulong)0); // Zero hash
 | 
			
		||||
				m_bwOutput.Write((ulong)0);
 | 
			
		||||
				m_bwOutput.Write((ulong)0);
 | 
			
		||||
				m_bwOutput.Write((ulong)0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_bwOutput.Write(m_nBufferPos);
 | 
			
		||||
			
 | 
			
		||||
			if(m_nBufferPos > 0)
 | 
			
		||||
				m_bwOutput.Write(m_pbBuffer, 0, m_nBufferPos);
 | 
			
		||||
 | 
			
		||||
			m_nBufferPos = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										453
									
								
								src/KeePassLib2Android/Serialization/IOConnection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										453
									
								
								src/KeePassLib2Android/Serialization/IOConnection.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,453 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Security.Cryptography.X509Certificates;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.Net.Cache;
 | 
			
		||||
using System.Net.Security;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Native;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
	public sealed class IOWebClient : WebClient
 | 
			
		||||
	{
 | 
			
		||||
		protected override WebRequest GetWebRequest(Uri address)
 | 
			
		||||
		{
 | 
			
		||||
			WebRequest request = base.GetWebRequest(address);
 | 
			
		||||
			IOConnection.ConfigureWebRequest(request);
 | 
			
		||||
			return request;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	public static class IOConnection
 | 
			
		||||
	{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		private static ProxyServerType m_pstProxyType = ProxyServerType.System;
 | 
			
		||||
		private static string m_strProxyAddr = string.Empty;
 | 
			
		||||
		private static string m_strProxyPort = string.Empty;
 | 
			
		||||
		private static string m_strProxyUserName = string.Empty;
 | 
			
		||||
		private static string m_strProxyPassword = string.Empty;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		// Web request methods
 | 
			
		||||
		public const string WrmDeleteFile = "DELETEFILE";
 | 
			
		||||
		public const string WrmMoveFile = "MOVEFILE";
 | 
			
		||||
 | 
			
		||||
		// Web request headers
 | 
			
		||||
		public const string WrhMoveFileTo = "MoveFileTo";
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		// Allow self-signed certificates, expired certificates, etc.
 | 
			
		||||
		private static bool ValidateServerCertificate(object sender,
 | 
			
		||||
			X509Certificate certificate, X509Chain chain,
 | 
			
		||||
			SslPolicyErrors sslPolicyErrors)
 | 
			
		||||
		{
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void SetProxy(ProxyServerType pst, string strAddr,
 | 
			
		||||
			string strPort, string strUserName, string strPassword)
 | 
			
		||||
		{
 | 
			
		||||
			m_pstProxyType = pst;
 | 
			
		||||
			m_strProxyAddr = (strAddr ?? string.Empty);
 | 
			
		||||
			m_strProxyPort = (strPort ?? string.Empty);
 | 
			
		||||
			m_strProxyUserName = (strUserName ?? string.Empty);
 | 
			
		||||
			m_strProxyPassword = (strPassword ?? string.Empty);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static void ConfigureWebRequest(WebRequest request)
 | 
			
		||||
		{
 | 
			
		||||
			if(request == null) { Debug.Assert(false); return; } // No throw
 | 
			
		||||
 | 
			
		||||
			// WebDAV support
 | 
			
		||||
			if(request is HttpWebRequest)
 | 
			
		||||
			{
 | 
			
		||||
				request.PreAuthenticate = true; // Also auth GET
 | 
			
		||||
				if(request.Method == WebRequestMethods.Http.Post)
 | 
			
		||||
					request.Method = WebRequestMethods.Http.Put;
 | 
			
		||||
			}
 | 
			
		||||
			// else if(request is FtpWebRequest)
 | 
			
		||||
			// {
 | 
			
		||||
			//	Debug.Assert(((FtpWebRequest)request).UsePassive);
 | 
			
		||||
			// }
 | 
			
		||||
 | 
			
		||||
			// Not implemented and ignored in Mono < 2.10
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
 | 
			
		||||
			}
 | 
			
		||||
			catch(NotImplementedException) { }
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				IWebProxy prx;
 | 
			
		||||
				if(GetWebProxy(out prx)) request.Proxy = prx;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static void ConfigureWebClient(WebClient wc)
 | 
			
		||||
		{
 | 
			
		||||
			// Not implemented and ignored in Mono < 2.10
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
 | 
			
		||||
			}
 | 
			
		||||
			catch(NotImplementedException) { }
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				IWebProxy prx;
 | 
			
		||||
				if(GetWebProxy(out prx)) wc.Proxy = prx;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static bool GetWebProxy(out IWebProxy prx)
 | 
			
		||||
		{
 | 
			
		||||
			prx = null;
 | 
			
		||||
 | 
			
		||||
			if(m_pstProxyType == ProxyServerType.None)
 | 
			
		||||
				return true; // Use null proxy
 | 
			
		||||
			if(m_pstProxyType == ProxyServerType.Manual)
 | 
			
		||||
			{
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					if(m_strProxyPort.Length > 0)
 | 
			
		||||
						prx = new WebProxy(m_strProxyAddr, int.Parse(m_strProxyPort));
 | 
			
		||||
					else prx = new WebProxy(m_strProxyAddr);
 | 
			
		||||
 | 
			
		||||
					if((m_strProxyUserName.Length > 0) || (m_strProxyPassword.Length > 0))
 | 
			
		||||
						prx.Credentials = new NetworkCredential(m_strProxyUserName,
 | 
			
		||||
							m_strProxyPassword);
 | 
			
		||||
 | 
			
		||||
					return true; // Use manual proxy
 | 
			
		||||
				}
 | 
			
		||||
				catch(Exception exProxy)
 | 
			
		||||
				{
 | 
			
		||||
					string strInfo = m_strProxyAddr;
 | 
			
		||||
					if(m_strProxyPort.Length > 0) strInfo += ":" + m_strProxyPort;
 | 
			
		||||
					MessageService.ShowWarning(strInfo, exProxy.Message);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return false; // Use default
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if((m_strProxyUserName.Length == 0) && (m_strProxyPassword.Length == 0))
 | 
			
		||||
				return false; // Use default proxy, no auth
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				prx = WebRequest.DefaultWebProxy;
 | 
			
		||||
				if(prx == null) prx = WebRequest.GetSystemWebProxy();
 | 
			
		||||
				if(prx == null) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
				prx.Credentials = new NetworkCredential(m_strProxyUserName,
 | 
			
		||||
					m_strProxyPassword);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void PrepareWebAccess()
 | 
			
		||||
		{
 | 
			
		||||
			ServicePointManager.ServerCertificateValidationCallback =
 | 
			
		||||
				ValidateServerCertificate;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static IOWebClient CreateWebClient(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			PrepareWebAccess();
 | 
			
		||||
 | 
			
		||||
			IOWebClient wc = new IOWebClient();
 | 
			
		||||
			ConfigureWebClient(wc);
 | 
			
		||||
 | 
			
		||||
			if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
 | 
			
		||||
				wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
 | 
			
		||||
			else if(NativeLib.IsUnix()) // Mono requires credentials
 | 
			
		||||
				wc.Credentials = new NetworkCredential("anonymous", string.Empty);
 | 
			
		||||
 | 
			
		||||
			return wc;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static WebRequest CreateWebRequest(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			PrepareWebAccess();
 | 
			
		||||
 | 
			
		||||
			WebRequest req = WebRequest.Create(ioc.Path);
 | 
			
		||||
			ConfigureWebRequest(req);
 | 
			
		||||
 | 
			
		||||
			if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
 | 
			
		||||
				req.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
 | 
			
		||||
			else if(NativeLib.IsUnix()) // Mono requires credentials
 | 
			
		||||
				req.Credentials = new NetworkCredential("anonymous", string.Empty);
 | 
			
		||||
 | 
			
		||||
			return req;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Stream OpenRead(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			if(StrUtil.IsDataUri(ioc.Path))
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbData = StrUtil.DataUriToData(ioc.Path);
 | 
			
		||||
				if(pbData != null) return new MemoryStream(pbData, false);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(ioc.IsLocalFile()) return OpenReadLocal(ioc);
 | 
			
		||||
 | 
			
		||||
			return CreateWebClient(ioc).OpenRead(new Uri(ioc.Path));
 | 
			
		||||
		}
 | 
			
		||||
#else
 | 
			
		||||
		public static Stream OpenRead(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			return OpenReadLocal(ioc);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		private static Stream OpenReadLocal(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read,
 | 
			
		||||
				FileShare.Read);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		public static Stream OpenWrite(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			if(ioc == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			if(ioc.IsLocalFile()) return OpenWriteLocal(ioc);
 | 
			
		||||
 | 
			
		||||
			Uri uri = new Uri(ioc.Path);
 | 
			
		||||
 | 
			
		||||
			// Mono does not set HttpWebRequest.Method to POST for writes,
 | 
			
		||||
			// so one needs to set the method to PUT explicitly
 | 
			
		||||
			if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp,
 | 
			
		||||
				StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps,
 | 
			
		||||
				StrUtil.CaseIgnoreCmp)))
 | 
			
		||||
				return CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put);
 | 
			
		||||
 | 
			
		||||
			return CreateWebClient(ioc).OpenWrite(uri);
 | 
			
		||||
		}
 | 
			
		||||
#else
 | 
			
		||||
		public static Stream OpenWrite(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			return OpenWriteLocal(ioc);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		private static Stream OpenWriteLocal(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write,
 | 
			
		||||
				FileShare.None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool FileExists(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			return FileExists(ioc, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool FileExists(IOConnectionInfo ioc, bool bThrowErrors)
 | 
			
		||||
		{
 | 
			
		||||
			if(ioc == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			if(ioc.IsLocalFile()) return File.Exists(ioc.Path);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			if(ioc.Path.StartsWith("ftp://", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
			{
 | 
			
		||||
				bool b = SendCommand(ioc, WebRequestMethods.Ftp.GetDateTimestamp);
 | 
			
		||||
				if(!b && bThrowErrors) throw new InvalidOperationException();
 | 
			
		||||
				return b;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				Stream s = OpenRead(ioc);
 | 
			
		||||
				if(s == null) throw new FileNotFoundException();
 | 
			
		||||
 | 
			
		||||
				try { s.ReadByte(); }
 | 
			
		||||
				catch(Exception) { }
 | 
			
		||||
 | 
			
		||||
				// We didn't download the file completely; close may throw
 | 
			
		||||
				// an exception -- that's okay
 | 
			
		||||
				try { s.Close(); }
 | 
			
		||||
				catch(Exception) { }
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception)
 | 
			
		||||
			{
 | 
			
		||||
				if(bThrowErrors) throw;
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void DeleteFile(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			WebRequest req = CreateWebRequest(ioc);
 | 
			
		||||
			if(req != null)
 | 
			
		||||
			{
 | 
			
		||||
				if(req is HttpWebRequest) req.Method = "DELETE";
 | 
			
		||||
				else if(req is FtpWebRequest) req.Method = WebRequestMethods.Ftp.DeleteFile;
 | 
			
		||||
				else if(req is FileWebRequest)
 | 
			
		||||
				{
 | 
			
		||||
					File.Delete(UrlUtil.FileUrlToPath(ioc.Path));
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				else req.Method = WrmDeleteFile;
 | 
			
		||||
 | 
			
		||||
				DisposeResponse(req.GetResponse(), true);
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Rename/move a file. For local file system and WebDAV, the
 | 
			
		||||
		/// specified file is moved, i.e. the file destination can be
 | 
			
		||||
		/// in a different directory/path. In contrast, for FTP the
 | 
			
		||||
		/// file is renamed, i.e. its destination must be in the same
 | 
			
		||||
		/// directory/path.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="iocFrom">Source file path.</param>
 | 
			
		||||
		/// <param name="iocTo">Target file path.</param>
 | 
			
		||||
		public static void RenameFile(IOConnectionInfo iocFrom, IOConnectionInfo iocTo)
 | 
			
		||||
		{
 | 
			
		||||
			if(iocFrom.IsLocalFile()) { File.Move(iocFrom.Path, iocTo.Path); return; }
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			WebRequest req = CreateWebRequest(iocFrom);
 | 
			
		||||
			if(req != null)
 | 
			
		||||
			{
 | 
			
		||||
				if(req is HttpWebRequest)
 | 
			
		||||
				{
 | 
			
		||||
					req.Method = "MOVE";
 | 
			
		||||
					req.Headers.Set("Destination", iocTo.Path); // Full URL supported
 | 
			
		||||
				}
 | 
			
		||||
				else if(req is FtpWebRequest)
 | 
			
		||||
				{
 | 
			
		||||
					req.Method = WebRequestMethods.Ftp.Rename;
 | 
			
		||||
					((FtpWebRequest)req).RenameTo = UrlUtil.GetFileName(iocTo.Path);
 | 
			
		||||
				}
 | 
			
		||||
				else if(req is FileWebRequest)
 | 
			
		||||
				{
 | 
			
		||||
					File.Move(UrlUtil.FileUrlToPath(iocFrom.Path),
 | 
			
		||||
						UrlUtil.FileUrlToPath(iocTo.Path));
 | 
			
		||||
					return;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					req.Method = WrmMoveFile;
 | 
			
		||||
					req.Headers.Set(WrhMoveFileTo, iocTo.Path);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				DisposeResponse(req.GetResponse(), true);
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			// using(Stream sIn = IOConnection.OpenRead(iocFrom))
 | 
			
		||||
			// {
 | 
			
		||||
			//	using(Stream sOut = IOConnection.OpenWrite(iocTo))
 | 
			
		||||
			//	{
 | 
			
		||||
			//		MemUtil.CopyStream(sIn, sOut);
 | 
			
		||||
			//		sOut.Close();
 | 
			
		||||
			//	}
 | 
			
		||||
			//
 | 
			
		||||
			//	sIn.Close();
 | 
			
		||||
			// }
 | 
			
		||||
			// DeleteFile(iocFrom);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		private static bool SendCommand(IOConnectionInfo ioc, string strMethod)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				WebRequest req = CreateWebRequest(ioc);
 | 
			
		||||
				req.Method = strMethod;
 | 
			
		||||
				DisposeResponse(req.GetResponse(), true);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { return false; }
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		private static void DisposeResponse(WebResponse wr, bool bGetStream)
 | 
			
		||||
		{
 | 
			
		||||
			if(wr == null) return;
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if(bGetStream)
 | 
			
		||||
				{
 | 
			
		||||
					Stream s = wr.GetResponseStream();
 | 
			
		||||
					if(s != null) s.Close();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			try { wr.Close(); }
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static byte[] ReadFile(IOConnectionInfo ioc)
 | 
			
		||||
		{
 | 
			
		||||
			Stream sIn = null;
 | 
			
		||||
			MemoryStream ms = null;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				sIn = IOConnection.OpenRead(ioc);
 | 
			
		||||
				if(sIn == null) return null;
 | 
			
		||||
 | 
			
		||||
				ms = new MemoryStream();
 | 
			
		||||
				MemUtil.CopyStream(sIn, ms);
 | 
			
		||||
 | 
			
		||||
				return ms.ToArray();
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
			finally
 | 
			
		||||
			{
 | 
			
		||||
				if(sIn != null) sIn.Close();
 | 
			
		||||
				if(ms != null) ms.Close();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										342
									
								
								src/KeePassLib2Android/Serialization/IOConnectionInfo.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								src/KeePassLib2Android/Serialization/IOConnectionInfo.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,342 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	public enum IOCredSaveMode
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Do not remember user name or password.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		NoSave = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Remember the user name only, not the password.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		UserNameOnly,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Save both user name and password.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		SaveCred
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public enum IOCredProtMode
 | 
			
		||||
	{
 | 
			
		||||
		None = 0,
 | 
			
		||||
		Obf
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* public enum IOFileFormatHint
 | 
			
		||||
	{
 | 
			
		||||
		None = 0,
 | 
			
		||||
		Deprecated
 | 
			
		||||
	} */
 | 
			
		||||
 | 
			
		||||
	public sealed class IOConnectionInfo : IDeepCloneable<IOConnectionInfo>
 | 
			
		||||
	{
 | 
			
		||||
		// private IOFileFormatHint m_ioHint = IOFileFormatHint.None;
 | 
			
		||||
 | 
			
		||||
		private string m_strUrl = string.Empty;
 | 
			
		||||
		public string Path
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strUrl; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null);
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_strUrl = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strUser = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string UserName
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strUser; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null);
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_strUser = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strPassword = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Password
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strPassword; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(value != null);
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_strPassword = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private IOCredProtMode m_ioCredProtMode = IOCredProtMode.None;
 | 
			
		||||
		public IOCredProtMode CredProtMode
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_ioCredProtMode; }
 | 
			
		||||
			set { m_ioCredProtMode = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private IOCredSaveMode m_ioCredSaveMode = IOCredSaveMode.NoSave;
 | 
			
		||||
		public IOCredSaveMode CredSaveMode
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_ioCredSaveMode; }
 | 
			
		||||
			set { m_ioCredSaveMode = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* public IOFileFormatHint FileFormatHint
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_ioHint; }
 | 
			
		||||
			set { m_ioHint = value; }
 | 
			
		||||
		} */
 | 
			
		||||
 | 
			
		||||
		public IOConnectionInfo CloneDeep()
 | 
			
		||||
		{
 | 
			
		||||
			return (IOConnectionInfo)this.MemberwiseClone();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Serialize the current connection info to a string. Credentials
 | 
			
		||||
		/// are only serialized if the <c>SaveCredentials</c> property
 | 
			
		||||
		/// is <c>true</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="iocToCompile">Input object to be serialized.</param>
 | 
			
		||||
		/// <returns>Serialized object as string.</returns>
 | 
			
		||||
		public static string SerializeToString(IOConnectionInfo iocToCompile)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(iocToCompile != null);
 | 
			
		||||
			if(iocToCompile == null) throw new ArgumentNullException("iocToCompile");
 | 
			
		||||
 | 
			
		||||
			string strUrl = iocToCompile.Path;
 | 
			
		||||
			string strUser = TransformUnreadable(iocToCompile.UserName, true);
 | 
			
		||||
			string strPassword = TransformUnreadable(iocToCompile.Password, true);
 | 
			
		||||
			string strAll = strUrl + strUser + strPassword;
 | 
			
		||||
			char chSep = char.MinValue;
 | 
			
		||||
 | 
			
		||||
			char[] vPrefSeps = new char[]{ '@', '#', '!', '$', '*' };
 | 
			
		||||
			foreach(char ch in vPrefSeps)
 | 
			
		||||
			{
 | 
			
		||||
				if(strAll.IndexOf(ch) < 0)
 | 
			
		||||
				{
 | 
			
		||||
					chSep = ch;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(chSep == char.MinValue)
 | 
			
		||||
			{
 | 
			
		||||
				for(char chEnum = '!'; chEnum < char.MaxValue; ++chEnum)
 | 
			
		||||
				{
 | 
			
		||||
					if(strAll.IndexOf(chEnum) < 0)
 | 
			
		||||
					{
 | 
			
		||||
						chSep = chEnum;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(chSep == char.MinValue) throw new FormatException();
 | 
			
		||||
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
			sb.Append(chSep);
 | 
			
		||||
			sb.Append(strUrl);
 | 
			
		||||
			sb.Append(chSep);
 | 
			
		||||
 | 
			
		||||
			if(iocToCompile.CredSaveMode == IOCredSaveMode.SaveCred)
 | 
			
		||||
			{
 | 
			
		||||
				sb.Append('C');
 | 
			
		||||
				sb.Append(chSep);
 | 
			
		||||
				sb.Append(strUser);
 | 
			
		||||
				sb.Append(chSep);
 | 
			
		||||
				sb.Append(strPassword);
 | 
			
		||||
			}
 | 
			
		||||
			else if(iocToCompile.CredSaveMode == IOCredSaveMode.UserNameOnly)
 | 
			
		||||
			{
 | 
			
		||||
				sb.Append('U');
 | 
			
		||||
				sb.Append(chSep);
 | 
			
		||||
				sb.Append(strUser);
 | 
			
		||||
				sb.Append(chSep);
 | 
			
		||||
			}
 | 
			
		||||
			else // Don't remember credentials
 | 
			
		||||
			{
 | 
			
		||||
				sb.Append('N');
 | 
			
		||||
				sb.Append(chSep);
 | 
			
		||||
				sb.Append(chSep);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return sb.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static IOConnectionInfo UnserializeFromString(string strToDecompile)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strToDecompile != null);
 | 
			
		||||
			if(strToDecompile == null) throw new ArgumentNullException("strToDecompile");
 | 
			
		||||
			if(strToDecompile.Length <= 1) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			char chSep = strToDecompile[0];
 | 
			
		||||
			string[] vParts = strToDecompile.Substring(1, strToDecompile.Length -
 | 
			
		||||
				1).Split(new char[]{ chSep });
 | 
			
		||||
			if(vParts.Length < 4) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			IOConnectionInfo s = new IOConnectionInfo();
 | 
			
		||||
			s.Path = vParts[0];
 | 
			
		||||
 | 
			
		||||
			if(vParts[1] == "C")
 | 
			
		||||
				s.CredSaveMode = IOCredSaveMode.SaveCred;
 | 
			
		||||
			else if(vParts[1] == "U")
 | 
			
		||||
				s.CredSaveMode = IOCredSaveMode.UserNameOnly;
 | 
			
		||||
			else
 | 
			
		||||
				s.CredSaveMode = IOCredSaveMode.NoSave;
 | 
			
		||||
 | 
			
		||||
			s.UserName = TransformUnreadable(vParts[2], false);
 | 
			
		||||
			s.Password = TransformUnreadable(vParts[3], false);
 | 
			
		||||
			return s;
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Very simple string protection. Doesn't really encrypt the input
 | 
			
		||||
		/// string, only encodes it that it's not readable on the first glance.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strToEncode">The string to encode/decode.</param>
 | 
			
		||||
		/// <param name="bEncode">If <c>true</c>, the string will be encoded,
 | 
			
		||||
		/// otherwise it'll be decoded.</param>
 | 
			
		||||
		/// <returns>Encoded/decoded string.</returns>
 | 
			
		||||
		private static string TransformUnreadable(string strToEncode, bool bEncode)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strToEncode != null);
 | 
			
		||||
			if(strToEncode == null) throw new ArgumentNullException("strToEncode");
 | 
			
		||||
 | 
			
		||||
			if(bEncode)
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strToEncode);
 | 
			
		||||
 | 
			
		||||
				unchecked
 | 
			
		||||
				{
 | 
			
		||||
					for(int iPos = 0; iPos < pbUtf8.Length; ++iPos)
 | 
			
		||||
						pbUtf8[iPos] += (byte)(iPos * 11);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return Convert.ToBase64String(pbUtf8);
 | 
			
		||||
			}
 | 
			
		||||
			else // Decode
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbBase = Convert.FromBase64String(strToEncode);
 | 
			
		||||
 | 
			
		||||
				unchecked
 | 
			
		||||
				{
 | 
			
		||||
					for(int iPos = 0; iPos < pbBase.Length; ++iPos)
 | 
			
		||||
						pbBase[iPos] -= (byte)(iPos * 11);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return StrUtil.Utf8.GetString(pbBase, 0, pbBase.Length);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
		public string GetDisplayName()
 | 
			
		||||
		{
 | 
			
		||||
			string str = m_strUrl;
 | 
			
		||||
 | 
			
		||||
			if(m_strUser.Length > 0)
 | 
			
		||||
				str += " (" + m_strUser + ")";
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool IsEmpty()
 | 
			
		||||
		{
 | 
			
		||||
			return (m_strUrl.Length > 0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static IOConnectionInfo FromPath(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			IOConnectionInfo ioc = new IOConnectionInfo();
 | 
			
		||||
 | 
			
		||||
			ioc.Path = strPath;
 | 
			
		||||
			ioc.CredSaveMode = IOCredSaveMode.NoSave;
 | 
			
		||||
 | 
			
		||||
			return ioc;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool CanProbablyAccess()
 | 
			
		||||
		{
 | 
			
		||||
			if(IsLocalFile()) return File.Exists(m_strUrl);
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool IsLocalFile()
 | 
			
		||||
		{
 | 
			
		||||
			// Not just ":/", see e.g. AppConfigEx.ChangePathRelAbs
 | 
			
		||||
			return (m_strUrl.IndexOf(@"://") < 0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void ClearCredentials(bool bDependingOnRememberMode)
 | 
			
		||||
		{
 | 
			
		||||
			if((bDependingOnRememberMode == false) ||
 | 
			
		||||
				(m_ioCredSaveMode == IOCredSaveMode.NoSave))
 | 
			
		||||
			{
 | 
			
		||||
				m_strUser = string.Empty;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if((bDependingOnRememberMode == false) ||
 | 
			
		||||
				(m_ioCredSaveMode == IOCredSaveMode.NoSave) ||
 | 
			
		||||
				(m_ioCredSaveMode == IOCredSaveMode.UserNameOnly))
 | 
			
		||||
			{
 | 
			
		||||
				m_strPassword = string.Empty;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void Obfuscate(bool bObf)
 | 
			
		||||
		{
 | 
			
		||||
			if(bObf && (m_ioCredProtMode == IOCredProtMode.None))
 | 
			
		||||
			{
 | 
			
		||||
				m_strPassword = StrUtil.Obfuscate(m_strPassword);
 | 
			
		||||
				m_ioCredProtMode = IOCredProtMode.Obf;
 | 
			
		||||
			}
 | 
			
		||||
			else if(!bObf && (m_ioCredProtMode == IOCredProtMode.Obf))
 | 
			
		||||
			{
 | 
			
		||||
				m_strPassword = StrUtil.Deobfuscate(m_strPassword);
 | 
			
		||||
				m_ioCredProtMode = IOCredProtMode.None;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										877
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.Read.Streamed.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										877
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.Read.Streamed.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,877 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib;
 | 
			
		||||
using KeePassLib.Collections;
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Cryptography.Cipher;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Serialization to KeePass KDBX files.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed partial class KdbxFile
 | 
			
		||||
	{
 | 
			
		||||
		private enum KdbContext
 | 
			
		||||
		{
 | 
			
		||||
			Null,
 | 
			
		||||
			KeePassFile,
 | 
			
		||||
			Meta,
 | 
			
		||||
			Root,
 | 
			
		||||
			MemoryProtection,
 | 
			
		||||
			CustomIcons,
 | 
			
		||||
			CustomIcon,
 | 
			
		||||
			Binaries,
 | 
			
		||||
			CustomData,
 | 
			
		||||
			CustomDataItem,
 | 
			
		||||
			RootDeletedObjects,
 | 
			
		||||
			DeletedObject,
 | 
			
		||||
			Group,
 | 
			
		||||
			GroupTimes,
 | 
			
		||||
			Entry,
 | 
			
		||||
			EntryTimes,
 | 
			
		||||
			EntryString,
 | 
			
		||||
			EntryBinary,
 | 
			
		||||
			EntryAutoType,
 | 
			
		||||
			EntryAutoTypeItem,
 | 
			
		||||
			EntryHistory
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bReadNextNode = true;
 | 
			
		||||
		private Stack<PwGroup> m_ctxGroups = new Stack<PwGroup>();
 | 
			
		||||
		private PwGroup m_ctxGroup = null;
 | 
			
		||||
		private PwEntry m_ctxEntry = null;
 | 
			
		||||
		private string m_ctxStringName = null;
 | 
			
		||||
		private ProtectedString m_ctxStringValue = null;
 | 
			
		||||
		private string m_ctxBinaryName = null;
 | 
			
		||||
		private ProtectedBinary m_ctxBinaryValue = null;
 | 
			
		||||
		private string m_ctxATName = null;
 | 
			
		||||
		private string m_ctxATSeq = null;
 | 
			
		||||
		private bool m_bEntryInHistory = false;
 | 
			
		||||
		private PwEntry m_ctxHistoryBase = null;
 | 
			
		||||
		private PwDeletedObject m_ctxDeletedObject = null;
 | 
			
		||||
		private PwUuid m_uuidCustomIconID = PwUuid.Zero;
 | 
			
		||||
		private byte[] m_pbCustomIconData = null;
 | 
			
		||||
		private string m_strCustomDataKey = null;
 | 
			
		||||
		private string m_strCustomDataValue = null;
 | 
			
		||||
 | 
			
		||||
		private void ReadXmlStreamed(Stream readerStream, Stream sParentStream)
 | 
			
		||||
		{
 | 
			
		||||
			ReadDocumentStreamed(CreateXmlReader(readerStream), sParentStream);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static XmlReaderSettings CreateStdXmlReaderSettings()
 | 
			
		||||
		{
 | 
			
		||||
			XmlReaderSettings xrs = new XmlReaderSettings();
 | 
			
		||||
 | 
			
		||||
			xrs.CloseInput = true;
 | 
			
		||||
			xrs.IgnoreComments = true;
 | 
			
		||||
			xrs.IgnoreProcessingInstructions = true;
 | 
			
		||||
			xrs.IgnoreWhitespace = true;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			xrs.ProhibitDtd = true;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			xrs.ValidationType = ValidationType.None;
 | 
			
		||||
 | 
			
		||||
			return xrs;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static XmlReader CreateXmlReader(Stream readerStream)
 | 
			
		||||
		{
 | 
			
		||||
			XmlReaderSettings xrs = CreateStdXmlReaderSettings();
 | 
			
		||||
			return XmlReader.Create(readerStream, xrs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void ReadDocumentStreamed(XmlReader xr, Stream sParentStream)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(xr != null);
 | 
			
		||||
			if(xr == null) throw new ArgumentNullException("xr");
 | 
			
		||||
 | 
			
		||||
			m_ctxGroups.Clear();
 | 
			
		||||
			m_dictBinPool = new Dictionary<string, ProtectedBinary>();
 | 
			
		||||
 | 
			
		||||
			KdbContext ctx = KdbContext.Null;
 | 
			
		||||
 | 
			
		||||
			uint uTagCounter = 0;
 | 
			
		||||
 | 
			
		||||
			bool bSupportsStatus = (m_slLogger != null);
 | 
			
		||||
			long lStreamLength = 1;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				sParentStream.Position.ToString(); // Test Position support
 | 
			
		||||
				lStreamLength = sParentStream.Length;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { bSupportsStatus = false; }
 | 
			
		||||
			if(lStreamLength <= 0) { Debug.Assert(false); lStreamLength = 1; }
 | 
			
		||||
 | 
			
		||||
			m_bReadNextNode = true;
 | 
			
		||||
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				if(m_bReadNextNode)
 | 
			
		||||
				{
 | 
			
		||||
					if(!xr.Read()) break;
 | 
			
		||||
				}
 | 
			
		||||
				else m_bReadNextNode = true;
 | 
			
		||||
 | 
			
		||||
				switch(xr.NodeType)
 | 
			
		||||
				{
 | 
			
		||||
					case XmlNodeType.Element:
 | 
			
		||||
						ctx = ReadXmlElement(ctx, xr);
 | 
			
		||||
						break;
 | 
			
		||||
 | 
			
		||||
					case XmlNodeType.EndElement:
 | 
			
		||||
						ctx = EndXmlElement(ctx, xr);
 | 
			
		||||
						break;
 | 
			
		||||
 | 
			
		||||
					case XmlNodeType.XmlDeclaration:
 | 
			
		||||
						break; // Ignore
 | 
			
		||||
 | 
			
		||||
					default:
 | 
			
		||||
						Debug.Assert(false);
 | 
			
		||||
						break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				++uTagCounter;
 | 
			
		||||
				if(((uTagCounter % 256) == 0) && bSupportsStatus)
 | 
			
		||||
				{
 | 
			
		||||
					Debug.Assert(lStreamLength == sParentStream.Length);
 | 
			
		||||
					uint uPct = (uint)((sParentStream.Position * 100) /
 | 
			
		||||
						lStreamLength);
 | 
			
		||||
 | 
			
		||||
					// Clip percent value in case the stream reports incorrect
 | 
			
		||||
					// position/length values (M120413)
 | 
			
		||||
					if(uPct > 100) { Debug.Assert(false); uPct = 100; }
 | 
			
		||||
 | 
			
		||||
					m_slLogger.SetProgress(uPct);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(ctx == KdbContext.Null);
 | 
			
		||||
			if(ctx != KdbContext.Null) throw new FormatException();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(m_ctxGroups.Count == 0);
 | 
			
		||||
			if(m_ctxGroups.Count != 0) throw new FormatException();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private KdbContext ReadXmlElement(KdbContext ctx, XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(xr.NodeType == XmlNodeType.Element);
 | 
			
		||||
 | 
			
		||||
			switch(ctx)
 | 
			
		||||
			{
 | 
			
		||||
				case KdbContext.Null:
 | 
			
		||||
					if(xr.Name == ElemDocNode)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.KeePassFile, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.KeePassFile:
 | 
			
		||||
					if(xr.Name == ElemMeta)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Meta, xr);
 | 
			
		||||
					else if(xr.Name == ElemRoot)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Root, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.Meta:
 | 
			
		||||
					if(xr.Name == ElemGenerator)
 | 
			
		||||
						ReadString(xr); // Ignore
 | 
			
		||||
					else if(xr.Name == ElemHeaderHash)
 | 
			
		||||
					{
 | 
			
		||||
						string strHash = ReadString(xr);
 | 
			
		||||
						if(!string.IsNullOrEmpty(strHash) && (m_pbHashOfHeader != null) &&
 | 
			
		||||
							!m_bRepairMode)
 | 
			
		||||
						{
 | 
			
		||||
							byte[] pbHash = Convert.FromBase64String(strHash);
 | 
			
		||||
							if(!MemUtil.ArraysEqual(pbHash, m_pbHashOfHeader))
 | 
			
		||||
								throw new IOException(KLRes.FileCorrupted);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else if(xr.Name == ElemDbName)
 | 
			
		||||
						m_pwDatabase.Name = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbNameChanged)
 | 
			
		||||
						m_pwDatabase.NameChanged = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbDesc)
 | 
			
		||||
						m_pwDatabase.Description = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbDescChanged)
 | 
			
		||||
						m_pwDatabase.DescriptionChanged = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbDefaultUser)
 | 
			
		||||
						m_pwDatabase.DefaultUserName = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbDefaultUserChanged)
 | 
			
		||||
						m_pwDatabase.DefaultUserNameChanged = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbMntncHistoryDays)
 | 
			
		||||
						m_pwDatabase.MaintenanceHistoryDays = ReadUInt(xr, 365);
 | 
			
		||||
					else if(xr.Name == ElemDbColor)
 | 
			
		||||
					{
 | 
			
		||||
						string strColor = ReadString(xr);
 | 
			
		||||
						if(!string.IsNullOrEmpty(strColor))
 | 
			
		||||
							m_pwDatabase.Color = ColorTranslator.FromHtml(strColor);
 | 
			
		||||
					}
 | 
			
		||||
					else if(xr.Name == ElemDbKeyChanged)
 | 
			
		||||
						m_pwDatabase.MasterKeyChanged = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemDbKeyChangeRec)
 | 
			
		||||
						m_pwDatabase.MasterKeyChangeRec = ReadLong(xr, -1);
 | 
			
		||||
					else if(xr.Name == ElemDbKeyChangeForce)
 | 
			
		||||
						m_pwDatabase.MasterKeyChangeForce = ReadLong(xr, -1);
 | 
			
		||||
					else if(xr.Name == ElemMemoryProt)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.MemoryProtection, xr);
 | 
			
		||||
					else if(xr.Name == ElemCustomIcons)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.CustomIcons, xr);
 | 
			
		||||
					else if(xr.Name == ElemRecycleBinEnabled)
 | 
			
		||||
						m_pwDatabase.RecycleBinEnabled = ReadBool(xr, true);
 | 
			
		||||
					else if(xr.Name == ElemRecycleBinUuid)
 | 
			
		||||
						m_pwDatabase.RecycleBinUuid = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemRecycleBinChanged)
 | 
			
		||||
						m_pwDatabase.RecycleBinChanged = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemEntryTemplatesGroup)
 | 
			
		||||
						m_pwDatabase.EntryTemplatesGroup = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemEntryTemplatesGroupChanged)
 | 
			
		||||
						m_pwDatabase.EntryTemplatesGroupChanged = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemHistoryMaxItems)
 | 
			
		||||
						m_pwDatabase.HistoryMaxItems = ReadInt(xr, -1);
 | 
			
		||||
					else if(xr.Name == ElemHistoryMaxSize)
 | 
			
		||||
						m_pwDatabase.HistoryMaxSize = ReadLong(xr, -1);
 | 
			
		||||
					else if(xr.Name == ElemLastSelectedGroup)
 | 
			
		||||
						m_pwDatabase.LastSelectedGroup = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemLastTopVisibleGroup)
 | 
			
		||||
						m_pwDatabase.LastTopVisibleGroup = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemBinaries)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Binaries, xr);
 | 
			
		||||
					else if(xr.Name == ElemCustomData)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.CustomData, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.MemoryProtection:
 | 
			
		||||
					if(xr.Name == ElemProtTitle)
 | 
			
		||||
						m_pwDatabase.MemoryProtection.ProtectTitle = ReadBool(xr, false);
 | 
			
		||||
					else if(xr.Name == ElemProtUserName)
 | 
			
		||||
						m_pwDatabase.MemoryProtection.ProtectUserName = ReadBool(xr, false);
 | 
			
		||||
					else if(xr.Name == ElemProtPassword)
 | 
			
		||||
						m_pwDatabase.MemoryProtection.ProtectPassword = ReadBool(xr, true);
 | 
			
		||||
					else if(xr.Name == ElemProtUrl)
 | 
			
		||||
						m_pwDatabase.MemoryProtection.ProtectUrl = ReadBool(xr, false);
 | 
			
		||||
					else if(xr.Name == ElemProtNotes)
 | 
			
		||||
						m_pwDatabase.MemoryProtection.ProtectNotes = ReadBool(xr, false);
 | 
			
		||||
					// else if(xr.Name == ElemProtAutoHide)
 | 
			
		||||
					//	m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = ReadBool(xr, true);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.CustomIcons:
 | 
			
		||||
					if(xr.Name == ElemCustomIconItem)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.CustomIcon, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.CustomIcon:
 | 
			
		||||
					if(xr.Name == ElemCustomIconItemID)
 | 
			
		||||
						m_uuidCustomIconID = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemCustomIconItemData)
 | 
			
		||||
					{
 | 
			
		||||
						string strData = ReadString(xr);
 | 
			
		||||
						if(!string.IsNullOrEmpty(strData))
 | 
			
		||||
							m_pbCustomIconData = Convert.FromBase64String(strData);
 | 
			
		||||
						else { Debug.Assert(false); }
 | 
			
		||||
					}
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.Binaries:
 | 
			
		||||
					if(xr.Name == ElemBinary)
 | 
			
		||||
					{
 | 
			
		||||
						if(xr.MoveToAttribute(AttrId))
 | 
			
		||||
						{
 | 
			
		||||
							string strKey = xr.Value;
 | 
			
		||||
							ProtectedBinary pbData = ReadProtectedBinary(xr);
 | 
			
		||||
 | 
			
		||||
							m_dictBinPool[strKey ?? string.Empty] = pbData;
 | 
			
		||||
						}
 | 
			
		||||
						else ReadUnknown(xr);
 | 
			
		||||
					}
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.CustomData:
 | 
			
		||||
					if(xr.Name == ElemStringDictExItem)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.CustomDataItem, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.CustomDataItem:
 | 
			
		||||
					if(xr.Name == ElemKey)
 | 
			
		||||
						m_strCustomDataKey = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemValue)
 | 
			
		||||
						m_strCustomDataValue = ReadString(xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.Root:
 | 
			
		||||
					if(xr.Name == ElemGroup)
 | 
			
		||||
					{
 | 
			
		||||
						Debug.Assert(m_ctxGroups.Count == 0);
 | 
			
		||||
						if(m_ctxGroups.Count != 0) throw new FormatException();
 | 
			
		||||
 | 
			
		||||
						m_pwDatabase.RootGroup = new PwGroup(false, false);
 | 
			
		||||
						m_ctxGroups.Push(m_pwDatabase.RootGroup);
 | 
			
		||||
						m_ctxGroup = m_ctxGroups.Peek();
 | 
			
		||||
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Group, xr);
 | 
			
		||||
					}
 | 
			
		||||
					else if(xr.Name == ElemDeletedObjects)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.RootDeletedObjects, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.Group:
 | 
			
		||||
					if(xr.Name == ElemUuid)
 | 
			
		||||
						m_ctxGroup.Uuid = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemName)
 | 
			
		||||
						m_ctxGroup.Name = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemNotes)
 | 
			
		||||
						m_ctxGroup.Notes = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemIcon)
 | 
			
		||||
						m_ctxGroup.IconId = (PwIcon)ReadInt(xr, (int)PwIcon.Folder);
 | 
			
		||||
					else if(xr.Name == ElemCustomIconID)
 | 
			
		||||
						m_ctxGroup.CustomIconUuid = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemTimes)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.GroupTimes, xr);
 | 
			
		||||
					else if(xr.Name == ElemIsExpanded)
 | 
			
		||||
						m_ctxGroup.IsExpanded = ReadBool(xr, true);
 | 
			
		||||
					else if(xr.Name == ElemGroupDefaultAutoTypeSeq)
 | 
			
		||||
						m_ctxGroup.DefaultAutoTypeSequence = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemEnableAutoType)
 | 
			
		||||
						m_ctxGroup.EnableAutoType = StrUtil.StringToBoolEx(ReadString(xr));
 | 
			
		||||
					else if(xr.Name == ElemEnableSearching)
 | 
			
		||||
						m_ctxGroup.EnableSearching = StrUtil.StringToBoolEx(ReadString(xr));
 | 
			
		||||
					else if(xr.Name == ElemLastTopVisibleEntry)
 | 
			
		||||
						m_ctxGroup.LastTopVisibleEntry = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemGroup)
 | 
			
		||||
					{
 | 
			
		||||
						m_ctxGroup = new PwGroup(false, false);
 | 
			
		||||
						m_ctxGroups.Peek().AddGroup(m_ctxGroup, true);
 | 
			
		||||
 | 
			
		||||
						m_ctxGroups.Push(m_ctxGroup);
 | 
			
		||||
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Group, xr);
 | 
			
		||||
					}
 | 
			
		||||
					else if(xr.Name == ElemEntry)
 | 
			
		||||
					{
 | 
			
		||||
						m_ctxEntry = new PwEntry(false, false);
 | 
			
		||||
						m_ctxGroup.AddEntry(m_ctxEntry, true);
 | 
			
		||||
 | 
			
		||||
						m_bEntryInHistory = false;
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Entry, xr);
 | 
			
		||||
					}
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.Entry:
 | 
			
		||||
					if(xr.Name == ElemUuid)
 | 
			
		||||
						m_ctxEntry.Uuid = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemIcon)
 | 
			
		||||
						m_ctxEntry.IconId = (PwIcon)ReadInt(xr, (int)PwIcon.Key);
 | 
			
		||||
					else if(xr.Name == ElemCustomIconID)
 | 
			
		||||
						m_ctxEntry.CustomIconUuid = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemFgColor)
 | 
			
		||||
					{
 | 
			
		||||
						string strColor = ReadString(xr);
 | 
			
		||||
						if(!string.IsNullOrEmpty(strColor))
 | 
			
		||||
							m_ctxEntry.ForegroundColor = ColorTranslator.FromHtml(strColor);
 | 
			
		||||
					}
 | 
			
		||||
					else if(xr.Name == ElemBgColor)
 | 
			
		||||
					{
 | 
			
		||||
						string strColor = ReadString(xr);
 | 
			
		||||
						if(!string.IsNullOrEmpty(strColor))
 | 
			
		||||
							m_ctxEntry.BackgroundColor = ColorTranslator.FromHtml(strColor);
 | 
			
		||||
					}
 | 
			
		||||
					else if(xr.Name == ElemOverrideUrl)
 | 
			
		||||
						m_ctxEntry.OverrideUrl = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemTags)
 | 
			
		||||
						m_ctxEntry.Tags = StrUtil.StringToTags(ReadString(xr));
 | 
			
		||||
					else if(xr.Name == ElemTimes)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.EntryTimes, xr);
 | 
			
		||||
					else if(xr.Name == ElemString)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.EntryString, xr);
 | 
			
		||||
					else if(xr.Name == ElemBinary)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.EntryBinary, xr);
 | 
			
		||||
					else if(xr.Name == ElemAutoType)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.EntryAutoType, xr);
 | 
			
		||||
					else if(xr.Name == ElemHistory)
 | 
			
		||||
					{
 | 
			
		||||
						Debug.Assert(m_bEntryInHistory == false);
 | 
			
		||||
 | 
			
		||||
						if(m_bEntryInHistory == false)
 | 
			
		||||
						{
 | 
			
		||||
							m_ctxHistoryBase = m_ctxEntry;
 | 
			
		||||
							return SwitchContext(ctx, KdbContext.EntryHistory, xr);
 | 
			
		||||
						}
 | 
			
		||||
						else ReadUnknown(xr);
 | 
			
		||||
					}
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.GroupTimes:
 | 
			
		||||
				case KdbContext.EntryTimes:
 | 
			
		||||
					ITimeLogger tl = ((ctx == KdbContext.GroupTimes) ?
 | 
			
		||||
						(ITimeLogger)m_ctxGroup : (ITimeLogger)m_ctxEntry);
 | 
			
		||||
					Debug.Assert(tl != null);
 | 
			
		||||
 | 
			
		||||
					if(xr.Name == ElemLastModTime)
 | 
			
		||||
						tl.LastModificationTime = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemCreationTime)
 | 
			
		||||
						tl.CreationTime = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemLastAccessTime)
 | 
			
		||||
						tl.LastAccessTime = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemExpiryTime)
 | 
			
		||||
						tl.ExpiryTime = ReadTime(xr);
 | 
			
		||||
					else if(xr.Name == ElemExpires)
 | 
			
		||||
						tl.Expires = ReadBool(xr, false);
 | 
			
		||||
					else if(xr.Name == ElemUsageCount)
 | 
			
		||||
						tl.UsageCount = ReadULong(xr, 0);
 | 
			
		||||
					else if(xr.Name == ElemLocationChanged)
 | 
			
		||||
						tl.LocationChanged = ReadTime(xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.EntryString:
 | 
			
		||||
					if(xr.Name == ElemKey)
 | 
			
		||||
						m_ctxStringName = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemValue)
 | 
			
		||||
						m_ctxStringValue = ReadProtectedString(xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.EntryBinary:
 | 
			
		||||
					if(xr.Name == ElemKey)
 | 
			
		||||
						m_ctxBinaryName = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemValue)
 | 
			
		||||
						m_ctxBinaryValue = ReadProtectedBinary(xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.EntryAutoType:
 | 
			
		||||
					if(xr.Name == ElemAutoTypeEnabled)
 | 
			
		||||
						m_ctxEntry.AutoType.Enabled = ReadBool(xr, true);
 | 
			
		||||
					else if(xr.Name == ElemAutoTypeObfuscation)
 | 
			
		||||
						m_ctxEntry.AutoType.ObfuscationOptions =
 | 
			
		||||
							(AutoTypeObfuscationOptions)ReadInt(xr, 0);
 | 
			
		||||
					else if(xr.Name == ElemAutoTypeDefaultSeq)
 | 
			
		||||
						m_ctxEntry.AutoType.DefaultSequence = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemAutoTypeItem)
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.EntryAutoTypeItem, xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.EntryAutoTypeItem:
 | 
			
		||||
					if(xr.Name == ElemWindow)
 | 
			
		||||
						m_ctxATName = ReadString(xr);
 | 
			
		||||
					else if(xr.Name == ElemKeystrokeSequence)
 | 
			
		||||
						m_ctxATSeq = ReadString(xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.EntryHistory:
 | 
			
		||||
					if(xr.Name == ElemEntry)
 | 
			
		||||
					{
 | 
			
		||||
						m_ctxEntry = new PwEntry(false, false);
 | 
			
		||||
						m_ctxHistoryBase.History.Add(m_ctxEntry);
 | 
			
		||||
 | 
			
		||||
						m_bEntryInHistory = true;
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.Entry, xr);
 | 
			
		||||
					}
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.RootDeletedObjects:
 | 
			
		||||
					if(xr.Name == ElemDeletedObject)
 | 
			
		||||
					{
 | 
			
		||||
						m_ctxDeletedObject = new PwDeletedObject();
 | 
			
		||||
						m_pwDatabase.DeletedObjects.Add(m_ctxDeletedObject);
 | 
			
		||||
 | 
			
		||||
						return SwitchContext(ctx, KdbContext.DeletedObject, xr);
 | 
			
		||||
					}
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbContext.DeletedObject:
 | 
			
		||||
					if(xr.Name == ElemUuid)
 | 
			
		||||
						m_ctxDeletedObject.Uuid = ReadUuid(xr);
 | 
			
		||||
					else if(xr.Name == ElemDeletionTime)
 | 
			
		||||
						m_ctxDeletedObject.DeletionTime = ReadTime(xr);
 | 
			
		||||
					else ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
					ReadUnknown(xr);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return ctx;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private KdbContext EndXmlElement(KdbContext ctx, XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(xr.NodeType == XmlNodeType.EndElement);
 | 
			
		||||
 | 
			
		||||
			if((ctx == KdbContext.KeePassFile) && (xr.Name == ElemDocNode))
 | 
			
		||||
				return KdbContext.Null;
 | 
			
		||||
			else if((ctx == KdbContext.Meta) && (xr.Name == ElemMeta))
 | 
			
		||||
				return KdbContext.KeePassFile;
 | 
			
		||||
			else if((ctx == KdbContext.Root) && (xr.Name == ElemRoot))
 | 
			
		||||
				return KdbContext.KeePassFile;
 | 
			
		||||
			else if((ctx == KdbContext.MemoryProtection) && (xr.Name == ElemMemoryProt))
 | 
			
		||||
				return KdbContext.Meta;
 | 
			
		||||
			else if((ctx == KdbContext.CustomIcons) && (xr.Name == ElemCustomIcons))
 | 
			
		||||
				return KdbContext.Meta;
 | 
			
		||||
			else if((ctx == KdbContext.CustomIcon) && (xr.Name == ElemCustomIconItem))
 | 
			
		||||
			{
 | 
			
		||||
				if((m_uuidCustomIconID != PwUuid.Zero) && (m_pbCustomIconData != null))
 | 
			
		||||
					m_pwDatabase.CustomIcons.Add(new PwCustomIcon(
 | 
			
		||||
						m_uuidCustomIconID, m_pbCustomIconData));
 | 
			
		||||
				else { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
				m_uuidCustomIconID = PwUuid.Zero;
 | 
			
		||||
				m_pbCustomIconData = null;
 | 
			
		||||
 | 
			
		||||
				return KdbContext.CustomIcons;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.Binaries) && (xr.Name == ElemBinaries))
 | 
			
		||||
				return KdbContext.Meta;
 | 
			
		||||
			else if((ctx == KdbContext.CustomData) && (xr.Name == ElemCustomData))
 | 
			
		||||
				return KdbContext.Meta;
 | 
			
		||||
			else if((ctx == KdbContext.CustomDataItem) && (xr.Name == ElemStringDictExItem))
 | 
			
		||||
			{
 | 
			
		||||
				if((m_strCustomDataKey != null) && (m_strCustomDataValue != null))
 | 
			
		||||
					m_pwDatabase.CustomData.Set(m_strCustomDataKey, m_strCustomDataValue);
 | 
			
		||||
				else { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
				m_strCustomDataKey = null;
 | 
			
		||||
				m_strCustomDataValue = null;
 | 
			
		||||
 | 
			
		||||
				return KdbContext.CustomData;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.Group) && (xr.Name == ElemGroup))
 | 
			
		||||
			{
 | 
			
		||||
				if(PwUuid.Zero.EqualsValue(m_ctxGroup.Uuid))
 | 
			
		||||
					m_ctxGroup.Uuid = new PwUuid(true); // No assert (import)
 | 
			
		||||
 | 
			
		||||
				m_ctxGroups.Pop();
 | 
			
		||||
 | 
			
		||||
				if(m_ctxGroups.Count == 0)
 | 
			
		||||
				{
 | 
			
		||||
					m_ctxGroup = null;
 | 
			
		||||
					return KdbContext.Root;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					m_ctxGroup = m_ctxGroups.Peek();
 | 
			
		||||
					return KdbContext.Group;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.GroupTimes) && (xr.Name == ElemTimes))
 | 
			
		||||
				return KdbContext.Group;
 | 
			
		||||
			else if((ctx == KdbContext.Entry) && (xr.Name == ElemEntry))
 | 
			
		||||
			{
 | 
			
		||||
				// Create new UUID if absent
 | 
			
		||||
				if(PwUuid.Zero.EqualsValue(m_ctxEntry.Uuid))
 | 
			
		||||
					m_ctxEntry.Uuid = new PwUuid(true); // No assert (import)
 | 
			
		||||
 | 
			
		||||
				if(m_bEntryInHistory)
 | 
			
		||||
				{
 | 
			
		||||
					m_ctxEntry = m_ctxHistoryBase;
 | 
			
		||||
					return KdbContext.EntryHistory;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return KdbContext.Group;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.EntryTimes) && (xr.Name == ElemTimes))
 | 
			
		||||
				return KdbContext.Entry;
 | 
			
		||||
			else if((ctx == KdbContext.EntryString) && (xr.Name == ElemString))
 | 
			
		||||
			{
 | 
			
		||||
				m_ctxEntry.Strings.Set(m_ctxStringName, m_ctxStringValue);
 | 
			
		||||
				m_ctxStringName = null;
 | 
			
		||||
				m_ctxStringValue = null;
 | 
			
		||||
				return KdbContext.Entry;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.EntryBinary) && (xr.Name == ElemBinary))
 | 
			
		||||
			{
 | 
			
		||||
				if(string.IsNullOrEmpty(m_strDetachBins))
 | 
			
		||||
					m_ctxEntry.Binaries.Set(m_ctxBinaryName, m_ctxBinaryValue);
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					SaveBinary(m_ctxBinaryName, m_ctxBinaryValue, m_strDetachBins);
 | 
			
		||||
 | 
			
		||||
					m_ctxBinaryValue = null;
 | 
			
		||||
					GC.Collect();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				m_ctxBinaryName = null;
 | 
			
		||||
				m_ctxBinaryValue = null;
 | 
			
		||||
				return KdbContext.Entry;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.EntryAutoType) && (xr.Name == ElemAutoType))
 | 
			
		||||
				return KdbContext.Entry;
 | 
			
		||||
			else if((ctx == KdbContext.EntryAutoTypeItem) && (xr.Name == ElemAutoTypeItem))
 | 
			
		||||
			{
 | 
			
		||||
				AutoTypeAssociation atAssoc = new AutoTypeAssociation(m_ctxATName,
 | 
			
		||||
					m_ctxATSeq);
 | 
			
		||||
				m_ctxEntry.AutoType.Add(atAssoc);
 | 
			
		||||
				m_ctxATName = null;
 | 
			
		||||
				m_ctxATSeq = null;
 | 
			
		||||
				return KdbContext.EntryAutoType;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.EntryHistory) && (xr.Name == ElemHistory))
 | 
			
		||||
			{
 | 
			
		||||
				m_bEntryInHistory = false;
 | 
			
		||||
				return KdbContext.Entry;
 | 
			
		||||
			}
 | 
			
		||||
			else if((ctx == KdbContext.RootDeletedObjects) && (xr.Name == ElemDeletedObjects))
 | 
			
		||||
				return KdbContext.Root;
 | 
			
		||||
			else if((ctx == KdbContext.DeletedObject) && (xr.Name == ElemDeletedObject))
 | 
			
		||||
			{
 | 
			
		||||
				m_ctxDeletedObject = null;
 | 
			
		||||
				return KdbContext.RootDeletedObjects;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(false);
 | 
			
		||||
				throw new FormatException();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string ReadString(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			XorredBuffer xb = ProcessNode(xr);
 | 
			
		||||
			if(xb != null)
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pb = xb.ReadPlainText();
 | 
			
		||||
				if(pb.Length == 0) return string.Empty;
 | 
			
		||||
				return StrUtil.Utf8.GetString(pb, 0, pb.Length);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_bReadNextNode = false; // ReadElementString skips end tag
 | 
			
		||||
			return xr.ReadElementString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string ReadStringRaw(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			m_bReadNextNode = false; // ReadElementString skips end tag
 | 
			
		||||
			return xr.ReadElementString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool ReadBool(XmlReader xr, bool bDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
			if(str == ValTrue) return true;
 | 
			
		||||
			else if(str == ValFalse) return false;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return bDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private PwUuid ReadUuid(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
			if(string.IsNullOrEmpty(str)) return PwUuid.Zero;
 | 
			
		||||
			return new PwUuid(Convert.FromBase64String(str));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private int ReadInt(XmlReader xr, int nDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
 | 
			
		||||
			int n;
 | 
			
		||||
			if(StrUtil.TryParseInt(str, out n)) return n;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return nDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private uint ReadUInt(XmlReader xr, uint uDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
 | 
			
		||||
			uint u;
 | 
			
		||||
			if(StrUtil.TryParseUInt(str, out u)) return u;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return uDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private long ReadLong(XmlReader xr, long lDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
 | 
			
		||||
			long l;
 | 
			
		||||
			if(StrUtil.TryParseLong(str, out l)) return l;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return lDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private ulong ReadULong(XmlReader xr, ulong uDefault)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
 | 
			
		||||
			ulong u;
 | 
			
		||||
			if(StrUtil.TryParseULong(str, out u)) return u;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return uDefault;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private DateTime ReadTime(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			string str = ReadString(xr);
 | 
			
		||||
 | 
			
		||||
			DateTime dt;
 | 
			
		||||
			if(TimeUtil.TryDeserializeUtc(str, out dt)) return dt;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return m_dtNow;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private ProtectedString ReadProtectedString(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			XorredBuffer xb = ProcessNode(xr);
 | 
			
		||||
			if(xb != null) return new ProtectedString(true, xb);
 | 
			
		||||
 | 
			
		||||
			bool bProtect = false;
 | 
			
		||||
			if(m_format == KdbxFormat.PlainXml)
 | 
			
		||||
			{
 | 
			
		||||
				if(xr.MoveToAttribute(AttrProtectedInMemPlainXml))
 | 
			
		||||
				{
 | 
			
		||||
					string strProtect = xr.Value;
 | 
			
		||||
					bProtect = ((strProtect != null) && (strProtect == ValTrue));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ProtectedString ps = new ProtectedString(bProtect, ReadString(xr));
 | 
			
		||||
			return ps;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private ProtectedBinary ReadProtectedBinary(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			if(xr.MoveToAttribute(AttrRef))
 | 
			
		||||
			{
 | 
			
		||||
				string strRef = xr.Value;
 | 
			
		||||
				if(strRef != null)
 | 
			
		||||
				{
 | 
			
		||||
					ProtectedBinary pb = BinPoolGet(strRef);
 | 
			
		||||
					if(pb != null) return pb;
 | 
			
		||||
					else { Debug.Assert(false); }
 | 
			
		||||
				}
 | 
			
		||||
				else { Debug.Assert(false); }
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool bCompressed = false;
 | 
			
		||||
			if(xr.MoveToAttribute(AttrCompressed))
 | 
			
		||||
				bCompressed = (xr.Value == ValTrue);
 | 
			
		||||
 | 
			
		||||
			XorredBuffer xb = ProcessNode(xr);
 | 
			
		||||
			if(xb != null)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(!bCompressed); // See SubWriteValue(ProtectedBinary value)
 | 
			
		||||
				return new ProtectedBinary(true, xb);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			string strValue = ReadString(xr);
 | 
			
		||||
			if(strValue.Length == 0) return new ProtectedBinary();
 | 
			
		||||
 | 
			
		||||
			byte[] pbData = Convert.FromBase64String(strValue);
 | 
			
		||||
			if(bCompressed) pbData = MemUtil.Decompress(pbData);
 | 
			
		||||
			return new ProtectedBinary(false, pbData);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void ReadUnknown(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(false); // Unknown node!
 | 
			
		||||
 | 
			
		||||
			if(xr.IsEmptyElement) return;
 | 
			
		||||
 | 
			
		||||
			string strUnknownName = xr.Name;
 | 
			
		||||
			ProcessNode(xr);
 | 
			
		||||
 | 
			
		||||
			while(xr.Read())
 | 
			
		||||
			{
 | 
			
		||||
				if(xr.NodeType == XmlNodeType.EndElement) break;
 | 
			
		||||
				if(xr.NodeType != XmlNodeType.Element) continue;
 | 
			
		||||
 | 
			
		||||
				ReadUnknown(xr);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(xr.Name == strUnknownName);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private XorredBuffer ProcessNode(XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			// Debug.Assert(xr.NodeType == XmlNodeType.Element);
 | 
			
		||||
 | 
			
		||||
			XorredBuffer xb = null;
 | 
			
		||||
			if(xr.HasAttributes)
 | 
			
		||||
			{
 | 
			
		||||
				if(xr.MoveToAttribute(AttrProtected))
 | 
			
		||||
				{
 | 
			
		||||
					if(xr.Value == ValTrue)
 | 
			
		||||
					{
 | 
			
		||||
						xr.MoveToElement();
 | 
			
		||||
						string strEncrypted = ReadStringRaw(xr);
 | 
			
		||||
 | 
			
		||||
						byte[] pbEncrypted;
 | 
			
		||||
						if(strEncrypted.Length > 0)
 | 
			
		||||
							pbEncrypted = Convert.FromBase64String(strEncrypted);
 | 
			
		||||
						else pbEncrypted = new byte[0];
 | 
			
		||||
 | 
			
		||||
						byte[] pbPad = m_randomStream.GetRandomBytes((uint)pbEncrypted.Length);
 | 
			
		||||
 | 
			
		||||
						xb = new XorredBuffer(pbEncrypted, pbPad);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return xb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static KdbContext SwitchContext(KdbContext ctxCurrent,
 | 
			
		||||
			KdbContext ctxNew, XmlReader xr)
 | 
			
		||||
		{
 | 
			
		||||
			if(xr.IsEmptyElement) return ctxCurrent;
 | 
			
		||||
			return ctxNew;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										391
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.Read.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,391 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.IO.Compression;
 | 
			
		||||
#else
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Cryptography.Cipher;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Keys;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Serialization to KeePass KDBX files.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed partial class KdbxFile
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Load a KDB file from a file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strFilePath">File to load.</param>
 | 
			
		||||
		/// <param name="kdbFormat">Format specifier.</param>
 | 
			
		||||
		/// <param name="slLogger">Status logger (optional).</param>
 | 
			
		||||
		public void Load(string strFilePath, KdbxFormat kdbFormat, IStatusLogger slLogger)
 | 
			
		||||
		{
 | 
			
		||||
			IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);
 | 
			
		||||
			Load(IOConnection.OpenRead(ioc), kdbFormat, slLogger);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Load a KDB file from a stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="sSource">Stream to read the data from. Must contain
 | 
			
		||||
		/// a KDBX stream.</param>
 | 
			
		||||
		/// <param name="kdbFormat">Format specifier.</param>
 | 
			
		||||
		/// <param name="slLogger">Status logger (optional).</param>
 | 
			
		||||
		public void Load(Stream sSource, KdbxFormat kdbFormat, IStatusLogger slLogger)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(sSource != null);
 | 
			
		||||
			if(sSource == null) throw new ArgumentNullException("sSource");
 | 
			
		||||
 | 
			
		||||
			m_format = kdbFormat;
 | 
			
		||||
			m_slLogger = slLogger;
 | 
			
		||||
 | 
			
		||||
			HashingStreamEx hashedStream = new HashingStreamEx(sSource, false, null);
 | 
			
		||||
 | 
			
		||||
			UTF8Encoding encNoBom = StrUtil.Utf8;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				BinaryReaderEx br = null;
 | 
			
		||||
				BinaryReaderEx brDecrypted = null;
 | 
			
		||||
				Stream readerStream = null;
 | 
			
		||||
 | 
			
		||||
				if(kdbFormat == KdbxFormat.Default)
 | 
			
		||||
				{
 | 
			
		||||
					br = new BinaryReaderEx(hashedStream, encNoBom, KLRes.FileCorrupted);
 | 
			
		||||
					ReadHeader(br);
 | 
			
		||||
 | 
			
		||||
					Stream sDecrypted = AttachStreamDecryptor(hashedStream);
 | 
			
		||||
					if((sDecrypted == null) || (sDecrypted == hashedStream))
 | 
			
		||||
						throw new SecurityException(KLRes.CryptoStreamFailed);
 | 
			
		||||
 | 
			
		||||
					brDecrypted = new BinaryReaderEx(sDecrypted, encNoBom, KLRes.FileCorrupted);
 | 
			
		||||
					byte[] pbStoredStartBytes = brDecrypted.ReadBytes(32);
 | 
			
		||||
 | 
			
		||||
					if((m_pbStreamStartBytes == null) || (m_pbStreamStartBytes.Length != 32))
 | 
			
		||||
						throw new InvalidDataException();
 | 
			
		||||
 | 
			
		||||
					for(int iStart = 0; iStart < 32; ++iStart)
 | 
			
		||||
					{
 | 
			
		||||
						if(pbStoredStartBytes[iStart] != m_pbStreamStartBytes[iStart])
 | 
			
		||||
							throw new InvalidCompositeKeyException();
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					Stream sHashed = new HashedBlockStream(sDecrypted, false, 0,
 | 
			
		||||
						!m_bRepairMode);
 | 
			
		||||
 | 
			
		||||
					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
 | 
			
		||||
						readerStream = new GZipStream(sHashed, CompressionMode.Decompress);
 | 
			
		||||
					else readerStream = sHashed;
 | 
			
		||||
				}
 | 
			
		||||
				else if(kdbFormat == KdbxFormat.PlainXml)
 | 
			
		||||
					readerStream = hashedStream;
 | 
			
		||||
				else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
 | 
			
		||||
 | 
			
		||||
				if(kdbFormat != KdbxFormat.PlainXml) // Is an encrypted format
 | 
			
		||||
				{
 | 
			
		||||
					if(m_pbProtectedStreamKey == null)
 | 
			
		||||
					{
 | 
			
		||||
						Debug.Assert(false);
 | 
			
		||||
						throw new SecurityException("Invalid protected stream key!");
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
 | 
			
		||||
						m_pbProtectedStreamKey);
 | 
			
		||||
				}
 | 
			
		||||
				else m_randomStream = null; // No random stream for plain-text files
 | 
			
		||||
 | 
			
		||||
				ReadXmlStreamed(readerStream, hashedStream);
 | 
			
		||||
				// ReadXmlDom(readerStream);
 | 
			
		||||
 | 
			
		||||
				readerStream.Close();
 | 
			
		||||
				// GC.KeepAlive(br);
 | 
			
		||||
				// GC.KeepAlive(brDecrypted);
 | 
			
		||||
			}
 | 
			
		||||
			catch(CryptographicException) // Thrown on invalid padding
 | 
			
		||||
			{
 | 
			
		||||
				throw new CryptographicException(KLRes.FileCorrupted);
 | 
			
		||||
			}
 | 
			
		||||
			finally { CommonCleanUpRead(sSource, hashedStream); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void CommonCleanUpRead(Stream sSource, HashingStreamEx hashedStream)
 | 
			
		||||
		{
 | 
			
		||||
			hashedStream.Close();
 | 
			
		||||
			m_pbHashOfFileOnDisk = hashedStream.Hash;
 | 
			
		||||
 | 
			
		||||
			sSource.Close();
 | 
			
		||||
 | 
			
		||||
			// Reset memory protection settings (to always use reasonable
 | 
			
		||||
			// defaults)
 | 
			
		||||
			m_pwDatabase.MemoryProtection = new MemoryProtectionConfig();
 | 
			
		||||
 | 
			
		||||
			// Remove old backups (this call is required here in order to apply
 | 
			
		||||
			// the default history maintenance settings for people upgrading from
 | 
			
		||||
			// KeePass <= 2.14 to >= 2.15; also it ensures history integrity in
 | 
			
		||||
			// case a different application has created the KDBX file and ignored
 | 
			
		||||
			// the history maintenance settings)
 | 
			
		||||
			m_pwDatabase.MaintainBackups(); // Don't mark database as modified
 | 
			
		||||
 | 
			
		||||
			m_pbHashOfHeader = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void ReadHeader(BinaryReaderEx br)
 | 
			
		||||
		{
 | 
			
		||||
			MemoryStream msHeader = new MemoryStream();
 | 
			
		||||
			Debug.Assert(br.CopyDataTo == null);
 | 
			
		||||
			br.CopyDataTo = msHeader;
 | 
			
		||||
 | 
			
		||||
			byte[] pbSig1 = br.ReadBytes(4);
 | 
			
		||||
			uint uSig1 = MemUtil.BytesToUInt32(pbSig1);
 | 
			
		||||
			byte[] pbSig2 = br.ReadBytes(4);
 | 
			
		||||
			uint uSig2 = MemUtil.BytesToUInt32(pbSig2);
 | 
			
		||||
 | 
			
		||||
			if((uSig1 == FileSignatureOld1) && (uSig2 == FileSignatureOld2))
 | 
			
		||||
				throw new OldFormatException(PwDefs.ShortProductName + @" 1.x",
 | 
			
		||||
					OldFormatException.OldFormatType.KeePass1x);
 | 
			
		||||
 | 
			
		||||
			if((uSig1 == FileSignature1) && (uSig2 == FileSignature2)) { }
 | 
			
		||||
			else if((uSig1 == FileSignaturePreRelease1) && (uSig2 ==
 | 
			
		||||
				FileSignaturePreRelease2)) { }
 | 
			
		||||
			else throw new FormatException(KLRes.FileSigInvalid);
 | 
			
		||||
 | 
			
		||||
			byte[] pb = br.ReadBytes(4);
 | 
			
		||||
			uint uVersion = MemUtil.BytesToUInt32(pb);
 | 
			
		||||
			if((uVersion & FileVersionCriticalMask) > (FileVersion32 & FileVersionCriticalMask))
 | 
			
		||||
				throw new FormatException(KLRes.FileVersionUnsupported +
 | 
			
		||||
					MessageService.NewParagraph + KLRes.FileNewVerReq);
 | 
			
		||||
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				if(ReadHeaderField(br) == false)
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			br.CopyDataTo = null;
 | 
			
		||||
			byte[] pbHeader = msHeader.ToArray();
 | 
			
		||||
			msHeader.Close();
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			m_pbHashOfHeader = sha256.ComputeHash(pbHeader);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool ReadHeaderField(BinaryReaderEx brSource)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(brSource != null);
 | 
			
		||||
			if(brSource == null) throw new ArgumentNullException("brSource");
 | 
			
		||||
 | 
			
		||||
			byte btFieldID = brSource.ReadByte();
 | 
			
		||||
			ushort uSize = MemUtil.BytesToUInt16(brSource.ReadBytes(2));
 | 
			
		||||
 | 
			
		||||
			byte[] pbData = null;
 | 
			
		||||
			if(uSize > 0)
 | 
			
		||||
			{
 | 
			
		||||
				string strPrevExcpText = brSource.ReadExceptionText;
 | 
			
		||||
				brSource.ReadExceptionText = KLRes.FileHeaderEndEarly;
 | 
			
		||||
 | 
			
		||||
				pbData = brSource.ReadBytes(uSize);
 | 
			
		||||
 | 
			
		||||
				brSource.ReadExceptionText = strPrevExcpText;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool bResult = true;
 | 
			
		||||
			KdbxHeaderFieldID kdbID = (KdbxHeaderFieldID)btFieldID;
 | 
			
		||||
			switch(kdbID)
 | 
			
		||||
			{
 | 
			
		||||
				case KdbxHeaderFieldID.EndOfHeader:
 | 
			
		||||
					bResult = false; // Returning false indicates end of header
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.CipherID:
 | 
			
		||||
					SetCipher(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.CompressionFlags:
 | 
			
		||||
					SetCompressionFlags(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.MasterSeed:
 | 
			
		||||
					m_pbMasterSeed = pbData;
 | 
			
		||||
					CryptoRandom.Instance.AddEntropy(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.TransformSeed:
 | 
			
		||||
					m_pbTransformSeed = pbData;
 | 
			
		||||
					CryptoRandom.Instance.AddEntropy(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.TransformRounds:
 | 
			
		||||
					m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.EncryptionIV:
 | 
			
		||||
					m_pbEncryptionIV = pbData;
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.ProtectedStreamKey:
 | 
			
		||||
					m_pbProtectedStreamKey = pbData;
 | 
			
		||||
					CryptoRandom.Instance.AddEntropy(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.StreamStartBytes:
 | 
			
		||||
					m_pbStreamStartBytes = pbData;
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case KdbxHeaderFieldID.InnerRandomStreamID:
 | 
			
		||||
					SetInnerRandomStreamID(pbData);
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				default:
 | 
			
		||||
					Debug.Assert(false);
 | 
			
		||||
					if(m_slLogger != null)
 | 
			
		||||
						m_slLogger.SetText(KLRes.UnknownHeaderId + @": " +
 | 
			
		||||
							kdbID.ToString() + "!", LogStatusType.Warning);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void SetCipher(byte[] pbID)
 | 
			
		||||
		{
 | 
			
		||||
			if((pbID == null) || (pbID.Length != 16))
 | 
			
		||||
				throw new FormatException(KLRes.FileUnknownCipher);
 | 
			
		||||
 | 
			
		||||
			m_pwDatabase.DataCipherUuid = new PwUuid(pbID);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void SetCompressionFlags(byte[] pbFlags)
 | 
			
		||||
		{
 | 
			
		||||
			int nID = (int)MemUtil.BytesToUInt32(pbFlags);
 | 
			
		||||
			if((nID < 0) || (nID >= (int)PwCompressionAlgorithm.Count))
 | 
			
		||||
				throw new FormatException(KLRes.FileUnknownCompression);
 | 
			
		||||
 | 
			
		||||
			m_pwDatabase.Compression = (PwCompressionAlgorithm)nID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void SetInnerRandomStreamID(byte[] pbID)
 | 
			
		||||
		{
 | 
			
		||||
			uint uID = MemUtil.BytesToUInt32(pbID);
 | 
			
		||||
			if(uID >= (uint)CrsAlgorithm.Count)
 | 
			
		||||
				throw new FormatException(KLRes.FileUnknownCipher);
 | 
			
		||||
 | 
			
		||||
			m_craInnerRandomStream = (CrsAlgorithm)uID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private Stream AttachStreamDecryptor(Stream s)
 | 
			
		||||
		{
 | 
			
		||||
			MemoryStream ms = new MemoryStream();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(m_pbMasterSeed.Length == 32);
 | 
			
		||||
			if(m_pbMasterSeed.Length != 32)
 | 
			
		||||
				throw new FormatException(KLRes.MasterSeedLengthInvalid);
 | 
			
		||||
			ms.Write(m_pbMasterSeed, 0, 32);
 | 
			
		||||
 | 
			
		||||
			byte[] pKey32 = m_pwDatabase.MasterKey.GenerateKey32(m_pbTransformSeed,
 | 
			
		||||
				m_pwDatabase.KeyEncryptionRounds).ReadData();
 | 
			
		||||
			if((pKey32 == null) || (pKey32.Length != 32))
 | 
			
		||||
				throw new SecurityException(KLRes.InvalidCompositeKey);
 | 
			
		||||
			ms.Write(pKey32, 0, 32);
 | 
			
		||||
			
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			byte[] aesKey = sha256.ComputeHash(ms.ToArray());
 | 
			
		||||
 | 
			
		||||
			ms.Close();
 | 
			
		||||
			Array.Clear(pKey32, 0, 32);
 | 
			
		||||
 | 
			
		||||
			if((aesKey == null) || (aesKey.Length != 32))
 | 
			
		||||
				throw new SecurityException(KLRes.FinalKeyCreationFailed);
 | 
			
		||||
 | 
			
		||||
			ICipherEngine iEngine = CipherPool.GlobalPool.GetCipher(m_pwDatabase.DataCipherUuid);
 | 
			
		||||
			if(iEngine == null) throw new SecurityException(KLRes.FileUnknownCipher);
 | 
			
		||||
			return iEngine.DecryptStream(s, aesKey, m_pbEncryptionIV);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public static List<PwEntry> ReadEntries(PwDatabase pwDatabase, Stream msData)
 | 
			
		||||
		{
 | 
			
		||||
			return ReadEntries(msData);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Read entries from a stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="msData">Input stream to read the entries from.</param>
 | 
			
		||||
		/// <returns>Extracted entries.</returns>
 | 
			
		||||
		public static List<PwEntry> ReadEntries(Stream msData)
 | 
			
		||||
		{
 | 
			
		||||
			/* KdbxFile f = new KdbxFile(pwDatabase);
 | 
			
		||||
			f.m_format = KdbxFormat.PlainXml;
 | 
			
		||||
 | 
			
		||||
			XmlDocument doc = new XmlDocument();
 | 
			
		||||
			doc.Load(msData);
 | 
			
		||||
 | 
			
		||||
			XmlElement el = doc.DocumentElement;
 | 
			
		||||
			if(el.Name != ElemRoot) throw new FormatException();
 | 
			
		||||
 | 
			
		||||
			List<PwEntry> vEntries = new List<PwEntry>();
 | 
			
		||||
 | 
			
		||||
			foreach(XmlNode xmlChild in el.ChildNodes)
 | 
			
		||||
			{
 | 
			
		||||
				if(xmlChild.Name == ElemEntry)
 | 
			
		||||
				{
 | 
			
		||||
					PwEntry pe = f.ReadEntry(xmlChild);
 | 
			
		||||
					pe.Uuid = new PwUuid(true);
 | 
			
		||||
 | 
			
		||||
					foreach(PwEntry peHistory in pe.History)
 | 
			
		||||
						peHistory.Uuid = pe.Uuid;
 | 
			
		||||
 | 
			
		||||
					vEntries.Add(pe);
 | 
			
		||||
				}
 | 
			
		||||
				else { Debug.Assert(false); }
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return vEntries; */
 | 
			
		||||
 | 
			
		||||
			PwDatabase pd = new PwDatabase();
 | 
			
		||||
			KdbxFile f = new KdbxFile(pd);
 | 
			
		||||
			f.Load(msData, KdbxFormat.PlainXml, null);
 | 
			
		||||
 | 
			
		||||
			List<PwEntry> vEntries = new List<PwEntry>();
 | 
			
		||||
			foreach(PwEntry pe in pd.RootGroup.Entries)
 | 
			
		||||
			{
 | 
			
		||||
				pe.SetUuid(new PwUuid(true), true);
 | 
			
		||||
				vEntries.Add(pe);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return vEntries;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										851
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										851
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.Write.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,851 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Security;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.Drawing.Imaging;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.IO.Compression;
 | 
			
		||||
#else
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Collections;
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Cryptography.Cipher;
 | 
			
		||||
using KeePassLib.Delegates;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Keys;
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Serialization to KeePass KDBX files.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed partial class KdbxFile
 | 
			
		||||
	{
 | 
			
		||||
		// public void Save(string strFile, PwGroup pgDataSource, KdbxFormat format,
 | 
			
		||||
		//	IStatusLogger slLogger)
 | 
			
		||||
		// {
 | 
			
		||||
		//	bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);
 | 
			
		||||
		//
 | 
			
		||||
		//	IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
 | 
			
		||||
		//	this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger);
 | 
			
		||||
		//
 | 
			
		||||
		//	if(bMadeUnhidden) UrlUtil.HideFile(strFile, true); // Hide again
 | 
			
		||||
		// }
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Save the contents of the current <c>PwDatabase</c> to a KDBX file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="sSaveTo">Stream to write the KDBX file into.</param>
 | 
			
		||||
		/// <param name="pgDataSource">Group containing all groups and
 | 
			
		||||
		/// entries to write. If <c>null</c>, the complete database will
 | 
			
		||||
		/// be written.</param>
 | 
			
		||||
		/// <param name="format">Format of the file to create.</param>
 | 
			
		||||
		/// <param name="slLogger">Logger that recieves status information.</param>
 | 
			
		||||
		public void Save(Stream sSaveTo, PwGroup pgDataSource, KdbxFormat format,
 | 
			
		||||
			IStatusLogger slLogger)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(sSaveTo != null);
 | 
			
		||||
			if(sSaveTo == null) throw new ArgumentNullException("sSaveTo");
 | 
			
		||||
 | 
			
		||||
			m_format = format;
 | 
			
		||||
			m_slLogger = slLogger;
 | 
			
		||||
 | 
			
		||||
			HashingStreamEx hashedStream = new HashingStreamEx(sSaveTo, true, null);
 | 
			
		||||
 | 
			
		||||
			UTF8Encoding encNoBom = StrUtil.Utf8;
 | 
			
		||||
			CryptoRandom cr = CryptoRandom.Instance;
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				m_pbMasterSeed = cr.GetRandomBytes(32);
 | 
			
		||||
				m_pbTransformSeed = cr.GetRandomBytes(32);
 | 
			
		||||
				m_pbEncryptionIV = cr.GetRandomBytes(16);
 | 
			
		||||
 | 
			
		||||
				m_pbProtectedStreamKey = cr.GetRandomBytes(32);
 | 
			
		||||
				m_craInnerRandomStream = CrsAlgorithm.Salsa20;
 | 
			
		||||
				m_randomStream = new CryptoRandomStream(m_craInnerRandomStream,
 | 
			
		||||
					m_pbProtectedStreamKey);
 | 
			
		||||
 | 
			
		||||
				m_pbStreamStartBytes = cr.GetRandomBytes(32);
 | 
			
		||||
 | 
			
		||||
				Stream writerStream;
 | 
			
		||||
				if(m_format == KdbxFormat.Default)
 | 
			
		||||
				{
 | 
			
		||||
					WriteHeader(hashedStream); // Also flushes the stream
 | 
			
		||||
 | 
			
		||||
					Stream sEncrypted = AttachStreamEncryptor(hashedStream);
 | 
			
		||||
					if((sEncrypted == null) || (sEncrypted == hashedStream))
 | 
			
		||||
						throw new SecurityException(KLRes.CryptoStreamFailed);
 | 
			
		||||
 | 
			
		||||
					sEncrypted.Write(m_pbStreamStartBytes, 0, m_pbStreamStartBytes.Length);
 | 
			
		||||
 | 
			
		||||
					Stream sHashed = new HashedBlockStream(sEncrypted, true);
 | 
			
		||||
 | 
			
		||||
					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
 | 
			
		||||
						writerStream = new GZipStream(sHashed, CompressionMode.Compress);
 | 
			
		||||
					else
 | 
			
		||||
						writerStream = sHashed;
 | 
			
		||||
				}
 | 
			
		||||
				else if(m_format == KdbxFormat.PlainXml)
 | 
			
		||||
					writerStream = hashedStream;
 | 
			
		||||
				else { Debug.Assert(false); throw new FormatException("KdbFormat"); }
 | 
			
		||||
 | 
			
		||||
				m_xmlWriter = new XmlTextWriter(writerStream, encNoBom);
 | 
			
		||||
				WriteDocument(pgDataSource);
 | 
			
		||||
 | 
			
		||||
				m_xmlWriter.Flush();
 | 
			
		||||
				m_xmlWriter.Close();
 | 
			
		||||
				writerStream.Close();
 | 
			
		||||
			}
 | 
			
		||||
			finally { CommonCleanUpWrite(sSaveTo, hashedStream); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void CommonCleanUpWrite(Stream sSaveTo, HashingStreamEx hashedStream)
 | 
			
		||||
		{
 | 
			
		||||
			hashedStream.Close();
 | 
			
		||||
			m_pbHashOfFileOnDisk = hashedStream.Hash;
 | 
			
		||||
 | 
			
		||||
			sSaveTo.Close();
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter = null;
 | 
			
		||||
			m_pbHashOfHeader = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteHeader(Stream s)
 | 
			
		||||
		{
 | 
			
		||||
			MemoryStream ms = new MemoryStream();
 | 
			
		||||
 | 
			
		||||
			MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature1));
 | 
			
		||||
			MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileSignature2));
 | 
			
		||||
			MemUtil.Write(ms, MemUtil.UInt32ToBytes(FileVersion32));
 | 
			
		||||
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.CipherID,
 | 
			
		||||
				m_pwDatabase.DataCipherUuid.UuidBytes);
 | 
			
		||||
 | 
			
		||||
			int nCprID = (int)m_pwDatabase.Compression;
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.CompressionFlags,
 | 
			
		||||
				MemUtil.UInt32ToBytes((uint)nCprID));
 | 
			
		||||
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.MasterSeed, m_pbMasterSeed);
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.TransformSeed, m_pbTransformSeed);
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.TransformRounds,
 | 
			
		||||
				MemUtil.UInt64ToBytes(m_pwDatabase.KeyEncryptionRounds));
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.EncryptionIV, m_pbEncryptionIV);
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.ProtectedStreamKey, m_pbProtectedStreamKey);
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.StreamStartBytes, m_pbStreamStartBytes);
 | 
			
		||||
 | 
			
		||||
			int nIrsID = (int)m_craInnerRandomStream;
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.InnerRandomStreamID,
 | 
			
		||||
				MemUtil.UInt32ToBytes((uint)nIrsID));
 | 
			
		||||
 | 
			
		||||
			WriteHeaderField(ms, KdbxHeaderFieldID.EndOfHeader, new byte[]{
 | 
			
		||||
				(byte)'\r', (byte)'\n', (byte)'\r', (byte)'\n' });
 | 
			
		||||
 | 
			
		||||
			byte[] pbHeader = ms.ToArray();
 | 
			
		||||
			ms.Close();
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			m_pbHashOfHeader = sha256.ComputeHash(pbHeader);
 | 
			
		||||
 | 
			
		||||
			s.Write(pbHeader, 0, pbHeader.Length);
 | 
			
		||||
			s.Flush();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void WriteHeaderField(Stream s, KdbxHeaderFieldID kdbID,
 | 
			
		||||
			byte[] pbData)
 | 
			
		||||
		{
 | 
			
		||||
			s.WriteByte((byte)kdbID);
 | 
			
		||||
 | 
			
		||||
			if(pbData != null)
 | 
			
		||||
			{
 | 
			
		||||
				ushort uLength = (ushort)pbData.Length;
 | 
			
		||||
				MemUtil.Write(s, MemUtil.UInt16ToBytes(uLength));
 | 
			
		||||
 | 
			
		||||
				if(uLength > 0) s.Write(pbData, 0, pbData.Length);
 | 
			
		||||
			}
 | 
			
		||||
			else MemUtil.Write(s, MemUtil.UInt16ToBytes((ushort)0));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private Stream AttachStreamEncryptor(Stream s)
 | 
			
		||||
		{
 | 
			
		||||
			MemoryStream ms = new MemoryStream();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(m_pbMasterSeed != null);
 | 
			
		||||
			Debug.Assert(m_pbMasterSeed.Length == 32);
 | 
			
		||||
			ms.Write(m_pbMasterSeed, 0, 32);
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(m_pwDatabase != null);
 | 
			
		||||
			Debug.Assert(m_pwDatabase.MasterKey != null);
 | 
			
		||||
			ProtectedBinary pbinKey = m_pwDatabase.MasterKey.GenerateKey32(
 | 
			
		||||
				m_pbTransformSeed, m_pwDatabase.KeyEncryptionRounds);
 | 
			
		||||
			Debug.Assert(pbinKey != null);
 | 
			
		||||
			if(pbinKey == null)
 | 
			
		||||
				throw new SecurityException(KLRes.InvalidCompositeKey);
 | 
			
		||||
			byte[] pKey32 = pbinKey.ReadData();
 | 
			
		||||
			if((pKey32 == null) || (pKey32.Length != 32))
 | 
			
		||||
				throw new SecurityException(KLRes.InvalidCompositeKey);
 | 
			
		||||
			ms.Write(pKey32, 0, 32);
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			byte[] aesKey = sha256.ComputeHash(ms.ToArray());
 | 
			
		||||
			
 | 
			
		||||
			ms.Close();
 | 
			
		||||
			Array.Clear(pKey32, 0, 32);
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(CipherPool.GlobalPool != null);
 | 
			
		||||
			ICipherEngine iEngine = CipherPool.GlobalPool.GetCipher(m_pwDatabase.DataCipherUuid);
 | 
			
		||||
			if(iEngine == null) throw new SecurityException(KLRes.FileUnknownCipher);
 | 
			
		||||
			return iEngine.EncryptStream(s, aesKey, m_pbEncryptionIV);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteDocument(PwGroup pgDataSource)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(m_xmlWriter != null);
 | 
			
		||||
			if(m_xmlWriter == null) throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			PwGroup pgRoot = (pgDataSource ?? m_pwDatabase.RootGroup);
 | 
			
		||||
 | 
			
		||||
			uint uNumGroups, uNumEntries, uCurEntry = 0;
 | 
			
		||||
			pgRoot.GetCounts(true, out uNumGroups, out uNumEntries);
 | 
			
		||||
 | 
			
		||||
			BinPoolBuild(pgRoot);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.Formatting = Formatting.Indented;
 | 
			
		||||
			m_xmlWriter.IndentChar = '\t';
 | 
			
		||||
			m_xmlWriter.Indentation = 1;
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartDocument(true);
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemDocNode);
 | 
			
		||||
 | 
			
		||||
			WriteMeta();
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemRoot);
 | 
			
		||||
			StartGroup(pgRoot);
 | 
			
		||||
 | 
			
		||||
			Stack<PwGroup> groupStack = new Stack<PwGroup>();
 | 
			
		||||
			groupStack.Push(pgRoot);
 | 
			
		||||
 | 
			
		||||
			GroupHandler gh = delegate(PwGroup pg)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(pg != null);
 | 
			
		||||
				if(pg == null) throw new ArgumentNullException("pg");
 | 
			
		||||
 | 
			
		||||
				while(true)
 | 
			
		||||
				{
 | 
			
		||||
					if(pg.ParentGroup == groupStack.Peek())
 | 
			
		||||
					{
 | 
			
		||||
						groupStack.Push(pg);
 | 
			
		||||
						StartGroup(pg);
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						groupStack.Pop();
 | 
			
		||||
						if(groupStack.Count <= 0) return false;
 | 
			
		||||
 | 
			
		||||
						EndGroup();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return true;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			EntryHandler eh = delegate(PwEntry pe)
 | 
			
		||||
			{
 | 
			
		||||
				Debug.Assert(pe != null);
 | 
			
		||||
				WriteEntry(pe, false);
 | 
			
		||||
 | 
			
		||||
				++uCurEntry;
 | 
			
		||||
				if(m_slLogger != null)
 | 
			
		||||
					if(!m_slLogger.SetProgress((100 * uCurEntry) / uNumEntries))
 | 
			
		||||
						return false;
 | 
			
		||||
 | 
			
		||||
				return true;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			if(!pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, eh))
 | 
			
		||||
				throw new InvalidOperationException();
 | 
			
		||||
 | 
			
		||||
			while(groupStack.Count > 1)
 | 
			
		||||
			{
 | 
			
		||||
				m_xmlWriter.WriteEndElement();
 | 
			
		||||
				groupStack.Pop();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			EndGroup();
 | 
			
		||||
 | 
			
		||||
			WriteList(ElemDeletedObjects, m_pwDatabase.DeletedObjects);
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // Root
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // ElemDocNode
 | 
			
		||||
			m_xmlWriter.WriteEndDocument();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteMeta()
 | 
			
		||||
		{
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemMeta);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemGenerator, PwDatabase.LocalizedAppName, false); // Generator name
 | 
			
		||||
 | 
			
		||||
			if(m_pbHashOfHeader != null)
 | 
			
		||||
				WriteObject(ElemHeaderHash, Convert.ToBase64String(
 | 
			
		||||
					m_pbHashOfHeader), false);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemDbName, m_pwDatabase.Name, true);
 | 
			
		||||
			WriteObject(ElemDbNameChanged, m_pwDatabase.NameChanged);
 | 
			
		||||
			WriteObject(ElemDbDesc, m_pwDatabase.Description, true);
 | 
			
		||||
			WriteObject(ElemDbDescChanged, m_pwDatabase.DescriptionChanged);
 | 
			
		||||
			WriteObject(ElemDbDefaultUser, m_pwDatabase.DefaultUserName, true);
 | 
			
		||||
			WriteObject(ElemDbDefaultUserChanged, m_pwDatabase.DefaultUserNameChanged);
 | 
			
		||||
			WriteObject(ElemDbMntncHistoryDays, m_pwDatabase.MaintenanceHistoryDays);
 | 
			
		||||
			WriteObject(ElemDbColor, StrUtil.ColorToUnnamedHtml(m_pwDatabase.Color, true), false);
 | 
			
		||||
			WriteObject(ElemDbKeyChanged, m_pwDatabase.MasterKeyChanged);
 | 
			
		||||
			WriteObject(ElemDbKeyChangeRec, m_pwDatabase.MasterKeyChangeRec);
 | 
			
		||||
			WriteObject(ElemDbKeyChangeForce, m_pwDatabase.MasterKeyChangeForce);
 | 
			
		||||
 | 
			
		||||
			WriteList(ElemMemoryProt, m_pwDatabase.MemoryProtection);
 | 
			
		||||
 | 
			
		||||
			WriteCustomIconList();
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemRecycleBinEnabled, m_pwDatabase.RecycleBinEnabled);
 | 
			
		||||
			WriteObject(ElemRecycleBinUuid, m_pwDatabase.RecycleBinUuid);
 | 
			
		||||
			WriteObject(ElemRecycleBinChanged, m_pwDatabase.RecycleBinChanged);
 | 
			
		||||
			WriteObject(ElemEntryTemplatesGroup, m_pwDatabase.EntryTemplatesGroup);
 | 
			
		||||
			WriteObject(ElemEntryTemplatesGroupChanged, m_pwDatabase.EntryTemplatesGroupChanged);
 | 
			
		||||
			WriteObject(ElemHistoryMaxItems, m_pwDatabase.HistoryMaxItems);
 | 
			
		||||
			WriteObject(ElemHistoryMaxSize, m_pwDatabase.HistoryMaxSize);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemLastSelectedGroup, m_pwDatabase.LastSelectedGroup);
 | 
			
		||||
			WriteObject(ElemLastTopVisibleGroup, m_pwDatabase.LastTopVisibleGroup);
 | 
			
		||||
 | 
			
		||||
			WriteBinPool();
 | 
			
		||||
			WriteList(ElemCustomData, m_pwDatabase.CustomData);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void StartGroup(PwGroup pg)
 | 
			
		||||
		{
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemGroup);
 | 
			
		||||
			WriteObject(ElemUuid, pg.Uuid);
 | 
			
		||||
			WriteObject(ElemName, pg.Name, true);
 | 
			
		||||
			WriteObject(ElemNotes, pg.Notes, true);
 | 
			
		||||
			WriteObject(ElemIcon, (int)pg.IconId);
 | 
			
		||||
			
 | 
			
		||||
			if(pg.CustomIconUuid != PwUuid.Zero)
 | 
			
		||||
				WriteObject(ElemCustomIconID, pg.CustomIconUuid);
 | 
			
		||||
			
 | 
			
		||||
			WriteList(ElemTimes, pg);
 | 
			
		||||
			WriteObject(ElemIsExpanded, pg.IsExpanded);
 | 
			
		||||
			WriteObject(ElemGroupDefaultAutoTypeSeq, pg.DefaultAutoTypeSequence, true);
 | 
			
		||||
			WriteObject(ElemEnableAutoType, StrUtil.BoolToStringEx(pg.EnableAutoType), false);
 | 
			
		||||
			WriteObject(ElemEnableSearching, StrUtil.BoolToStringEx(pg.EnableSearching), false);
 | 
			
		||||
			WriteObject(ElemLastTopVisibleEntry, pg.LastTopVisibleEntry);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void EndGroup()
 | 
			
		||||
		{
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // Close group element
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteEntry(PwEntry pe, bool bIsHistory)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pe != null); if(pe == null) throw new ArgumentNullException("pe");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemEntry);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemUuid, pe.Uuid);
 | 
			
		||||
			WriteObject(ElemIcon, (int)pe.IconId);
 | 
			
		||||
			
 | 
			
		||||
			if(pe.CustomIconUuid != PwUuid.Zero)
 | 
			
		||||
				WriteObject(ElemCustomIconID, pe.CustomIconUuid);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemFgColor, StrUtil.ColorToUnnamedHtml(pe.ForegroundColor, true), false);
 | 
			
		||||
			WriteObject(ElemBgColor, StrUtil.ColorToUnnamedHtml(pe.BackgroundColor, true), false);
 | 
			
		||||
			WriteObject(ElemOverrideUrl, pe.OverrideUrl, true);
 | 
			
		||||
			WriteObject(ElemTags, StrUtil.TagsToString(pe.Tags, false), true);
 | 
			
		||||
 | 
			
		||||
			WriteList(ElemTimes, pe);
 | 
			
		||||
 | 
			
		||||
			WriteList(pe.Strings, true);
 | 
			
		||||
			WriteList(pe.Binaries);
 | 
			
		||||
			WriteList(ElemAutoType, pe.AutoType);
 | 
			
		||||
 | 
			
		||||
			if(!bIsHistory) WriteList(ElemHistory, pe.History, true);
 | 
			
		||||
			else { Debug.Assert(pe.History.UCount == 0); }
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(ProtectedStringDictionary dictStrings, bool bEntryStrings)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(dictStrings != null);
 | 
			
		||||
			if(dictStrings == null) throw new ArgumentNullException("dictStrings");
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedString> kvp in dictStrings)
 | 
			
		||||
				WriteObject(kvp.Key, kvp.Value, bEntryStrings);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(ProtectedBinaryDictionary dictBinaries)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(dictBinaries != null);
 | 
			
		||||
			if(dictBinaries == null) throw new ArgumentNullException("dictBinaries");
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvp in dictBinaries)
 | 
			
		||||
				WriteObject(kvp.Key, kvp.Value, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(string name, AutoTypeConfig cfgAutoType)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(cfgAutoType != null);
 | 
			
		||||
			if(cfgAutoType == null) throw new ArgumentNullException("cfgAutoType");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemAutoTypeEnabled, cfgAutoType.Enabled);
 | 
			
		||||
			WriteObject(ElemAutoTypeObfuscation, (int)cfgAutoType.ObfuscationOptions);
 | 
			
		||||
 | 
			
		||||
			if(cfgAutoType.DefaultSequence.Length > 0)
 | 
			
		||||
				WriteObject(ElemAutoTypeDefaultSeq, cfgAutoType.DefaultSequence, true);
 | 
			
		||||
 | 
			
		||||
			foreach(AutoTypeAssociation a in cfgAutoType.Associations)
 | 
			
		||||
				WriteObject(ElemAutoTypeItem, ElemWindow, ElemKeystrokeSequence,
 | 
			
		||||
					new KeyValuePair<string, string>(a.WindowName, a.Sequence));
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(string name, ITimeLogger times)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(times != null); if(times == null) throw new ArgumentNullException("times");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemLastModTime, times.LastModificationTime);
 | 
			
		||||
			WriteObject(ElemCreationTime, times.CreationTime);
 | 
			
		||||
			WriteObject(ElemLastAccessTime, times.LastAccessTime);
 | 
			
		||||
			WriteObject(ElemExpiryTime, times.ExpiryTime);
 | 
			
		||||
			WriteObject(ElemExpires, times.Expires);
 | 
			
		||||
			WriteObject(ElemUsageCount, times.UsageCount);
 | 
			
		||||
			WriteObject(ElemLocationChanged, times.LocationChanged);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // Name
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(string name, PwObjectList<PwEntry> value, bool bIsHistory)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			foreach(PwEntry pe in value)
 | 
			
		||||
				WriteEntry(pe, bIsHistory);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(string name, PwObjectList<PwDeletedObject> value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			foreach(PwDeletedObject pdo in value)
 | 
			
		||||
				WriteObject(ElemDeletedObject, pdo);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(string name, MemoryProtectionConfig value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			WriteObject(ElemProtTitle, value.ProtectTitle);
 | 
			
		||||
			WriteObject(ElemProtUserName, value.ProtectUserName);
 | 
			
		||||
			WriteObject(ElemProtPassword, value.ProtectPassword);
 | 
			
		||||
			WriteObject(ElemProtUrl, value.ProtectUrl);
 | 
			
		||||
			WriteObject(ElemProtNotes, value.ProtectNotes);
 | 
			
		||||
			// WriteObject(ElemProtAutoHide, value.AutoEnableVisualHiding);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteList(string name, StringDictionaryEx value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, string> kvp in value)
 | 
			
		||||
				WriteObject(ElemStringDictExItem, ElemKey, ElemValue, kvp);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteCustomIconList()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_pwDatabase.CustomIcons.Count == 0) return;
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemCustomIcons);
 | 
			
		||||
 | 
			
		||||
			foreach(PwCustomIcon pwci in m_pwDatabase.CustomIcons)
 | 
			
		||||
			{
 | 
			
		||||
				m_xmlWriter.WriteStartElement(ElemCustomIconItem);
 | 
			
		||||
 | 
			
		||||
				WriteObject(ElemCustomIconItemID, pwci.Uuid);
 | 
			
		||||
 | 
			
		||||
				string strData = Convert.ToBase64String(pwci.ImageDataPng);
 | 
			
		||||
				WriteObject(ElemCustomIconItemData, strData, false);
 | 
			
		||||
 | 
			
		||||
				m_xmlWriter.WriteEndElement();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, string value,
 | 
			
		||||
			bool bFilterValueXmlChars)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			if(bFilterValueXmlChars)
 | 
			
		||||
				m_xmlWriter.WriteString(StrUtil.SafeXmlString(value));
 | 
			
		||||
			else m_xmlWriter.WriteString(value);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, bool value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
 | 
			
		||||
			WriteObject(name, value ? ValTrue : ValFalse, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, PwUuid value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			WriteObject(name, Convert.ToBase64String(value.UuidBytes), false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, int value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
			m_xmlWriter.WriteString(value.ToString());
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, uint value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
			m_xmlWriter.WriteString(value.ToString());
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, long value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
			m_xmlWriter.WriteString(value.ToString());
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, ulong value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
			m_xmlWriter.WriteString(value.ToString());
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, DateTime value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
 | 
			
		||||
			WriteObject(name, TimeUtil.SerializeUtc(value), false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, string strKeyName,
 | 
			
		||||
			string strValueName, KeyValuePair<string, string> kvp)
 | 
			
		||||
		{
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(strKeyName);
 | 
			
		||||
			m_xmlWriter.WriteString(StrUtil.SafeXmlString(kvp.Key));
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
			m_xmlWriter.WriteStartElement(strValueName);
 | 
			
		||||
			m_xmlWriter.WriteString(StrUtil.SafeXmlString(kvp.Value));
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, ProtectedString value, bool bIsEntryString)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemString);
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemKey);
 | 
			
		||||
			m_xmlWriter.WriteString(StrUtil.SafeXmlString(name));
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemValue);
 | 
			
		||||
 | 
			
		||||
			bool bProtected = value.IsProtected;
 | 
			
		||||
			if(bIsEntryString)
 | 
			
		||||
			{
 | 
			
		||||
				// Adjust memory protection setting (which might be different
 | 
			
		||||
				// from the database default, e.g. due to an import which
 | 
			
		||||
				// didn't specify the correct setting)
 | 
			
		||||
				if(name == PwDefs.TitleField)
 | 
			
		||||
					bProtected = m_pwDatabase.MemoryProtection.ProtectTitle;
 | 
			
		||||
				else if(name == PwDefs.UserNameField)
 | 
			
		||||
					bProtected = m_pwDatabase.MemoryProtection.ProtectUserName;
 | 
			
		||||
				else if(name == PwDefs.PasswordField)
 | 
			
		||||
					bProtected = m_pwDatabase.MemoryProtection.ProtectPassword;
 | 
			
		||||
				else if(name == PwDefs.UrlField)
 | 
			
		||||
					bProtected = m_pwDatabase.MemoryProtection.ProtectUrl;
 | 
			
		||||
				else if(name == PwDefs.NotesField)
 | 
			
		||||
					bProtected = m_pwDatabase.MemoryProtection.ProtectNotes;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(bProtected && (m_format != KdbxFormat.PlainXml))
 | 
			
		||||
			{
 | 
			
		||||
				m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
 | 
			
		||||
 | 
			
		||||
				byte[] pbEncoded = value.ReadXorredString(m_randomStream);
 | 
			
		||||
				if(pbEncoded.Length > 0)
 | 
			
		||||
					m_xmlWriter.WriteBase64(pbEncoded, 0, pbEncoded.Length);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				string strValue = value.ReadString();
 | 
			
		||||
 | 
			
		||||
				// If names should be localized, we need to apply the language-dependent
 | 
			
		||||
				// string transformation here. By default, language-dependent conversions
 | 
			
		||||
				// should be applied, otherwise characters could be rendered incorrectly
 | 
			
		||||
				// (code page problems).
 | 
			
		||||
				if(m_bLocalizedNames)
 | 
			
		||||
				{
 | 
			
		||||
					StringBuilder sb = new StringBuilder();
 | 
			
		||||
					foreach(char ch in strValue)
 | 
			
		||||
					{
 | 
			
		||||
						char chMapped = ch;
 | 
			
		||||
 | 
			
		||||
						// Symbols and surrogates must be moved into the correct code
 | 
			
		||||
						// page area
 | 
			
		||||
						if(char.IsSymbol(ch) || char.IsSurrogate(ch))
 | 
			
		||||
						{
 | 
			
		||||
							System.Globalization.UnicodeCategory cat = char.GetUnicodeCategory(ch);
 | 
			
		||||
							// Map character to correct position in code page
 | 
			
		||||
							chMapped = (char)((int)cat * 32 + ch);
 | 
			
		||||
						}
 | 
			
		||||
						else if(char.IsControl(ch))
 | 
			
		||||
						{
 | 
			
		||||
							if(ch >= 256) // Control character in high ANSI code page
 | 
			
		||||
							{
 | 
			
		||||
								// Some of the control characters map to corresponding ones
 | 
			
		||||
								// in the low ANSI range (up to 255) when calling
 | 
			
		||||
								// ToLower on them with invariant culture (see
 | 
			
		||||
								// http://lists.ximian.com/pipermail/mono-patches/2002-February/086106.html )
 | 
			
		||||
								chMapped = char.ToLower(ch, CultureInfo.InvariantCulture);
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						sb.Append(chMapped);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					strValue = sb.ToString(); // Correct string for current code page
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if((m_format == KdbxFormat.PlainXml) && bProtected)
 | 
			
		||||
					m_xmlWriter.WriteAttributeString(AttrProtectedInMemPlainXml, ValTrue);
 | 
			
		||||
 | 
			
		||||
				m_xmlWriter.WriteString(StrUtil.SafeXmlString(strValue));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // ElemValue
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // ElemString
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, ProtectedBinary value, bool bAllowRef)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemBinary);
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemKey);
 | 
			
		||||
			m_xmlWriter.WriteString(StrUtil.SafeXmlString(name));
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemValue);
 | 
			
		||||
 | 
			
		||||
			string strRef = (bAllowRef ? BinPoolFind(value) : null);
 | 
			
		||||
			if(strRef != null)
 | 
			
		||||
			{
 | 
			
		||||
				m_xmlWriter.WriteAttributeString(AttrRef, strRef);
 | 
			
		||||
			}
 | 
			
		||||
			else SubWriteValue(value);
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // ElemValue
 | 
			
		||||
			m_xmlWriter.WriteEndElement(); // ElemBinary
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void SubWriteValue(ProtectedBinary value)
 | 
			
		||||
		{
 | 
			
		||||
			if(value.IsProtected && (m_format != KdbxFormat.PlainXml))
 | 
			
		||||
			{
 | 
			
		||||
				m_xmlWriter.WriteAttributeString(AttrProtected, ValTrue);
 | 
			
		||||
 | 
			
		||||
				byte[] pbEncoded = value.ReadXorredData(m_randomStream);
 | 
			
		||||
				if(pbEncoded.Length > 0)
 | 
			
		||||
					m_xmlWriter.WriteBase64(pbEncoded, 0, pbEncoded.Length);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip)
 | 
			
		||||
				{
 | 
			
		||||
					m_xmlWriter.WriteAttributeString(AttrCompressed, ValTrue);
 | 
			
		||||
 | 
			
		||||
					byte[] pbRaw = value.ReadData();
 | 
			
		||||
					byte[] pbCmp = MemUtil.Compress(pbRaw);
 | 
			
		||||
					m_xmlWriter.WriteBase64(pbCmp, 0, pbCmp.Length);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					byte[] pbRaw = value.ReadData();
 | 
			
		||||
					m_xmlWriter.WriteBase64(pbRaw, 0, pbRaw.Length);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteObject(string name, PwDeletedObject value)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(name != null);
 | 
			
		||||
			Debug.Assert(value != null); if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteStartElement(name);
 | 
			
		||||
			WriteObject(ElemUuid, value.Uuid);
 | 
			
		||||
			WriteObject(ElemDeletionTime, value.DeletionTime);
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void WriteBinPool()
 | 
			
		||||
		{
 | 
			
		||||
			m_xmlWriter.WriteStartElement(ElemBinaries);
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvp in m_dictBinPool)
 | 
			
		||||
			{
 | 
			
		||||
				m_xmlWriter.WriteStartElement(ElemBinary);
 | 
			
		||||
				m_xmlWriter.WriteAttributeString(AttrId, kvp.Key);
 | 
			
		||||
				SubWriteValue(kvp.Value);
 | 
			
		||||
				m_xmlWriter.WriteEndElement();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_xmlWriter.WriteEndElement();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		[Obsolete]
 | 
			
		||||
		public static bool WriteEntries(Stream msOutput, PwDatabase pwDatabase,
 | 
			
		||||
			PwEntry[] vEntries)
 | 
			
		||||
		{
 | 
			
		||||
			return WriteEntries(msOutput, vEntries);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Write entries to a stream.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="msOutput">Output stream to which the entries will be written.</param>
 | 
			
		||||
		/// <param name="vEntries">Entries to serialize.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c>, if the entries were written successfully
 | 
			
		||||
		/// to the stream.</returns>
 | 
			
		||||
		public static bool WriteEntries(Stream msOutput, PwEntry[] vEntries)
 | 
			
		||||
		{
 | 
			
		||||
			/* KdbxFile f = new KdbxFile(pwDatabase);
 | 
			
		||||
			f.m_format = KdbxFormat.PlainXml;
 | 
			
		||||
 | 
			
		||||
			XmlTextWriter xtw = null;
 | 
			
		||||
			try { xtw = new XmlTextWriter(msOutput, StrUtil.Utf8); }
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); return false; }
 | 
			
		||||
			if(xtw == null) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			f.m_xmlWriter = xtw;
 | 
			
		||||
 | 
			
		||||
			xtw.Formatting = Formatting.Indented;
 | 
			
		||||
			xtw.IndentChar = '\t';
 | 
			
		||||
			xtw.Indentation = 1;
 | 
			
		||||
 | 
			
		||||
			xtw.WriteStartDocument(true);
 | 
			
		||||
			xtw.WriteStartElement(ElemRoot);
 | 
			
		||||
 | 
			
		||||
			foreach(PwEntry pe in vEntries)
 | 
			
		||||
				f.WriteEntry(pe, false);
 | 
			
		||||
 | 
			
		||||
			xtw.WriteEndElement();
 | 
			
		||||
			xtw.WriteEndDocument();
 | 
			
		||||
 | 
			
		||||
			xtw.Flush();
 | 
			
		||||
			xtw.Close();
 | 
			
		||||
			return true; */
 | 
			
		||||
 | 
			
		||||
			PwDatabase pd = new PwDatabase();
 | 
			
		||||
			pd.New(new IOConnectionInfo(), new CompositeKey());
 | 
			
		||||
 | 
			
		||||
			foreach(PwEntry peCopy in vEntries)
 | 
			
		||||
				pd.RootGroup.AddEntry(peCopy.CloneDeep(), true);
 | 
			
		||||
 | 
			
		||||
			KdbxFile f = new KdbxFile(pd);
 | 
			
		||||
			f.Save(msOutput, null, KdbxFormat.PlainXml, null);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										390
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								src/KeePassLib2Android/Serialization/KdbxFile.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,390 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.IO.Compression;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Collections;
 | 
			
		||||
using KeePassLib.Cryptography;
 | 
			
		||||
using KeePassLib.Delegates;
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Security;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// The <c>KdbxFile</c> class supports saving the data to various
 | 
			
		||||
	/// formats.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public enum KdbxFormat
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The default, encrypted file format.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		Default = 0,
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Use this flag when exporting data to a plain-text XML file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		PlainXml
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Serialization to KeePass KDBX files.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public sealed partial class KdbxFile
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// File identifier, first 32-bit value.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private const uint FileSignature1 = 0x9AA2D903;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// File identifier, second 32-bit value.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private const uint FileSignature2 = 0xB54BFB67;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// File version of files saved by the current <c>KdbxFile</c> class.
 | 
			
		||||
		/// 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, 2.20 has 3.01.
 | 
			
		||||
		/// The first 2 bytes are critical (i.e. loading will fail, if the
 | 
			
		||||
		/// file version is too high), the last 2 bytes are informational.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		private const uint FileVersion32 = 0x00030001;
 | 
			
		||||
 | 
			
		||||
		private const uint FileVersionCriticalMask = 0xFFFF0000;
 | 
			
		||||
 | 
			
		||||
		// KeePass 1.x signature
 | 
			
		||||
		private const uint FileSignatureOld1 = 0x9AA2D903;
 | 
			
		||||
		private const uint FileSignatureOld2 = 0xB54BFB65;
 | 
			
		||||
		// KeePass 2.x pre-release (alpha and beta) signature
 | 
			
		||||
		private const uint FileSignaturePreRelease1 = 0x9AA2D903;
 | 
			
		||||
		private const uint FileSignaturePreRelease2 = 0xB54BFB66;
 | 
			
		||||
 | 
			
		||||
		private const string ElemDocNode = "KeePassFile";
 | 
			
		||||
		private const string ElemMeta = "Meta";
 | 
			
		||||
		private const string ElemRoot = "Root";
 | 
			
		||||
		private const string ElemGroup = "Group";
 | 
			
		||||
		private const string ElemEntry = "Entry";
 | 
			
		||||
 | 
			
		||||
		private const string ElemGenerator = "Generator";
 | 
			
		||||
		private const string ElemHeaderHash = "HeaderHash";
 | 
			
		||||
		private const string ElemDbName = "DatabaseName";
 | 
			
		||||
		private const string ElemDbNameChanged = "DatabaseNameChanged";
 | 
			
		||||
		private const string ElemDbDesc = "DatabaseDescription";
 | 
			
		||||
		private const string ElemDbDescChanged = "DatabaseDescriptionChanged";
 | 
			
		||||
		private const string ElemDbDefaultUser = "DefaultUserName";
 | 
			
		||||
		private const string ElemDbDefaultUserChanged = "DefaultUserNameChanged";
 | 
			
		||||
		private const string ElemDbMntncHistoryDays = "MaintenanceHistoryDays";
 | 
			
		||||
		private const string ElemDbColor = "Color";
 | 
			
		||||
		private const string ElemDbKeyChanged = "MasterKeyChanged";
 | 
			
		||||
		private const string ElemDbKeyChangeRec = "MasterKeyChangeRec";
 | 
			
		||||
		private const string ElemDbKeyChangeForce = "MasterKeyChangeForce";
 | 
			
		||||
		private const string ElemRecycleBinEnabled = "RecycleBinEnabled";
 | 
			
		||||
		private const string ElemRecycleBinUuid = "RecycleBinUUID";
 | 
			
		||||
		private const string ElemRecycleBinChanged = "RecycleBinChanged";
 | 
			
		||||
		private const string ElemEntryTemplatesGroup = "EntryTemplatesGroup";
 | 
			
		||||
		private const string ElemEntryTemplatesGroupChanged = "EntryTemplatesGroupChanged";
 | 
			
		||||
		private const string ElemHistoryMaxItems = "HistoryMaxItems";
 | 
			
		||||
		private const string ElemHistoryMaxSize = "HistoryMaxSize";
 | 
			
		||||
		private const string ElemLastSelectedGroup = "LastSelectedGroup";
 | 
			
		||||
		private const string ElemLastTopVisibleGroup = "LastTopVisibleGroup";
 | 
			
		||||
 | 
			
		||||
		private const string ElemMemoryProt = "MemoryProtection";
 | 
			
		||||
		private const string ElemProtTitle = "ProtectTitle";
 | 
			
		||||
		private const string ElemProtUserName = "ProtectUserName";
 | 
			
		||||
		private const string ElemProtPassword = "ProtectPassword";
 | 
			
		||||
		private const string ElemProtUrl = "ProtectURL";
 | 
			
		||||
		private const string ElemProtNotes = "ProtectNotes";
 | 
			
		||||
		// private const string ElemProtAutoHide = "AutoEnableVisualHiding";
 | 
			
		||||
 | 
			
		||||
		private const string ElemCustomIcons = "CustomIcons";
 | 
			
		||||
		private const string ElemCustomIconItem = "Icon";
 | 
			
		||||
		private const string ElemCustomIconItemID = "UUID";
 | 
			
		||||
		private const string ElemCustomIconItemData = "Data";
 | 
			
		||||
 | 
			
		||||
		private const string ElemAutoType = "AutoType";
 | 
			
		||||
		private const string ElemHistory = "History";
 | 
			
		||||
 | 
			
		||||
		private const string ElemName = "Name";
 | 
			
		||||
		private const string ElemNotes = "Notes";
 | 
			
		||||
		private const string ElemUuid = "UUID";
 | 
			
		||||
		private const string ElemIcon = "IconID";
 | 
			
		||||
		private const string ElemCustomIconID = "CustomIconUUID";
 | 
			
		||||
		private const string ElemFgColor = "ForegroundColor";
 | 
			
		||||
		private const string ElemBgColor = "BackgroundColor";
 | 
			
		||||
		private const string ElemOverrideUrl = "OverrideURL";
 | 
			
		||||
		private const string ElemTimes = "Times";
 | 
			
		||||
		private const string ElemTags = "Tags";
 | 
			
		||||
 | 
			
		||||
		private const string ElemCreationTime = "CreationTime";
 | 
			
		||||
		private const string ElemLastModTime = "LastModificationTime";
 | 
			
		||||
		private const string ElemLastAccessTime = "LastAccessTime";
 | 
			
		||||
		private const string ElemExpiryTime = "ExpiryTime";
 | 
			
		||||
		private const string ElemExpires = "Expires";
 | 
			
		||||
		private const string ElemUsageCount = "UsageCount";
 | 
			
		||||
		private const string ElemLocationChanged = "LocationChanged";
 | 
			
		||||
 | 
			
		||||
		private const string ElemGroupDefaultAutoTypeSeq = "DefaultAutoTypeSequence";
 | 
			
		||||
		private const string ElemEnableAutoType = "EnableAutoType";
 | 
			
		||||
		private const string ElemEnableSearching = "EnableSearching";
 | 
			
		||||
 | 
			
		||||
		private const string ElemString = "String";
 | 
			
		||||
		private const string ElemBinary = "Binary";
 | 
			
		||||
		private const string ElemKey = "Key";
 | 
			
		||||
		private const string ElemValue = "Value";
 | 
			
		||||
 | 
			
		||||
		private const string ElemAutoTypeEnabled = "Enabled";
 | 
			
		||||
		private const string ElemAutoTypeObfuscation = "DataTransferObfuscation";
 | 
			
		||||
		private const string ElemAutoTypeDefaultSeq = "DefaultSequence";
 | 
			
		||||
		private const string ElemAutoTypeItem = "Association";
 | 
			
		||||
		private const string ElemWindow = "Window";
 | 
			
		||||
		private const string ElemKeystrokeSequence = "KeystrokeSequence";
 | 
			
		||||
 | 
			
		||||
		private const string ElemBinaries = "Binaries";
 | 
			
		||||
 | 
			
		||||
		private const string AttrId = "ID";
 | 
			
		||||
		private const string AttrRef = "Ref";
 | 
			
		||||
		private const string AttrProtected = "Protected";
 | 
			
		||||
		private const string AttrProtectedInMemPlainXml = "ProtectInMemory";
 | 
			
		||||
		private const string AttrCompressed = "Compressed";
 | 
			
		||||
 | 
			
		||||
		private const string ElemIsExpanded = "IsExpanded";
 | 
			
		||||
		private const string ElemLastTopVisibleEntry = "LastTopVisibleEntry";
 | 
			
		||||
 | 
			
		||||
		private const string ElemDeletedObjects = "DeletedObjects";
 | 
			
		||||
		private const string ElemDeletedObject = "DeletedObject";
 | 
			
		||||
		private const string ElemDeletionTime = "DeletionTime";
 | 
			
		||||
 | 
			
		||||
		private const string ValFalse = "False";
 | 
			
		||||
		private const string ValTrue = "True";
 | 
			
		||||
 | 
			
		||||
		private const string ElemCustomData = "CustomData";
 | 
			
		||||
		private const string ElemStringDictExItem = "Item";
 | 
			
		||||
 | 
			
		||||
		private PwDatabase m_pwDatabase; // Not null, see constructor
 | 
			
		||||
 | 
			
		||||
		private XmlTextWriter m_xmlWriter = null;
 | 
			
		||||
		private CryptoRandomStream m_randomStream = null;
 | 
			
		||||
		private KdbxFormat m_format = KdbxFormat.Default;
 | 
			
		||||
		private IStatusLogger m_slLogger = null;
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbMasterSeed = null;
 | 
			
		||||
		private byte[] m_pbTransformSeed = null;
 | 
			
		||||
		private byte[] m_pbEncryptionIV = null;
 | 
			
		||||
		private byte[] m_pbProtectedStreamKey = null;
 | 
			
		||||
		private byte[] m_pbStreamStartBytes = null;
 | 
			
		||||
 | 
			
		||||
		// ArcFourVariant only for compatibility; KeePass will default to a
 | 
			
		||||
		// different (more secure) algorithm when *writing* databases
 | 
			
		||||
		private CrsAlgorithm m_craInnerRandomStream = CrsAlgorithm.ArcFourVariant;
 | 
			
		||||
 | 
			
		||||
		private Dictionary<string, ProtectedBinary> m_dictBinPool =
 | 
			
		||||
			new Dictionary<string, ProtectedBinary>();
 | 
			
		||||
 | 
			
		||||
		private byte[] m_pbHashOfHeader = null;
 | 
			
		||||
		private byte[] m_pbHashOfFileOnDisk = null;
 | 
			
		||||
 | 
			
		||||
		private readonly DateTime m_dtNow = DateTime.Now; // Cache current time
 | 
			
		||||
 | 
			
		||||
		private const uint NeutralLanguageOffset = 0x100000; // 2^20, see 32-bit Unicode specs
 | 
			
		||||
		private const uint NeutralLanguageIDSec = 0x7DC5C; // See 32-bit Unicode specs
 | 
			
		||||
		private const uint NeutralLanguageID = NeutralLanguageOffset + NeutralLanguageIDSec;
 | 
			
		||||
		private static bool m_bLocalizedNames = false;
 | 
			
		||||
 | 
			
		||||
		private enum KdbxHeaderFieldID : byte
 | 
			
		||||
		{
 | 
			
		||||
			EndOfHeader = 0,
 | 
			
		||||
			Comment = 1,
 | 
			
		||||
			CipherID = 2,
 | 
			
		||||
			CompressionFlags = 3,
 | 
			
		||||
			MasterSeed = 4,
 | 
			
		||||
			TransformSeed = 5,
 | 
			
		||||
			TransformRounds = 6,
 | 
			
		||||
			EncryptionIV = 7,
 | 
			
		||||
			ProtectedStreamKey = 8,
 | 
			
		||||
			StreamStartBytes = 9,
 | 
			
		||||
			InnerRandomStreamID = 10
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public byte[] HashOfFileOnDisk
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_pbHashOfFileOnDisk; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bRepairMode = false;
 | 
			
		||||
		public bool RepairMode
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bRepairMode; }
 | 
			
		||||
			set { m_bRepairMode = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strDetachBins = null;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Detach binaries when opening a file. If this isn't <c>null</c>,
 | 
			
		||||
		/// all binaries are saved to the specified path and are removed
 | 
			
		||||
		/// from the database.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public string DetachBinaries
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strDetachBins; }
 | 
			
		||||
			set { m_strDetachBins = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Default constructor.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pwDataStore">The <c>PwDatabase</c> instance that the
 | 
			
		||||
		/// class will load file data into or use to create a KDBX file.</param>
 | 
			
		||||
		public KdbxFile(PwDatabase pwDataStore)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pwDataStore != null);
 | 
			
		||||
			if(pwDataStore == null) throw new ArgumentNullException("pwDataStore");
 | 
			
		||||
 | 
			
		||||
			m_pwDatabase = pwDataStore;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Call this once to determine the current localization settings.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static void DetermineLanguageId()
 | 
			
		||||
		{
 | 
			
		||||
			// Test if localized names should be used. If localized names are used,
 | 
			
		||||
			// the m_bLocalizedNames value must be set to true. By default, localized
 | 
			
		||||
			// names should be used! (Otherwise characters could be corrupted
 | 
			
		||||
			// because of different code pages).
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				uint uTest = 0;
 | 
			
		||||
				foreach(char ch in PwDatabase.LocalizedAppName)
 | 
			
		||||
					uTest = uTest * 5 + ch;
 | 
			
		||||
 | 
			
		||||
				m_bLocalizedNames = (uTest != NeutralLanguageID);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void BinPoolBuild(PwGroup pgDataSource)
 | 
			
		||||
		{
 | 
			
		||||
			m_dictBinPool = new Dictionary<string, ProtectedBinary>();
 | 
			
		||||
 | 
			
		||||
			if(pgDataSource == null) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			EntryHandler eh = delegate(PwEntry pe)
 | 
			
		||||
			{
 | 
			
		||||
				foreach(PwEntry peHistory in pe.History)
 | 
			
		||||
				{
 | 
			
		||||
					BinPoolAdd(peHistory.Binaries);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				BinPoolAdd(pe.Binaries);
 | 
			
		||||
				return true;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			pgDataSource.TraverseTree(TraversalMethod.PreOrder, null, eh);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void BinPoolAdd(ProtectedBinaryDictionary dict)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvp in dict)
 | 
			
		||||
			{
 | 
			
		||||
				BinPoolAdd(kvp.Value);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void BinPoolAdd(ProtectedBinary pb)
 | 
			
		||||
		{
 | 
			
		||||
			if(pb == null) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			if(BinPoolFind(pb) != null) return; // Exists already
 | 
			
		||||
 | 
			
		||||
			m_dictBinPool.Add(m_dictBinPool.Count.ToString(), pb);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string BinPoolFind(ProtectedBinary pb)
 | 
			
		||||
		{
 | 
			
		||||
			if(pb == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			foreach(KeyValuePair<string, ProtectedBinary> kvp in m_dictBinPool)
 | 
			
		||||
			{
 | 
			
		||||
				if(pb.Equals(kvp.Value)) return kvp.Key;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private ProtectedBinary BinPoolGet(string strKey)
 | 
			
		||||
		{
 | 
			
		||||
			if(strKey == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			ProtectedBinary pb;
 | 
			
		||||
			if(m_dictBinPool.TryGetValue(strKey, out pb)) return pb;
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void SaveBinary(string strName, ProtectedBinary pb,
 | 
			
		||||
			string strSaveDir)
 | 
			
		||||
		{
 | 
			
		||||
			if(pb == null) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			if(string.IsNullOrEmpty(strName)) strName = "File.bin";
 | 
			
		||||
 | 
			
		||||
			string strPath;
 | 
			
		||||
			int iTry = 1;
 | 
			
		||||
			do
 | 
			
		||||
			{
 | 
			
		||||
				strPath = UrlUtil.EnsureTerminatingSeparator(strSaveDir, false);
 | 
			
		||||
 | 
			
		||||
				string strExt = UrlUtil.GetExtension(strName);
 | 
			
		||||
				string strDesc = UrlUtil.StripExtension(strName);
 | 
			
		||||
 | 
			
		||||
				strPath += strDesc;
 | 
			
		||||
				if(iTry > 1) strPath += " (" + iTry.ToString() + ")";
 | 
			
		||||
 | 
			
		||||
				if(!string.IsNullOrEmpty(strExt)) strPath += "." + strExt;
 | 
			
		||||
 | 
			
		||||
				++iTry;
 | 
			
		||||
			}
 | 
			
		||||
			while(File.Exists(strPath));
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			byte[] pbData = pb.ReadData();
 | 
			
		||||
			File.WriteAllBytes(strPath, pbData);
 | 
			
		||||
			MemUtil.ZeroByteArray(pbData);
 | 
			
		||||
#else
 | 
			
		||||
			FileStream fs = new FileStream(strPath, FileMode.Create,
 | 
			
		||||
				FileAccess.Write, FileShare.None);
 | 
			
		||||
			byte[] pbData = pb.ReadData();
 | 
			
		||||
			fs.Write(pbData, 0, pbData.Length);
 | 
			
		||||
			fs.Close();
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								src/KeePassLib2Android/Serialization/OldFormatException.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/KeePassLib2Android/Serialization/OldFormatException.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Serialization
 | 
			
		||||
{
 | 
			
		||||
	public sealed class OldFormatException : Exception
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strFormat = string.Empty;
 | 
			
		||||
		private OldFormatType m_type = OldFormatType.Unknown;
 | 
			
		||||
 | 
			
		||||
		public enum OldFormatType
 | 
			
		||||
		{
 | 
			
		||||
			Unknown = 0,
 | 
			
		||||
			KeePass1x = 1
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public override string Message
 | 
			
		||||
		{
 | 
			
		||||
			get
 | 
			
		||||
			{
 | 
			
		||||
				string str = KLRes.OldFormat + ((m_strFormat.Length > 0) ?
 | 
			
		||||
					(@" (" + m_strFormat + @")") : string.Empty) + ".";
 | 
			
		||||
 | 
			
		||||
				if(m_type == OldFormatType.KeePass1x)
 | 
			
		||||
					str += MessageService.NewParagraph + KLRes.KeePass1xHint;
 | 
			
		||||
 | 
			
		||||
				return str;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public OldFormatException(string strFormatName)
 | 
			
		||||
		{
 | 
			
		||||
			if(strFormatName != null) m_strFormat = strFormatName;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public OldFormatException(string strFormatName, OldFormatType t)
 | 
			
		||||
		{
 | 
			
		||||
			if(strFormatName != null) m_strFormat = strFormatName;
 | 
			
		||||
 | 
			
		||||
			m_type = t;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										400
									
								
								src/KeePassLib2Android/Translation/KPControlCustomization.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								src/KeePassLib2Android/Translation/KPControlCustomization.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,400 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Windows.Forms;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.Globalization;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Translation
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KpccLayout
 | 
			
		||||
	{
 | 
			
		||||
		public enum LayoutParameterEx
 | 
			
		||||
		{
 | 
			
		||||
			X, Y, Width, Height
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private const string m_strControlRelative = @"%c";
 | 
			
		||||
 | 
			
		||||
		internal const NumberStyles m_nsParser = NumberStyles.AllowLeadingSign |
 | 
			
		||||
			NumberStyles.AllowDecimalPoint;
 | 
			
		||||
		internal static readonly CultureInfo m_lclInv = CultureInfo.InvariantCulture;
 | 
			
		||||
 | 
			
		||||
		private string m_strPosX = string.Empty;
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string X
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strPosX; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strPosX = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strPosY = string.Empty;
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Y
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strPosY; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strPosY = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strSizeW = string.Empty;
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Width
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strSizeW; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strSizeW = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strSizeH = string.Empty;
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Height
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strSizeH; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strSizeH = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void SetControlRelativeValue(LayoutParameterEx lp, string strValue)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strValue != null);
 | 
			
		||||
			if(strValue == null) throw new ArgumentNullException("strValue");
 | 
			
		||||
 | 
			
		||||
			if(strValue.Length > 0) strValue += m_strControlRelative;
 | 
			
		||||
 | 
			
		||||
			if(lp == LayoutParameterEx.X) m_strPosX = strValue;
 | 
			
		||||
			else if(lp == LayoutParameterEx.Y) m_strPosY = strValue;
 | 
			
		||||
			else if(lp == LayoutParameterEx.Width) m_strSizeW = strValue;
 | 
			
		||||
			else if(lp == LayoutParameterEx.Height) m_strSizeH = strValue;
 | 
			
		||||
			else { Debug.Assert(false); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		internal void ApplyTo(Control c)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(c != null); if(c == null) return;
 | 
			
		||||
 | 
			
		||||
			int? v;
 | 
			
		||||
			v = GetModControlParameter(c, LayoutParameterEx.X, m_strPosX);
 | 
			
		||||
			if(v.HasValue) c.Left = v.Value;
 | 
			
		||||
			v = GetModControlParameter(c, LayoutParameterEx.Y, m_strPosY);
 | 
			
		||||
			if(v.HasValue) c.Top = v.Value;
 | 
			
		||||
			v = GetModControlParameter(c, LayoutParameterEx.Width, m_strSizeW);
 | 
			
		||||
			if(v.HasValue) c.Width = v.Value;
 | 
			
		||||
			v = GetModControlParameter(c, LayoutParameterEx.Height, m_strSizeH);
 | 
			
		||||
			if(v.HasValue) c.Height = v.Value;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static int? GetModControlParameter(Control c, LayoutParameterEx p,
 | 
			
		||||
			string strModParam)
 | 
			
		||||
		{
 | 
			
		||||
			if(strModParam.Length == 0) return null;
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(c.Left == c.Location.X);
 | 
			
		||||
			Debug.Assert(c.Top == c.Location.Y);
 | 
			
		||||
			Debug.Assert(c.Width == c.Size.Width);
 | 
			
		||||
			Debug.Assert(c.Height == c.Size.Height);
 | 
			
		||||
 | 
			
		||||
			int iPrev;
 | 
			
		||||
			if(p == LayoutParameterEx.X) iPrev = c.Left;
 | 
			
		||||
			else if(p == LayoutParameterEx.Y) iPrev = c.Top;
 | 
			
		||||
			else if(p == LayoutParameterEx.Width) iPrev = c.Width;
 | 
			
		||||
			else if(p == LayoutParameterEx.Height) iPrev = c.Height;
 | 
			
		||||
			else { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			double? dRel = ToControlRelativePercent(strModParam);
 | 
			
		||||
			if(dRel.HasValue)
 | 
			
		||||
				return (iPrev + (int)((dRel.Value * (double)iPrev) / 100.0));
 | 
			
		||||
			
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static double? ToControlRelativePercent(string strEncoded)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strEncoded != null);
 | 
			
		||||
			if(strEncoded == null) throw new ArgumentNullException("strEncoded");
 | 
			
		||||
 | 
			
		||||
			if(strEncoded.Length == 0) return null;
 | 
			
		||||
 | 
			
		||||
			if(strEncoded.EndsWith(m_strControlRelative))
 | 
			
		||||
			{
 | 
			
		||||
				string strValue = strEncoded.Substring(0, strEncoded.Length -
 | 
			
		||||
					m_strControlRelative.Length);
 | 
			
		||||
				if((strValue.Length == 1) && (strValue == "-"))
 | 
			
		||||
					strValue = "0";
 | 
			
		||||
 | 
			
		||||
				double dRel;
 | 
			
		||||
				if(double.TryParse(strValue, m_nsParser, m_lclInv, out dRel))
 | 
			
		||||
				{
 | 
			
		||||
					return dRel;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Debug.Assert(false);
 | 
			
		||||
					return null;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		public static string ToControlRelativeString(string strEncoded)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strEncoded != null);
 | 
			
		||||
			if(strEncoded == null) throw new ArgumentNullException("strEncoded");
 | 
			
		||||
 | 
			
		||||
			if(strEncoded.Length == 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			if(strEncoded.EndsWith(m_strControlRelative))
 | 
			
		||||
				return strEncoded.Substring(0, strEncoded.Length -
 | 
			
		||||
					m_strControlRelative.Length);
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return string.Empty;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public sealed class KPControlCustomization : IComparable<KPControlCustomization>
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strMemberName = string.Empty;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Member variable name of the control to be translated.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		public string Name
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strMemberName; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strMemberName = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strHash = string.Empty;
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		public string BaseHash
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strHash; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strHash = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strText = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string Text
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strText; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strText = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strEngText = string.Empty;
 | 
			
		||||
		[XmlIgnore]
 | 
			
		||||
		public string TextEnglish
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strEngText; }
 | 
			
		||||
			set { m_strEngText = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private KpccLayout m_layout = new KpccLayout();
 | 
			
		||||
		public KpccLayout Layout
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_layout; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_layout = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public int CompareTo(KPControlCustomization kpOther)
 | 
			
		||||
		{
 | 
			
		||||
			if(kpOther == null) { Debug.Assert(false); return 1; }
 | 
			
		||||
 | 
			
		||||
			return m_strMemberName.CompareTo(kpOther.Name);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		private static readonly Type[] m_vTextControls = new Type[] {
 | 
			
		||||
			typeof(MenuStrip), typeof(PictureBox), typeof(ListView),
 | 
			
		||||
			typeof(TreeView), typeof(ToolStrip), typeof(WebBrowser),
 | 
			
		||||
			typeof(Panel), typeof(StatusStrip), typeof(ProgressBar),
 | 
			
		||||
			typeof(NumericUpDown), typeof(TabControl)
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		public static bool ControlSupportsText(object oControl)
 | 
			
		||||
		{
 | 
			
		||||
			if(oControl == null) return false;
 | 
			
		||||
 | 
			
		||||
			Type t = oControl.GetType();
 | 
			
		||||
			for(int i = 0; i < m_vTextControls.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(t == m_vTextControls[i]) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Name-unchecked (!) property application method
 | 
			
		||||
		internal void ApplyTo(Control c)
 | 
			
		||||
		{
 | 
			
		||||
			if((m_strText.Length > 0) && ControlSupportsText(c) &&
 | 
			
		||||
				(c.Text.Length > 0))
 | 
			
		||||
			{
 | 
			
		||||
				c.Text = m_strText;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			m_layout.ApplyTo(c);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string HashControl(Control c)
 | 
			
		||||
		{
 | 
			
		||||
			if(c == null) { Debug.Assert(false); return string.Empty; }
 | 
			
		||||
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
			WriteCpiParam(sb, c.Text);
 | 
			
		||||
 | 
			
		||||
			if(c is Form)
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, c.ClientSize.Width.ToString());
 | 
			
		||||
				WriteCpiParam(sb, c.ClientSize.Height.ToString());
 | 
			
		||||
			}
 | 
			
		||||
			else // Normal control
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, c.Left.ToString(KpccLayout.m_lclInv));
 | 
			
		||||
				WriteCpiParam(sb, c.Top.ToString(KpccLayout.m_lclInv));
 | 
			
		||||
				WriteCpiParam(sb, c.Width.ToString(KpccLayout.m_lclInv));
 | 
			
		||||
				WriteCpiParam(sb, c.Height.ToString(KpccLayout.m_lclInv));
 | 
			
		||||
				WriteCpiParam(sb, c.Dock.ToString());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			WriteCpiParam(sb, c.Font.Name);
 | 
			
		||||
			WriteCpiParam(sb, c.Font.SizeInPoints.ToString(KpccLayout.m_lclInv));
 | 
			
		||||
			WriteCpiParam(sb, c.Font.Bold ? "B" : "N");
 | 
			
		||||
			WriteCpiParam(sb, c.Font.Italic ? "I" : "N");
 | 
			
		||||
			WriteCpiParam(sb, c.Font.Underline ? "U" : "N");
 | 
			
		||||
			WriteCpiParam(sb, c.Font.Strikeout ? "S" : "N");
 | 
			
		||||
 | 
			
		||||
			WriteControlDependentParams(sb, c);
 | 
			
		||||
 | 
			
		||||
			byte[] pb = StrUtil.Utf8.GetBytes(sb.ToString());
 | 
			
		||||
 | 
			
		||||
			SHA256Managed sha256 = new SHA256Managed();
 | 
			
		||||
			byte[] pbSha = sha256.ComputeHash(pb);
 | 
			
		||||
 | 
			
		||||
			// Also see MatchHash
 | 
			
		||||
			return "v1:" + Convert.ToBase64String(pbSha, 0, 3,
 | 
			
		||||
				Base64FormattingOptions.None);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void WriteControlDependentParams(StringBuilder sb, Control c)
 | 
			
		||||
		{
 | 
			
		||||
			CheckBox cb = (c as CheckBox);
 | 
			
		||||
			RadioButton rb = (c as RadioButton);
 | 
			
		||||
			Button btn = (c as Button);
 | 
			
		||||
			Label l = (c as Label);
 | 
			
		||||
			LinkLabel ll = (c as LinkLabel);
 | 
			
		||||
 | 
			
		||||
			if(cb != null)
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, cb.AutoSize ? "A" : "F");
 | 
			
		||||
				WriteCpiParam(sb, cb.TextAlign.ToString());
 | 
			
		||||
				WriteCpiParam(sb, cb.TextImageRelation.ToString());
 | 
			
		||||
				WriteCpiParam(sb, cb.Appearance.ToString());
 | 
			
		||||
				WriteCpiParam(sb, cb.CheckAlign.ToString());
 | 
			
		||||
			}
 | 
			
		||||
			else if(rb != null)
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, rb.AutoSize ? "A" : "F");
 | 
			
		||||
				WriteCpiParam(sb, rb.TextAlign.ToString());
 | 
			
		||||
				WriteCpiParam(sb, rb.TextImageRelation.ToString());
 | 
			
		||||
				WriteCpiParam(sb, rb.Appearance.ToString());
 | 
			
		||||
				WriteCpiParam(sb, rb.CheckAlign.ToString());
 | 
			
		||||
			}
 | 
			
		||||
			else if(btn != null)
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, btn.AutoSize ? "A" : "F");
 | 
			
		||||
				WriteCpiParam(sb, btn.TextAlign.ToString());
 | 
			
		||||
				WriteCpiParam(sb, btn.TextImageRelation.ToString());
 | 
			
		||||
			}
 | 
			
		||||
			else if(l != null)
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, l.AutoSize ? "A" : "F");
 | 
			
		||||
				WriteCpiParam(sb, l.TextAlign.ToString());
 | 
			
		||||
			}
 | 
			
		||||
			else if(ll != null)
 | 
			
		||||
			{
 | 
			
		||||
				WriteCpiParam(sb, ll.AutoSize ? "A" : "F");
 | 
			
		||||
				WriteCpiParam(sb, ll.TextAlign.ToString());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void WriteCpiParam(StringBuilder sb, string strProp)
 | 
			
		||||
		{
 | 
			
		||||
			sb.Append('/');
 | 
			
		||||
			sb.Append(strProp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public bool MatchHash(string strHash)
 | 
			
		||||
		{
 | 
			
		||||
			if(strHash == null) throw new ArgumentNullException("strHash");
 | 
			
		||||
 | 
			
		||||
			// Currently only v1: is supported, see HashControl
 | 
			
		||||
			return (m_strHash == strHash);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										106
									
								
								src/KeePassLib2Android/Translation/KPFormCustomization.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/KeePassLib2Android/Translation/KPFormCustomization.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Windows.Forms;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Translation
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KPFormCustomization
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strFQName = string.Empty;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// The fully qualified name of the form.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		public string FullName
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strFQName; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strFQName = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private KPControlCustomization m_ccWindow = new KPControlCustomization();
 | 
			
		||||
		public KPControlCustomization Window
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_ccWindow; }
 | 
			
		||||
			set { m_ccWindow = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private List<KPControlCustomization> m_vControls =
 | 
			
		||||
			new List<KPControlCustomization>();
 | 
			
		||||
		[XmlArray("ChildControls")]
 | 
			
		||||
		[XmlArrayItem("Control")]
 | 
			
		||||
		public List<KPControlCustomization> Controls
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vControls; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_vControls = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private Form m_formEnglish = null;
 | 
			
		||||
		[XmlIgnore]
 | 
			
		||||
		public Form FormEnglish
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_formEnglish; }
 | 
			
		||||
			set { m_formEnglish = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		public void ApplyTo(Form form)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(form != null); if(form == null) throw new ArgumentNullException("form");
 | 
			
		||||
			
 | 
			
		||||
			// Not supported by TrlUtil (preview form):
 | 
			
		||||
			// Debug.Assert(form.GetType().FullName == m_strFQName);
 | 
			
		||||
 | 
			
		||||
			m_ccWindow.ApplyTo(form);
 | 
			
		||||
 | 
			
		||||
			if(m_vControls.Count == 0) return;
 | 
			
		||||
			foreach(Control c in form.Controls) ApplyToControl(c);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void ApplyToControl(Control c)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(KPControlCustomization cc in m_vControls)
 | 
			
		||||
			{
 | 
			
		||||
				if(c.Name == cc.Name)
 | 
			
		||||
				{
 | 
			
		||||
					cc.ApplyTo(c);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			foreach(Control cSub in c.Controls) ApplyToControl(cSub);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								src/KeePassLib2Android/Translation/KPStringTable.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/KeePassLib2Android/Translation/KPStringTable.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.Windows.Forms;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Translation
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KPStringTable
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strName = string.Empty;
 | 
			
		||||
		[XmlAttribute]
 | 
			
		||||
		public string Name
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strName; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_strName = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private List<KPStringTableItem> m_vItems = new List<KPStringTableItem>();
 | 
			
		||||
 | 
			
		||||
		[XmlArrayItem("Data")]
 | 
			
		||||
		public List<KPStringTableItem> Strings
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vItems; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
				m_vItems = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Dictionary<string, string> ToDictionary()
 | 
			
		||||
		{
 | 
			
		||||
			Dictionary<string, string> dict = new Dictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
			foreach(KPStringTableItem kpstItem in m_vItems)
 | 
			
		||||
			{
 | 
			
		||||
				if(kpstItem.Value.Length > 0)
 | 
			
		||||
					dict[kpstItem.Name] = kpstItem.Value;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return dict;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		public void ApplyTo(ToolStripItemCollection tsic)
 | 
			
		||||
		{
 | 
			
		||||
			if(tsic == null) throw new ArgumentNullException("tsic");
 | 
			
		||||
 | 
			
		||||
			Dictionary<string, string> dict = this.ToDictionary();
 | 
			
		||||
			if(dict.Count == 0) return;
 | 
			
		||||
 | 
			
		||||
			this.ApplyTo(tsic, dict);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private void ApplyTo(ToolStripItemCollection tsic, Dictionary<string, string> dict)
 | 
			
		||||
		{
 | 
			
		||||
			if(tsic == null) return;
 | 
			
		||||
 | 
			
		||||
			foreach(ToolStripItem tsi in tsic)
 | 
			
		||||
			{
 | 
			
		||||
				if(tsi.Text.Length == 0) continue;
 | 
			
		||||
 | 
			
		||||
				string strTrl;
 | 
			
		||||
				if(dict.TryGetValue(tsi.Name, out strTrl))
 | 
			
		||||
					tsi.Text = strTrl;
 | 
			
		||||
 | 
			
		||||
				ToolStripMenuItem tsmi = tsi as ToolStripMenuItem;
 | 
			
		||||
				if((tsmi != null) && (tsmi.DropDownItems != null))
 | 
			
		||||
					this.ApplyTo(tsmi.DropDownItems);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								src/KeePassLib2Android/Translation/KPStringTableItem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/KeePassLib2Android/Translation/KPStringTableItem.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Translation
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KPStringTableItem
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strName = string.Empty;
 | 
			
		||||
		public string Name
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strName; }
 | 
			
		||||
			set { m_strName = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strValue = string.Empty;
 | 
			
		||||
		public string Value
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strValue; }
 | 
			
		||||
			set { m_strValue = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strEnglish = string.Empty;
 | 
			
		||||
		[XmlIgnore]
 | 
			
		||||
		public string ValueEnglish
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strEnglish; }
 | 
			
		||||
			set { m_strEnglish = value; }
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										252
									
								
								src/KeePassLib2Android/Translation/KPTranslation.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								src/KeePassLib2Android/Translation/KPTranslation.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,252 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Xml;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
using System.Windows.Forms;
 | 
			
		||||
using System.ComponentModel;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Interfaces;
 | 
			
		||||
using KeePassLib.Utility;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.IO.Compression;
 | 
			
		||||
#else
 | 
			
		||||
using ICSharpCode.SharpZipLib.GZip;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Translation
 | 
			
		||||
{
 | 
			
		||||
	[XmlRoot("Translation")]
 | 
			
		||||
	public sealed class KPTranslation
 | 
			
		||||
	{
 | 
			
		||||
		public const string FileExtension = "lngx";
 | 
			
		||||
 | 
			
		||||
		private KPTranslationProperties m_props = new KPTranslationProperties();
 | 
			
		||||
		public KPTranslationProperties Properties
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_props; }
 | 
			
		||||
			set { m_props = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private List<KPStringTable> m_vStringTables = new List<KPStringTable>();
 | 
			
		||||
 | 
			
		||||
		[XmlArrayItem("StringTable")]
 | 
			
		||||
		public List<KPStringTable> StringTables
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vStringTables; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_vStringTables = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private List<KPFormCustomization> m_vForms = new List<KPFormCustomization>();
 | 
			
		||||
 | 
			
		||||
		[XmlArrayItem("Form")]
 | 
			
		||||
		public List<KPFormCustomization> Forms
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_vForms; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_vForms = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strUnusedText = string.Empty;
 | 
			
		||||
		[DefaultValue("")]
 | 
			
		||||
		public string UnusedText
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strUnusedText; }
 | 
			
		||||
			set
 | 
			
		||||
			{
 | 
			
		||||
				if(value == null) throw new ArgumentNullException("value");
 | 
			
		||||
 | 
			
		||||
				m_strUnusedText = value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void SaveToFile(KPTranslation kpTrl, string strFileName,
 | 
			
		||||
			IXmlSerializerEx xs)
 | 
			
		||||
		{
 | 
			
		||||
			if(xs == null) throw new ArgumentNullException("xs");
 | 
			
		||||
 | 
			
		||||
			FileStream fs = new FileStream(strFileName, FileMode.Create,
 | 
			
		||||
				FileAccess.Write, FileShare.None);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			GZipStream gz = new GZipStream(fs, CompressionMode.Compress);
 | 
			
		||||
#else
 | 
			
		||||
			GZipOutputStream gz = new GZipOutputStream(fs);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			XmlWriterSettings xws = new XmlWriterSettings();
 | 
			
		||||
			xws.CheckCharacters = true;
 | 
			
		||||
			xws.Encoding = StrUtil.Utf8;
 | 
			
		||||
			xws.Indent = true;
 | 
			
		||||
			xws.IndentChars = "\t";
 | 
			
		||||
 | 
			
		||||
			XmlWriter xw = XmlWriter.Create(gz, xws);
 | 
			
		||||
 | 
			
		||||
			xs.Serialize(xw, kpTrl);
 | 
			
		||||
 | 
			
		||||
			xw.Close();
 | 
			
		||||
			gz.Close();
 | 
			
		||||
			fs.Close();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static KPTranslation LoadFromFile(string strFile,
 | 
			
		||||
			IXmlSerializerEx xs)
 | 
			
		||||
		{
 | 
			
		||||
			if(xs == null) throw new ArgumentNullException("xs");
 | 
			
		||||
 | 
			
		||||
			FileStream fs = new FileStream(strFile, FileMode.Open,
 | 
			
		||||
				FileAccess.Read, FileShare.Read);
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			GZipStream gz = new GZipStream(fs, CompressionMode.Decompress);
 | 
			
		||||
#else
 | 
			
		||||
			GZipInputStream gz = new GZipInputStream(fs);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			KPTranslation kpTrl = (xs.Deserialize(gz) as KPTranslation);
 | 
			
		||||
 | 
			
		||||
			gz.Close();
 | 
			
		||||
			fs.Close();
 | 
			
		||||
			return kpTrl;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public Dictionary<string, string> SafeGetStringTableDictionary(
 | 
			
		||||
			string strTableName)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(KPStringTable kpst in m_vStringTables)
 | 
			
		||||
			{
 | 
			
		||||
				if(kpst.Name == strTableName) return kpst.ToDictionary();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return new Dictionary<string, string>();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		public void ApplyTo(Form form)
 | 
			
		||||
		{
 | 
			
		||||
			if(form == null) throw new ArgumentNullException("form");
 | 
			
		||||
 | 
			
		||||
			if(m_props.RightToLeft)
 | 
			
		||||
			{
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					form.RightToLeft = RightToLeft.Yes;
 | 
			
		||||
					form.RightToLeftLayout = true;
 | 
			
		||||
				}
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			string strTypeName = form.GetType().FullName;
 | 
			
		||||
			foreach(KPFormCustomization kpfc in m_vForms)
 | 
			
		||||
			{
 | 
			
		||||
				if(kpfc.FullName == strTypeName)
 | 
			
		||||
				{
 | 
			
		||||
					kpfc.ApplyTo(form);
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(m_props.RightToLeft)
 | 
			
		||||
			{
 | 
			
		||||
				try { RtlApplyToControls(form.Controls); }
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void RtlApplyToControls(Control.ControlCollection cc)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(Control c in cc)
 | 
			
		||||
			{
 | 
			
		||||
				if(c.Controls.Count > 0) RtlApplyToControls(c.Controls);
 | 
			
		||||
 | 
			
		||||
				if(c is DateTimePicker)
 | 
			
		||||
					((DateTimePicker)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is ListView)
 | 
			
		||||
					((ListView)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is MonthCalendar)
 | 
			
		||||
					((MonthCalendar)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is ProgressBar)
 | 
			
		||||
					((ProgressBar)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is TabControl)
 | 
			
		||||
					((TabControl)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is TrackBar)
 | 
			
		||||
					((TrackBar)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is TreeView)
 | 
			
		||||
					((TreeView)c).RightToLeftLayout = true;
 | 
			
		||||
				else if(c is ToolStrip)
 | 
			
		||||
					RtlApplyToToolStripItems(((ToolStrip)c).Items);
 | 
			
		||||
 | 
			
		||||
				if((c is GroupBox) || (c is Panel)) RtlMoveChildControls(c);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void RtlMoveChildControls(Control cParent)
 | 
			
		||||
		{
 | 
			
		||||
			int nParentWidth = cParent.Size.Width;
 | 
			
		||||
 | 
			
		||||
			foreach(Control c in cParent.Controls)
 | 
			
		||||
			{
 | 
			
		||||
				Point ptCur = c.Location;
 | 
			
		||||
				c.Location = new Point(nParentWidth - c.Size.Width - ptCur.X, ptCur.Y);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void RtlApplyToToolStripItems(ToolStripItemCollection tsic)
 | 
			
		||||
		{
 | 
			
		||||
			foreach(ToolStripItem tsi in tsic)
 | 
			
		||||
			{
 | 
			
		||||
				tsi.RightToLeftAutoMirrorImage = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public void ApplyTo(string strTableName, ToolStripItemCollection tsic)
 | 
			
		||||
		{
 | 
			
		||||
			if(tsic == null) throw new ArgumentNullException("tsic");
 | 
			
		||||
 | 
			
		||||
			KPStringTable kpst = null;
 | 
			
		||||
			foreach(KPStringTable kpstEnum in m_vStringTables)
 | 
			
		||||
			{
 | 
			
		||||
				if(kpstEnum.Name == strTableName)
 | 
			
		||||
				{
 | 
			
		||||
					kpst = kpstEnum;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(kpst != null) kpst.ApplyTo(tsic);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										105
									
								
								src/KeePassLib2Android/Translation/KPTranslationProperties.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/KeePassLib2Android/Translation/KPTranslationProperties.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Translation
 | 
			
		||||
{
 | 
			
		||||
	public sealed class KPTranslationProperties
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strApp = string.Empty;
 | 
			
		||||
		public string Application
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strApp; }
 | 
			
		||||
			set { m_strApp = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strForVersion = PwDefs.VersionString;
 | 
			
		||||
		public string ApplicationVersion
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strForVersion; }
 | 
			
		||||
			set { m_strForVersion = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strNameEnglish = string.Empty;
 | 
			
		||||
		public string NameEnglish
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strNameEnglish; }
 | 
			
		||||
			set { m_strNameEnglish = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strNameNative = string.Empty;
 | 
			
		||||
		public string NameNative
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strNameNative; }
 | 
			
		||||
			set { m_strNameNative = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strIso6391Code = string.Empty;
 | 
			
		||||
		public string Iso6391Code
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strIso6391Code; }
 | 
			
		||||
			set { m_strIso6391Code = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private bool m_bRtl = false;
 | 
			
		||||
		public bool RightToLeft
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_bRtl; }
 | 
			
		||||
			set { m_bRtl = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strAuthorName = string.Empty;
 | 
			
		||||
		public string AuthorName
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strAuthorName; }
 | 
			
		||||
			set { m_strAuthorName = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strAuthorContact = string.Empty;
 | 
			
		||||
		public string AuthorContact
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strAuthorContact; }
 | 
			
		||||
			set { m_strAuthorContact = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strGen = string.Empty;
 | 
			
		||||
		public string Generator
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strGen; }
 | 
			
		||||
			set { m_strGen = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strUuid = string.Empty;
 | 
			
		||||
		public string FileUuid
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strUuid; }
 | 
			
		||||
			set { m_strUuid = value; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private string m_strLastModified = string.Empty;
 | 
			
		||||
		public string LastModified
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_strLastModified; }
 | 
			
		||||
			set { m_strLastModified = value; }
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								src/KeePassLib2Android/Utility/AppLogEx.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/KeePassLib2Android/Utility/AppLogEx.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.IO.Compression;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Utility
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Application-wide logging services.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class AppLogEx
 | 
			
		||||
	{
 | 
			
		||||
		private static StreamWriter m_swOut = null;
 | 
			
		||||
 | 
			
		||||
		public static void Open(string strPrefix)
 | 
			
		||||
		{
 | 
			
		||||
			return; // Logging is not enabled in normal builds of KeePass!
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			AppLogEx.Close();
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(strPrefix != null);
 | 
			
		||||
			if(strPrefix == null) strPrefix = "Log";
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				string strDirSep = string.Empty;
 | 
			
		||||
				strDirSep += Path.DirectorySeparatorChar;
 | 
			
		||||
 | 
			
		||||
				string strTemp = UrlUtil.GetTempPath();
 | 
			
		||||
				if(!strTemp.EndsWith(strDirSep))
 | 
			
		||||
					strTemp += strDirSep;
 | 
			
		||||
 | 
			
		||||
				string strPath = strTemp + strPrefix + "-";
 | 
			
		||||
				Debug.Assert(strPath.IndexOf('/') < 0);
 | 
			
		||||
 | 
			
		||||
				DateTime dtNow = DateTime.Now;
 | 
			
		||||
				string strTime = dtNow.ToString("s");
 | 
			
		||||
				strTime = strTime.Replace('T', '-');
 | 
			
		||||
				strTime = strTime.Replace(':', '-');
 | 
			
		||||
 | 
			
		||||
				strPath += strTime + "-" + Environment.TickCount.ToString(
 | 
			
		||||
					CultureInfo.InvariantCulture) + ".log.gz";
 | 
			
		||||
 | 
			
		||||
				FileStream fsOut = new FileStream(strPath, FileMode.Create,
 | 
			
		||||
					FileAccess.Write, FileShare.None);
 | 
			
		||||
				GZipStream gz = new GZipStream(fsOut, CompressionMode.Compress);
 | 
			
		||||
				m_swOut = new StreamWriter(gz);
 | 
			
		||||
 | 
			
		||||
				AppLogEx.Log("Started logging on " + dtNow.ToString("s") + ".");
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
			*/
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void Close()
 | 
			
		||||
		{
 | 
			
		||||
			if(m_swOut == null) return;
 | 
			
		||||
 | 
			
		||||
			m_swOut.Close();
 | 
			
		||||
			m_swOut = null;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void Log(string strText)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_swOut == null) return;
 | 
			
		||||
 | 
			
		||||
			if(strText == null) m_swOut.WriteLine();
 | 
			
		||||
			else m_swOut.WriteLine(strText);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void Log(Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			if(m_swOut == null) return;
 | 
			
		||||
 | 
			
		||||
			if(ex == null) m_swOut.WriteLine();
 | 
			
		||||
			else m_swOut.WriteLine(ex.ToString());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								src/KeePassLib2Android/Utility/GfxUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/KeePassLib2Android/Utility/GfxUtil.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Drawing;
 | 
			
		||||
using System.Drawing.Imaging;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Utility
 | 
			
		||||
{
 | 
			
		||||
	public static class GfxUtil
 | 
			
		||||
	{
 | 
			
		||||
		public static Image LoadImage(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			if(pb == null) throw new ArgumentNullException("pb");
 | 
			
		||||
 | 
			
		||||
			MemoryStream ms = new MemoryStream(pb, false);
 | 
			
		||||
			try { return LoadImagePriv(ms); }
 | 
			
		||||
			catch(Exception)
 | 
			
		||||
			{
 | 
			
		||||
				Image imgIco = TryLoadIco(pb);
 | 
			
		||||
				if(imgIco != null) return imgIco;
 | 
			
		||||
				throw;
 | 
			
		||||
			}
 | 
			
		||||
			finally { ms.Close(); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static Image LoadImagePriv(Stream s)
 | 
			
		||||
		{
 | 
			
		||||
			// Image.FromStream wants the stream to be open during
 | 
			
		||||
			// the whole lifetime of the image; as we can't guarantee
 | 
			
		||||
			// this, we make a copy of the image
 | 
			
		||||
			Image imgSrc = null;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				imgSrc = Image.FromStream(s);
 | 
			
		||||
				Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height,
 | 
			
		||||
					PixelFormat.Format32bppArgb);
 | 
			
		||||
 | 
			
		||||
				try
 | 
			
		||||
				{
 | 
			
		||||
					bmp.SetResolution(imgSrc.HorizontalResolution,
 | 
			
		||||
						imgSrc.VerticalResolution);
 | 
			
		||||
					Debug.Assert(bmp.Size == imgSrc.Size);
 | 
			
		||||
				}
 | 
			
		||||
				catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
#else
 | 
			
		||||
				imgSrc = new Bitmap(s);
 | 
			
		||||
				Bitmap bmp = new Bitmap(imgSrc.Width, imgSrc.Height);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				using(Graphics g = Graphics.FromImage(bmp))
 | 
			
		||||
				{
 | 
			
		||||
					g.Clear(Color.Transparent);
 | 
			
		||||
					g.DrawImage(imgSrc, 0, 0);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return bmp;
 | 
			
		||||
			}
 | 
			
		||||
			finally { if(imgSrc != null) imgSrc.Dispose(); }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static Image TryLoadIco(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			MemoryStream ms = new MemoryStream(pb, false);
 | 
			
		||||
			try { return (new Icon(ms)).ToBitmap(); }
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
			finally { ms.Close(); }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										404
									
								
								src/KeePassLib2Android/Utility/MemUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										404
									
								
								src/KeePassLib2Android/Utility/MemUtil.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,404 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
using System.IO.Compression;
 | 
			
		||||
#else
 | 
			
		||||
using KeePassLibSD;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Utility
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Contains static buffer manipulation and string conversion routines.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class MemUtil
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert a hexadecimal string to a byte array. The input string must be
 | 
			
		||||
		/// even (i.e. its length is a multiple of 2).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strHex">String containing hexadecimal characters.</param>
 | 
			
		||||
		/// <returns>Returns a byte array. Returns <c>null</c> if the string parameter
 | 
			
		||||
		/// was <c>null</c> or is an uneven string (i.e. if its length isn't a
 | 
			
		||||
		/// multiple of 2).</returns>
 | 
			
		||||
		/// <exception cref="System.ArgumentNullException">Thrown if <paramref name="strHex" />
 | 
			
		||||
		/// is <c>null</c>.</exception>
 | 
			
		||||
		public static byte[] HexStringToByteArray(string strHex)
 | 
			
		||||
		{
 | 
			
		||||
			if(strHex == null) { Debug.Assert(false); throw new ArgumentNullException("strHex"); }
 | 
			
		||||
 | 
			
		||||
			int nStrLen = strHex.Length;
 | 
			
		||||
			if((nStrLen & 1) != 0) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			byte[] pb = new byte[nStrLen / 2];
 | 
			
		||||
			byte bt;
 | 
			
		||||
			char ch;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < nStrLen; i += 2)
 | 
			
		||||
			{
 | 
			
		||||
				ch = strHex[i];
 | 
			
		||||
 | 
			
		||||
				if((ch >= '0') && (ch <= '9'))
 | 
			
		||||
					bt = (byte)(ch - '0');
 | 
			
		||||
				else if((ch >= 'a') && (ch <= 'f'))
 | 
			
		||||
					bt = (byte)(ch - 'a' + 10);
 | 
			
		||||
				else if((ch >= 'A') && (ch <= 'F'))
 | 
			
		||||
					bt = (byte)(ch - 'A' + 10);
 | 
			
		||||
				else { Debug.Assert(false); bt = 0; }
 | 
			
		||||
 | 
			
		||||
				bt <<= 4;
 | 
			
		||||
 | 
			
		||||
				ch = strHex[i + 1];
 | 
			
		||||
				if((ch >= '0') && (ch <= '9'))
 | 
			
		||||
					bt += (byte)(ch - '0');
 | 
			
		||||
				else if((ch >= 'a') && (ch <= 'f'))
 | 
			
		||||
					bt += (byte)(ch - 'a' + 10);
 | 
			
		||||
				else if((ch >= 'A') && (ch <= 'F'))
 | 
			
		||||
					bt += (byte)(ch - 'A' + 10);
 | 
			
		||||
				else { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
				pb[i >> 1] = bt;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert a byte array to a hexadecimal string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbArray">Input byte array.</param>
 | 
			
		||||
		/// <returns>Returns the hexadecimal string representing the byte
 | 
			
		||||
		/// array. Returns <c>null</c>, if the input byte array was <c>null</c>. Returns
 | 
			
		||||
		/// an empty string, if the input byte array has length 0.</returns>
 | 
			
		||||
		public static string ByteArrayToHexString(byte[] pbArray)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbArray == null) return null;
 | 
			
		||||
 | 
			
		||||
			int nLen = pbArray.Length;
 | 
			
		||||
			if(nLen == 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
			byte bt, btHigh, btLow;
 | 
			
		||||
			for(int i = 0; i < nLen; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				bt = pbArray[i];
 | 
			
		||||
				btHigh = bt; btHigh >>= 4;
 | 
			
		||||
				btLow = (byte)(bt & 0x0F);
 | 
			
		||||
 | 
			
		||||
				if(btHigh >= 10) sb.Append((char)('A' + btHigh - 10));
 | 
			
		||||
				else sb.Append((char)('0' + btHigh));
 | 
			
		||||
 | 
			
		||||
				if(btLow >= 10) sb.Append((char)('A' + btLow - 10));
 | 
			
		||||
				else sb.Append((char)('0' + btLow));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return sb.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Set all bytes in a byte array to zero.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pbArray">Input array. All bytes of this array will be set
 | 
			
		||||
		/// to zero.</param>
 | 
			
		||||
		public static void ZeroByteArray(byte[] pbArray)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(pbArray != null); if(pbArray == null) throw new ArgumentNullException("pbArray");
 | 
			
		||||
 | 
			
		||||
			// for(int i = 0; i < pbArray.Length; ++i)
 | 
			
		||||
			//	pbArray[i] = 0;
 | 
			
		||||
 | 
			
		||||
			Array.Clear(pbArray, 0, pbArray.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert 2 bytes to a 16-bit unsigned integer using Little-Endian
 | 
			
		||||
		/// encoding.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pb">Input bytes. Array must contain at least 2 bytes.</param>
 | 
			
		||||
		/// <returns>16-bit unsigned integer.</returns>
 | 
			
		||||
		public static ushort BytesToUInt16(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((pb != null) && (pb.Length == 2));
 | 
			
		||||
			if(pb == null) throw new ArgumentNullException("pb");
 | 
			
		||||
			if(pb.Length != 2) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			return (ushort)((ushort)pb[0] | ((ushort)pb[1] << 8));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert 4 bytes to a 32-bit unsigned integer using Little-Endian
 | 
			
		||||
		/// encoding.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pb">Input bytes.</param>
 | 
			
		||||
		/// <returns>32-bit unsigned integer.</returns>
 | 
			
		||||
		public static uint BytesToUInt32(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((pb != null) && (pb.Length == 4));
 | 
			
		||||
			if(pb == null) throw new ArgumentNullException("pb");
 | 
			
		||||
			if(pb.Length != 4) throw new ArgumentException("Input array must contain 4 bytes!");
 | 
			
		||||
 | 
			
		||||
			return (uint)pb[0] | ((uint)pb[1] << 8) | ((uint)pb[2] << 16) |
 | 
			
		||||
				((uint)pb[3] << 24);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert 8 bytes to a 64-bit unsigned integer using Little-Endian
 | 
			
		||||
		/// encoding.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pb">Input bytes.</param>
 | 
			
		||||
		/// <returns>64-bit unsigned integer.</returns>
 | 
			
		||||
		public static ulong BytesToUInt64(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((pb != null) && (pb.Length == 8));
 | 
			
		||||
			if(pb == null) throw new ArgumentNullException("pb");
 | 
			
		||||
			if(pb.Length != 8) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			return (ulong)pb[0] | ((ulong)pb[1] << 8) | ((ulong)pb[2] << 16) |
 | 
			
		||||
				((ulong)pb[3] << 24) | ((ulong)pb[4] << 32) | ((ulong)pb[5] << 40) |
 | 
			
		||||
				((ulong)pb[6] << 48) | ((ulong)pb[7] << 56);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert a 16-bit unsigned integer to 2 bytes using Little-Endian
 | 
			
		||||
		/// encoding.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uValue">16-bit input word.</param>
 | 
			
		||||
		/// <returns>Two bytes representing the 16-bit value.</returns>
 | 
			
		||||
		public static byte[] UInt16ToBytes(ushort uValue)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = new byte[2];
 | 
			
		||||
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				pb[0] = (byte)uValue;
 | 
			
		||||
				pb[1] = (byte)(uValue >> 8);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert a 32-bit unsigned integer to 4 bytes using Little-Endian
 | 
			
		||||
		/// encoding.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uValue">32-bit input word.</param>
 | 
			
		||||
		/// <returns>Four bytes representing the 32-bit value.</returns>
 | 
			
		||||
		public static byte[] UInt32ToBytes(uint uValue)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = new byte[4];
 | 
			
		||||
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				pb[0] = (byte)uValue;
 | 
			
		||||
				pb[1] = (byte)(uValue >> 8);
 | 
			
		||||
				pb[2] = (byte)(uValue >> 16);
 | 
			
		||||
				pb[3] = (byte)(uValue >> 24);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert a 64-bit unsigned integer to 8 bytes using Little-Endian
 | 
			
		||||
		/// encoding.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="uValue">64-bit input word.</param>
 | 
			
		||||
		/// <returns>Eight bytes representing the 64-bit value.</returns>
 | 
			
		||||
		public static byte[] UInt64ToBytes(ulong uValue)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = new byte[8];
 | 
			
		||||
 | 
			
		||||
			unchecked
 | 
			
		||||
			{
 | 
			
		||||
				pb[0] = (byte)uValue;
 | 
			
		||||
				pb[1] = (byte)(uValue >> 8);
 | 
			
		||||
				pb[2] = (byte)(uValue >> 16);
 | 
			
		||||
				pb[3] = (byte)(uValue >> 24);
 | 
			
		||||
				pb[4] = (byte)(uValue >> 32);
 | 
			
		||||
				pb[5] = (byte)(uValue >> 40);
 | 
			
		||||
				pb[6] = (byte)(uValue >> 48);
 | 
			
		||||
				pb[7] = (byte)(uValue >> 56);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool ArraysEqual(byte[] x, byte[] y)
 | 
			
		||||
		{
 | 
			
		||||
			// Return false if one of them is null (not comparable)!
 | 
			
		||||
			if((x == null) || (y == null)) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			if(x.Length != y.Length) return false;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < x.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(x[i] != y[i]) return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void XorArray(byte[] pbSource, int nSourceOffset,
 | 
			
		||||
			byte[] pbBuffer, int nBufferOffset, int nLength)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbSource == null) throw new ArgumentNullException("pbSource");
 | 
			
		||||
			if(nSourceOffset < 0) throw new ArgumentException();
 | 
			
		||||
			if(pbBuffer == null) throw new ArgumentNullException("pbBuffer");
 | 
			
		||||
			if(nBufferOffset < 0) throw new ArgumentException();
 | 
			
		||||
			if(nLength < 0) throw new ArgumentException();
 | 
			
		||||
			if((nSourceOffset + nLength) > pbSource.Length) throw new ArgumentException();
 | 
			
		||||
			if((nBufferOffset + nLength) > pbBuffer.Length) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < nLength; ++i)
 | 
			
		||||
				pbBuffer[nBufferOffset + i] ^= pbSource[nSourceOffset + i];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void CopyStream(Stream sSource, Stream sTarget)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((sSource != null) && (sTarget != null));
 | 
			
		||||
			if(sSource == null) throw new ArgumentNullException("sSource");
 | 
			
		||||
			if(sTarget == null) throw new ArgumentNullException("sTarget");
 | 
			
		||||
 | 
			
		||||
			const int nBufSize = 4096;
 | 
			
		||||
			byte[] pbBuf = new byte[nBufSize];
 | 
			
		||||
 | 
			
		||||
			while(true)
 | 
			
		||||
			{
 | 
			
		||||
				int nRead = sSource.Read(pbBuf, 0, nBufSize);
 | 
			
		||||
				if(nRead == 0) break;
 | 
			
		||||
 | 
			
		||||
				sTarget.Write(pbBuf, 0, nRead);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Do not close any of the streams
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static byte[] Read(Stream s, int nCount)
 | 
			
		||||
		{
 | 
			
		||||
			if(s == null) throw new ArgumentNullException("s");
 | 
			
		||||
			if(nCount < 0) throw new ArgumentOutOfRangeException("nCount");
 | 
			
		||||
 | 
			
		||||
			byte[] pb = new byte[nCount];
 | 
			
		||||
			int iOffset = 0;
 | 
			
		||||
			while(nCount > 0)
 | 
			
		||||
			{
 | 
			
		||||
				int iRead = s.Read(pb, iOffset, nCount);
 | 
			
		||||
				if(iRead == 0) break;
 | 
			
		||||
 | 
			
		||||
				iOffset += iRead;
 | 
			
		||||
				nCount -= iRead;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(iOffset != pb.Length)
 | 
			
		||||
			{
 | 
			
		||||
				byte[] pbPart = new byte[iOffset];
 | 
			
		||||
				Array.Copy(pb, pbPart, iOffset);
 | 
			
		||||
				return pbPart;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void Write(Stream s, byte[] pbData)
 | 
			
		||||
		{
 | 
			
		||||
			if(s == null) { Debug.Assert(false); return; }
 | 
			
		||||
			if(pbData == null) { Debug.Assert(false); return; }
 | 
			
		||||
 | 
			
		||||
			s.Write(pbData, 0, pbData.Length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static byte[] Compress(byte[] pbData)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbData == null) throw new ArgumentNullException("pbData");
 | 
			
		||||
			if(pbData.Length == 0) return pbData;
 | 
			
		||||
 | 
			
		||||
			MemoryStream msCompressed = new MemoryStream();
 | 
			
		||||
			GZipStream gz = new GZipStream(msCompressed, CompressionMode.Compress);
 | 
			
		||||
			MemoryStream msSource = new MemoryStream(pbData, false);
 | 
			
		||||
			MemUtil.CopyStream(msSource, gz);
 | 
			
		||||
			gz.Close();
 | 
			
		||||
			msSource.Close();
 | 
			
		||||
 | 
			
		||||
			byte[] pbCompressed = msCompressed.ToArray();
 | 
			
		||||
			msCompressed.Close();
 | 
			
		||||
			return pbCompressed;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static byte[] Decompress(byte[] pbCompressed)
 | 
			
		||||
		{
 | 
			
		||||
			if(pbCompressed == null) throw new ArgumentNullException("pbCompressed");
 | 
			
		||||
			if(pbCompressed.Length == 0) return pbCompressed;
 | 
			
		||||
 | 
			
		||||
			MemoryStream msCompressed = new MemoryStream(pbCompressed, false);
 | 
			
		||||
			GZipStream gz = new GZipStream(msCompressed, CompressionMode.Decompress);
 | 
			
		||||
			MemoryStream msData = new MemoryStream();
 | 
			
		||||
			MemUtil.CopyStream(gz, msData);
 | 
			
		||||
			gz.Close();
 | 
			
		||||
			msCompressed.Close();
 | 
			
		||||
 | 
			
		||||
			byte[] pbData = msData.ToArray();
 | 
			
		||||
			msData.Close();
 | 
			
		||||
			return pbData;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static int IndexOf<T>(T[] vHaystack, T[] vNeedle)
 | 
			
		||||
			where T : IEquatable<T>
 | 
			
		||||
		{
 | 
			
		||||
			if(vHaystack == null) throw new ArgumentNullException("vHaystack");
 | 
			
		||||
			if(vNeedle == null) throw new ArgumentNullException("vNeedle");
 | 
			
		||||
			if(vNeedle.Length == 0) return 0;
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i <= (vHaystack.Length - vNeedle.Length); ++i)
 | 
			
		||||
			{
 | 
			
		||||
				bool bFound = true;
 | 
			
		||||
				for(int m = 0; m < vNeedle.Length; ++m)
 | 
			
		||||
				{
 | 
			
		||||
					if(!vHaystack[i + m].Equals(vNeedle[m]))
 | 
			
		||||
					{
 | 
			
		||||
						bFound = false;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if(bFound) return i;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static T[] Mid<T>(T[] v, int iOffset, int iLength)
 | 
			
		||||
		{
 | 
			
		||||
			if(v == null) throw new ArgumentNullException("v");
 | 
			
		||||
			if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset");
 | 
			
		||||
			if(iLength < 0) throw new ArgumentOutOfRangeException("iLength");
 | 
			
		||||
			if(iOffset + iLength > v.Length) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			T[] r = new T[iLength];
 | 
			
		||||
			Array.Copy(v, iOffset, r, 0, iLength);
 | 
			
		||||
			return r;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										428
									
								
								src/KeePassLib2Android/Utility/MessageService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										428
									
								
								src/KeePassLib2Android/Utility/MessageService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,428 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Collections.Specialized;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Windows.Forms;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Resources;
 | 
			
		||||
using KeePassLib.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Utility
 | 
			
		||||
{
 | 
			
		||||
	public sealed class MessageServiceEventArgs : EventArgs
 | 
			
		||||
	{
 | 
			
		||||
		private string m_strTitle = string.Empty;
 | 
			
		||||
		private string m_strText = string.Empty;
 | 
			
		||||
		private MessageBoxButtons m_msgButtons = MessageBoxButtons.OK;
 | 
			
		||||
		private MessageBoxIcon m_msgIcon = MessageBoxIcon.None;
 | 
			
		||||
 | 
			
		||||
		public string Title { get { return m_strTitle; } }
 | 
			
		||||
		public string Text { get { return m_strText; } }
 | 
			
		||||
		public MessageBoxButtons Buttons { get { return m_msgButtons; } }
 | 
			
		||||
		public MessageBoxIcon Icon { get { return m_msgIcon; } }
 | 
			
		||||
 | 
			
		||||
		public MessageServiceEventArgs() { }
 | 
			
		||||
 | 
			
		||||
		public MessageServiceEventArgs(string strTitle, string strText,
 | 
			
		||||
			MessageBoxButtons msgButtons, MessageBoxIcon msgIcon)
 | 
			
		||||
		{
 | 
			
		||||
			m_strTitle = (strTitle ?? string.Empty);
 | 
			
		||||
			m_strText = (strText ?? string.Empty);
 | 
			
		||||
			m_msgButtons = msgButtons;
 | 
			
		||||
			m_msgIcon = msgIcon;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public static class MessageService
 | 
			
		||||
	{
 | 
			
		||||
		private static volatile uint m_uCurrentMessageCount = 0;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Information;
 | 
			
		||||
		private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Warning;
 | 
			
		||||
		private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Error;
 | 
			
		||||
 | 
			
		||||
		private const MessageBoxOptions m_mboRtl = (MessageBoxOptions.RtlReading |
 | 
			
		||||
			MessageBoxOptions.RightAlign);
 | 
			
		||||
#else
 | 
			
		||||
		private const MessageBoxIcon m_mbiInfo = MessageBoxIcon.Asterisk;
 | 
			
		||||
		private const MessageBoxIcon m_mbiWarning = MessageBoxIcon.Exclamation;
 | 
			
		||||
		private const MessageBoxIcon m_mbiFatal = MessageBoxIcon.Hand;
 | 
			
		||||
#endif
 | 
			
		||||
		private const MessageBoxIcon m_mbiQuestion = MessageBoxIcon.Question;
 | 
			
		||||
 | 
			
		||||
		public static string NewLine
 | 
			
		||||
		{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			get { return Environment.NewLine; }
 | 
			
		||||
#else
 | 
			
		||||
			get { return "\r\n"; }
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string NewParagraph
 | 
			
		||||
		{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			get { return Environment.NewLine + Environment.NewLine; }
 | 
			
		||||
#else
 | 
			
		||||
			get { return "\r\n\r\n"; }
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static uint CurrentMessageCount
 | 
			
		||||
		{
 | 
			
		||||
			get { return m_uCurrentMessageCount; }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static event EventHandler<MessageServiceEventArgs> MessageShowing;
 | 
			
		||||
 | 
			
		||||
		private static string ObjectsToMessage(object[] vLines)
 | 
			
		||||
		{
 | 
			
		||||
			return ObjectsToMessage(vLines, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static string ObjectsToMessage(object[] vLines, bool bFullExceptions)
 | 
			
		||||
		{
 | 
			
		||||
			if(vLines == null) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			string strNewPara = MessageService.NewParagraph;
 | 
			
		||||
 | 
			
		||||
			StringBuilder sbText = new StringBuilder();
 | 
			
		||||
			bool bSeparator = false;
 | 
			
		||||
 | 
			
		||||
			foreach(object obj in vLines)
 | 
			
		||||
			{
 | 
			
		||||
				if(obj == null) continue;
 | 
			
		||||
 | 
			
		||||
				string strAppend = null;
 | 
			
		||||
 | 
			
		||||
				Exception exObj = (obj as Exception);
 | 
			
		||||
				string strObj = (obj as string);
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				StringCollection scObj = (obj as StringCollection);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				if(exObj != null)
 | 
			
		||||
				{
 | 
			
		||||
					if(bFullExceptions)
 | 
			
		||||
						strAppend = StrUtil.FormatException(exObj);
 | 
			
		||||
					else if((exObj.Message != null) && (exObj.Message.Length > 0))
 | 
			
		||||
						strAppend = exObj.Message;
 | 
			
		||||
				}
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				else if(scObj != null)
 | 
			
		||||
				{
 | 
			
		||||
					StringBuilder sb = new StringBuilder();
 | 
			
		||||
					foreach(string strCollLine in scObj)
 | 
			
		||||
					{
 | 
			
		||||
						if(sb.Length > 0) sb.AppendLine();
 | 
			
		||||
						sb.Append(strCollLine.TrimEnd());
 | 
			
		||||
					}
 | 
			
		||||
					strAppend = sb.ToString();
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
				else if(strObj != null)
 | 
			
		||||
					strAppend = strObj;
 | 
			
		||||
				else
 | 
			
		||||
					strAppend = obj.ToString();
 | 
			
		||||
 | 
			
		||||
				if(!string.IsNullOrEmpty(strAppend))
 | 
			
		||||
				{
 | 
			
		||||
					if(bSeparator) sbText.Append(strNewPara);
 | 
			
		||||
					else bSeparator = true;
 | 
			
		||||
 | 
			
		||||
					sbText.Append(strAppend);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return sbText.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		internal static Form GetTopForm()
 | 
			
		||||
		{
 | 
			
		||||
			FormCollection fc = Application.OpenForms;
 | 
			
		||||
			if((fc == null) || (fc.Count == 0)) return null;
 | 
			
		||||
 | 
			
		||||
			return fc[fc.Count - 1];
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		private static DialogResult SafeShowMessageBox(string strText, string strTitle,
 | 
			
		||||
			MessageBoxButtons mb, MessageBoxIcon mi, MessageBoxDefaultButton mdb)
 | 
			
		||||
		{
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
			return MessageBox.Show(strText, strTitle, mb, mi, mdb);
 | 
			
		||||
#else
 | 
			
		||||
			IWin32Window wnd = null;
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				Form f = GetTopForm();
 | 
			
		||||
				if((f != null) && f.InvokeRequired)
 | 
			
		||||
					return (DialogResult)f.Invoke(new SafeShowMessageBoxInternalDelegate(
 | 
			
		||||
						SafeShowMessageBoxInternal), f, strText, strTitle, mb, mi, mdb);
 | 
			
		||||
				else wnd = f;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			if(wnd == null)
 | 
			
		||||
			{
 | 
			
		||||
				if(StrUtil.RightToLeft)
 | 
			
		||||
					return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl);
 | 
			
		||||
				return MessageBox.Show(strText, strTitle, mb, mi, mdb);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if(StrUtil.RightToLeft)
 | 
			
		||||
					return MessageBox.Show(wnd, strText, strTitle, mb, mi, mdb, m_mboRtl);
 | 
			
		||||
				return MessageBox.Show(wnd, strText, strTitle, mb, mi, mdb);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			if(StrUtil.RightToLeft)
 | 
			
		||||
				return MessageBox.Show(strText, strTitle, mb, mi, mdb, m_mboRtl);
 | 
			
		||||
			return MessageBox.Show(strText, strTitle, mb, mi, mdb);
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		internal delegate DialogResult SafeShowMessageBoxInternalDelegate(IWin32Window iParent,
 | 
			
		||||
			string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
 | 
			
		||||
			MessageBoxDefaultButton mdb);
 | 
			
		||||
 | 
			
		||||
		internal static DialogResult SafeShowMessageBoxInternal(IWin32Window iParent,
 | 
			
		||||
			string strText, string strTitle, MessageBoxButtons mb, MessageBoxIcon mi,
 | 
			
		||||
			MessageBoxDefaultButton mdb)
 | 
			
		||||
		{
 | 
			
		||||
			if(StrUtil.RightToLeft)
 | 
			
		||||
				return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb, m_mboRtl);
 | 
			
		||||
			return MessageBox.Show(iParent, strText, strTitle, mb, mi, mdb);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		public static void ShowInfo(params object[] vLines)
 | 
			
		||||
		{
 | 
			
		||||
			ShowInfoEx(null, vLines);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowInfoEx(string strTitle, params object[] vLines)
 | 
			
		||||
		{
 | 
			
		||||
			++m_uCurrentMessageCount;
 | 
			
		||||
 | 
			
		||||
			strTitle = (strTitle ?? PwDefs.ShortProductName);
 | 
			
		||||
			string strText = ObjectsToMessage(vLines);
 | 
			
		||||
 | 
			
		||||
			if(MessageService.MessageShowing != null)
 | 
			
		||||
				MessageService.MessageShowing(null, new MessageServiceEventArgs(
 | 
			
		||||
					strTitle, strText, MessageBoxButtons.OK, m_mbiInfo));
 | 
			
		||||
 | 
			
		||||
			SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiInfo,
 | 
			
		||||
				MessageBoxDefaultButton.Button1);
 | 
			
		||||
 | 
			
		||||
			--m_uCurrentMessageCount;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowWarning(params object[] vLines)
 | 
			
		||||
		{
 | 
			
		||||
			ShowWarningPriv(vLines, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		internal static void ShowWarningExcp(params object[] vLines)
 | 
			
		||||
		{
 | 
			
		||||
			ShowWarningPriv(vLines, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static void ShowWarningPriv(object[] vLines, bool bFullExceptions)
 | 
			
		||||
		{
 | 
			
		||||
			++m_uCurrentMessageCount;
 | 
			
		||||
 | 
			
		||||
			string strTitle = PwDefs.ShortProductName;
 | 
			
		||||
			string strText = ObjectsToMessage(vLines, bFullExceptions);
 | 
			
		||||
 | 
			
		||||
			if(MessageService.MessageShowing != null)
 | 
			
		||||
				MessageService.MessageShowing(null, new MessageServiceEventArgs(
 | 
			
		||||
					strTitle, strText, MessageBoxButtons.OK, m_mbiWarning));
 | 
			
		||||
 | 
			
		||||
			SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiWarning,
 | 
			
		||||
				MessageBoxDefaultButton.Button1);
 | 
			
		||||
 | 
			
		||||
			--m_uCurrentMessageCount;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowFatal(params object[] vLines)
 | 
			
		||||
		{
 | 
			
		||||
			++m_uCurrentMessageCount;
 | 
			
		||||
 | 
			
		||||
			string strTitle = PwDefs.ShortProductName + @" - " + KLRes.FatalError;
 | 
			
		||||
			string strText = KLRes.FatalErrorText + MessageService.NewParagraph +
 | 
			
		||||
				KLRes.ErrorInClipboard + MessageService.NewParagraph +
 | 
			
		||||
				// Please send it to the KeePass developers.
 | 
			
		||||
				// KLRes.ErrorFeedbackRequest + MessageService.NewParagraph +
 | 
			
		||||
				ObjectsToMessage(vLines);
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				Clipboard.Clear();
 | 
			
		||||
				Clipboard.SetText(ObjectsToMessage(vLines, true));
 | 
			
		||||
#else
 | 
			
		||||
				Clipboard.SetDataObject(ObjectsToMessage(vLines, true));
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			if(MessageService.MessageShowing != null)
 | 
			
		||||
				MessageService.MessageShowing(null, new MessageServiceEventArgs(
 | 
			
		||||
					strTitle, strText, MessageBoxButtons.OK, m_mbiFatal));
 | 
			
		||||
 | 
			
		||||
			SafeShowMessageBox(strText, strTitle, MessageBoxButtons.OK, m_mbiFatal,
 | 
			
		||||
				MessageBoxDefaultButton.Button1);
 | 
			
		||||
 | 
			
		||||
			--m_uCurrentMessageCount;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static DialogResult Ask(string strText, string strTitle,
 | 
			
		||||
			MessageBoxButtons mbb)
 | 
			
		||||
		{
 | 
			
		||||
			++m_uCurrentMessageCount;
 | 
			
		||||
 | 
			
		||||
			string strTextEx = (strText ?? string.Empty);
 | 
			
		||||
			string strTitleEx = (strTitle ?? PwDefs.ShortProductName);
 | 
			
		||||
 | 
			
		||||
			if(MessageService.MessageShowing != null)
 | 
			
		||||
				MessageService.MessageShowing(null, new MessageServiceEventArgs(
 | 
			
		||||
					strTitleEx, strTextEx, mbb, m_mbiQuestion));
 | 
			
		||||
 | 
			
		||||
			DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx, mbb,
 | 
			
		||||
				m_mbiQuestion, MessageBoxDefaultButton.Button1);
 | 
			
		||||
 | 
			
		||||
			--m_uCurrentMessageCount;
 | 
			
		||||
			return dr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool AskYesNo(string strText, string strTitle, bool bDefaultToYes)
 | 
			
		||||
		{
 | 
			
		||||
			++m_uCurrentMessageCount;
 | 
			
		||||
 | 
			
		||||
			string strTextEx = (strText ?? string.Empty);
 | 
			
		||||
			string strTitleEx = (strTitle ?? PwDefs.ShortProductName);
 | 
			
		||||
 | 
			
		||||
			if(MessageService.MessageShowing != null)
 | 
			
		||||
				MessageService.MessageShowing(null, new MessageServiceEventArgs(
 | 
			
		||||
					strTitleEx, strTextEx, MessageBoxButtons.YesNo, m_mbiQuestion));
 | 
			
		||||
 | 
			
		||||
			DialogResult dr = SafeShowMessageBox(strTextEx, strTitleEx,
 | 
			
		||||
				MessageBoxButtons.YesNo, m_mbiQuestion, bDefaultToYes ?
 | 
			
		||||
				MessageBoxDefaultButton.Button1 : MessageBoxDefaultButton.Button2);
 | 
			
		||||
 | 
			
		||||
			--m_uCurrentMessageCount;
 | 
			
		||||
			return (dr == DialogResult.Yes);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool AskYesNo(string strText, string strTitle)
 | 
			
		||||
		{
 | 
			
		||||
			return AskYesNo(strText, strTitle, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool AskYesNo(string strText)
 | 
			
		||||
		{
 | 
			
		||||
			return AskYesNo(strText, null, true);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowLoadWarning(string strFilePath, Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			ShowLoadWarning(strFilePath, ex, false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowLoadWarning(string strFilePath, Exception ex,
 | 
			
		||||
			bool bFullException)
 | 
			
		||||
		{
 | 
			
		||||
			string str = string.Empty;
 | 
			
		||||
 | 
			
		||||
			if((strFilePath != null) && (strFilePath.Length > 0))
 | 
			
		||||
				str += strFilePath + MessageService.NewParagraph;
 | 
			
		||||
 | 
			
		||||
			str += KLRes.FileLoadFailed;
 | 
			
		||||
 | 
			
		||||
			if((ex != null) && (ex.Message != null) && (ex.Message.Length > 0))
 | 
			
		||||
			{
 | 
			
		||||
				str += MessageService.NewParagraph;
 | 
			
		||||
				if(!bFullException) str += ex.Message;
 | 
			
		||||
				else str += ObjectsToMessage(new object[] { ex }, true);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ShowWarning(str);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowLoadWarning(IOConnectionInfo ioConnection, Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			if(ioConnection != null)
 | 
			
		||||
				ShowLoadWarning(ioConnection.GetDisplayName(), ex, false);
 | 
			
		||||
			else ShowWarning(ex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowSaveWarning(string strFilePath, Exception ex,
 | 
			
		||||
			bool bCorruptionWarning)
 | 
			
		||||
		{
 | 
			
		||||
			FileLockException fl = (ex as FileLockException);
 | 
			
		||||
			if(fl != null)
 | 
			
		||||
			{
 | 
			
		||||
				ShowWarning(fl.Message);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			string str = string.Empty;
 | 
			
		||||
			if((strFilePath != null) && (strFilePath.Length > 0))
 | 
			
		||||
				str += strFilePath + MessageService.NewParagraph;
 | 
			
		||||
 | 
			
		||||
			str += KLRes.FileSaveFailed;
 | 
			
		||||
 | 
			
		||||
			if((ex != null) && (ex.Message != null) && (ex.Message.Length > 0))
 | 
			
		||||
				str += MessageService.NewParagraph + ex.Message;
 | 
			
		||||
 | 
			
		||||
			if(bCorruptionWarning)
 | 
			
		||||
				str += MessageService.NewParagraph + KLRes.FileSaveCorruptionWarning;
 | 
			
		||||
 | 
			
		||||
			ShowWarning(str);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ShowSaveWarning(IOConnectionInfo ioConnection, Exception ex,
 | 
			
		||||
			bool bCorruptionWarning)
 | 
			
		||||
		{
 | 
			
		||||
			if(ioConnection != null)
 | 
			
		||||
				ShowSaveWarning(ioConnection.GetDisplayName(), ex, bCorruptionWarning);
 | 
			
		||||
			else ShowWarning(ex);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ExternalIncrementMessageCount()
 | 
			
		||||
		{
 | 
			
		||||
			++m_uCurrentMessageCount;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ExternalDecrementMessageCount()
 | 
			
		||||
		{
 | 
			
		||||
			--m_uCurrentMessageCount;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1334
									
								
								src/KeePassLib2Android/Utility/StrUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1334
									
								
								src/KeePassLib2Android/Utility/StrUtil.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										222
									
								
								src/KeePassLib2Android/Utility/TimeUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								src/KeePassLib2Android/Utility/TimeUtil.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,222 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Utility
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// Contains various static time structure manipulation and conversion
 | 
			
		||||
	/// routines.
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class TimeUtil
 | 
			
		||||
	{
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Length of a compressed <c>PW_TIME</c> structure in bytes.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public const int PwTimeLength = 7;
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Pack a <c>DateTime</c> object into 5 bytes. Layout: 2 zero bits,
 | 
			
		||||
		/// year 12 bits, month 4 bits, day 5 bits, hour 5 bits, minute 6
 | 
			
		||||
		/// bits, second 6 bits.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="dt"></param>
 | 
			
		||||
		/// <returns></returns>
 | 
			
		||||
		public static byte[] PackTime(DateTime dt)
 | 
			
		||||
		{
 | 
			
		||||
			byte[] pb = new byte[5];
 | 
			
		||||
 | 
			
		||||
			// Pack time to 5 byte structure:
 | 
			
		||||
			// Byte bits: 11111111 22222222 33333333 44444444 55555555
 | 
			
		||||
			// Contents : 00YYYYYY YYYYYYMM MMDDDDDH HHHHMMMM MMSSSSSS
 | 
			
		||||
			pb[0] = (byte)((dt.Year >> 6) & 0x3F);
 | 
			
		||||
			pb[1] = (byte)(((dt.Year & 0x3F) << 2) | ((dt.Month >> 2) & 0x03));
 | 
			
		||||
			pb[2] = (byte)(((dt.Month & 0x03) << 6) | ((dt.Day & 0x1F) << 1) |
 | 
			
		||||
				((dt.Hour >> 4) & 0x01));
 | 
			
		||||
			pb[3] = (byte)(((dt.Hour & 0x0F) << 4) | ((dt.Minute >> 2) & 0x0F));
 | 
			
		||||
			pb[4] = (byte)(((dt.Minute & 0x03) << 6) | (dt.Second & 0x3F));
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Unpack a packed time (5 bytes, packed by the <c>PackTime</c>
 | 
			
		||||
		/// member function) to a <c>DateTime</c> object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pb">Packed time, 5 bytes.</param>
 | 
			
		||||
		/// <returns>Unpacked <c>DateTime</c> object.</returns>
 | 
			
		||||
		public static DateTime UnpackTime(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert((pb != null) && (pb.Length == 5));
 | 
			
		||||
			if(pb == null) throw new ArgumentNullException("pb");
 | 
			
		||||
			if(pb.Length != 5) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			int n1 = pb[0], n2 = pb[1], n3 = pb[2], n4 = pb[3], n5 = pb[4];
 | 
			
		||||
 | 
			
		||||
			// Unpack 5 byte structure to date and time
 | 
			
		||||
			int nYear = (n1 << 6) | (n2 >> 2);
 | 
			
		||||
			int nMonth = ((n2 & 0x00000003) << 2) | (n3 >> 6);
 | 
			
		||||
			int nDay = (n3 >> 1) & 0x0000001F;
 | 
			
		||||
			int nHour = ((n3 & 0x00000001) << 4) | (n4 >> 4);
 | 
			
		||||
			int nMinute = ((n4 & 0x0000000F) << 2) | (n5 >> 6);
 | 
			
		||||
			int nSecond = n5 & 0x0000003F;
 | 
			
		||||
 | 
			
		||||
			return new DateTime(nYear, nMonth, nDay, nHour, nMinute, nSecond);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Pack a <c>DateTime</c> object into 7 bytes (<c>PW_TIME</c>).
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="dt">Object to be encoded.</param>
 | 
			
		||||
		/// <returns>Packed time, 7 bytes (<c>PW_TIME</c>).</returns>
 | 
			
		||||
		public static byte[] PackPwTime(DateTime dt)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(PwTimeLength == 7);
 | 
			
		||||
 | 
			
		||||
			byte[] pb = new byte[7];
 | 
			
		||||
			pb[0] = (byte)(dt.Year & 0xFF);
 | 
			
		||||
			pb[1] = (byte)(dt.Year >> 8);
 | 
			
		||||
			pb[2] = (byte)dt.Month;
 | 
			
		||||
			pb[3] = (byte)dt.Day;
 | 
			
		||||
			pb[4] = (byte)dt.Hour;
 | 
			
		||||
			pb[5] = (byte)dt.Minute;
 | 
			
		||||
			pb[6] = (byte)dt.Second;
 | 
			
		||||
 | 
			
		||||
			return pb;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Unpack a packed time (7 bytes, <c>PW_TIME</c>) to a <c>DateTime</c> object.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="pb">Packed time, 7 bytes.</param>
 | 
			
		||||
		/// <returns>Unpacked <c>DateTime</c> object.</returns>
 | 
			
		||||
		public static DateTime UnpackPwTime(byte[] pb)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(PwTimeLength == 7);
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(pb != null); if(pb == null) throw new ArgumentNullException("pb");
 | 
			
		||||
			Debug.Assert(pb.Length == 7); if(pb.Length != 7) throw new ArgumentException();
 | 
			
		||||
 | 
			
		||||
			return new DateTime(((int)pb[1] << 8) | (int)pb[0], (int)pb[2], (int)pb[3],
 | 
			
		||||
				(int)pb[4], (int)pb[5], (int)pb[6]);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Convert a <c>DateTime</c> object to a displayable string.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="dt"><c>DateTime</c> object to convert to a string.</param>
 | 
			
		||||
		/// <returns>String representing the specified <c>DateTime</c> object.</returns>
 | 
			
		||||
		public static string ToDisplayString(DateTime dt)
 | 
			
		||||
		{
 | 
			
		||||
			return dt.ToString();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string ToDisplayStringDateOnly(DateTime dt)
 | 
			
		||||
		{
 | 
			
		||||
			return dt.ToString("d");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static DateTime FromDisplayString(string strDisplay)
 | 
			
		||||
		{
 | 
			
		||||
			DateTime dt;
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
			if(DateTime.TryParse(strDisplay, out dt)) return dt;
 | 
			
		||||
#else
 | 
			
		||||
			try { dt = DateTime.Parse(strDisplay); return dt; }
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(false);
 | 
			
		||||
			return DateTime.Now;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string SerializeUtc(DateTime dt)
 | 
			
		||||
		{
 | 
			
		||||
			string str = dt.ToUniversalTime().ToString("s");
 | 
			
		||||
			if(str.EndsWith("Z") == false) str += "Z";
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool TryDeserializeUtc(string str, out DateTime dt)
 | 
			
		||||
		{
 | 
			
		||||
			if(str == null) throw new ArgumentNullException("str");
 | 
			
		||||
 | 
			
		||||
			if(str.EndsWith("Z")) str = str.Substring(0, str.Length - 1);
 | 
			
		||||
 | 
			
		||||
			bool bResult = StrUtil.TryParseDateTime(str, out dt);
 | 
			
		||||
			if(bResult) dt = dt.ToLocalTime();
 | 
			
		||||
			return bResult;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private static DateTime? m_dtUnixRoot = null;
 | 
			
		||||
		public static DateTime ConvertUnixTime(double dtUnix)
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if(!m_dtUnixRoot.HasValue)
 | 
			
		||||
					m_dtUnixRoot = (new DateTime(1970, 1, 1, 0, 0, 0, 0,
 | 
			
		||||
						DateTimeKind.Utc)).ToLocalTime();
 | 
			
		||||
 | 
			
		||||
				return m_dtUnixRoot.Value.AddSeconds(dtUnix);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return DateTime.Now;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
		private static string[] m_vUSMonths = null;
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Parse a US textual date string, like e.g. "January 02, 2012".
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public static DateTime? ParseUSTextDate(string strDate)
 | 
			
		||||
		{
 | 
			
		||||
			if(strDate == null) { Debug.Assert(false); return null; }
 | 
			
		||||
 | 
			
		||||
			if(m_vUSMonths == null)
 | 
			
		||||
				m_vUSMonths = new string[]{ "January", "February", "March",
 | 
			
		||||
					"April", "May", "June", "July", "August", "September",
 | 
			
		||||
					"October", "November", "December" };
 | 
			
		||||
 | 
			
		||||
			string str = strDate.Trim();
 | 
			
		||||
			for(int i = 0; i < m_vUSMonths.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(str.StartsWith(m_vUSMonths[i], StrUtil.CaseIgnoreCmp))
 | 
			
		||||
				{
 | 
			
		||||
					str = str.Substring(m_vUSMonths[i].Length);
 | 
			
		||||
					string[] v = str.Split(new char[]{ ',', ';' });
 | 
			
		||||
					if((v == null) || (v.Length != 2)) return null;
 | 
			
		||||
 | 
			
		||||
					string strDay = v[0].Trim().TrimStart('0');
 | 
			
		||||
					int iDay, iYear;
 | 
			
		||||
					if(int.TryParse(strDay, out iDay) &&
 | 
			
		||||
						int.TryParse(v[1].Trim(), out iYear))
 | 
			
		||||
						return new DateTime(iYear, i + 1, iDay);
 | 
			
		||||
					else { Debug.Assert(false); return null; }
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										609
									
								
								src/KeePassLib2Android/Utility/UrlUtil.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										609
									
								
								src/KeePassLib2Android/Utility/UrlUtil.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,609 @@
 | 
			
		||||
/*
 | 
			
		||||
  KeePass Password Safe - The Open-Source Password Manager
 | 
			
		||||
  Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Runtime.InteropServices;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
using KeePassLib.Native;
 | 
			
		||||
 | 
			
		||||
namespace KeePassLib.Utility
 | 
			
		||||
{
 | 
			
		||||
	/// <summary>
 | 
			
		||||
	/// A class containing various static path utility helper methods (like
 | 
			
		||||
	/// stripping extension from a file, etc.).
 | 
			
		||||
	/// </summary>
 | 
			
		||||
	public static class UrlUtil
 | 
			
		||||
	{
 | 
			
		||||
		private static readonly char[] m_vDirSeps = new char[] { '\\', '/',
 | 
			
		||||
			Path.DirectorySeparatorChar };
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the directory (path) of a file name. The returned string is
 | 
			
		||||
		/// terminated by a directory separator character. Example:
 | 
			
		||||
		/// passing <c>C:\\My Documents\\My File.kdb</c> in <paramref name="strFile" />
 | 
			
		||||
		/// would produce this string: <c>C:\\My Documents\\</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strFile">Full path of a file.</param>
 | 
			
		||||
		/// <param name="bAppendTerminatingChar">Append a terminating directory separator
 | 
			
		||||
		/// character to the returned path.</param>
 | 
			
		||||
		/// <param name="bEnsureValidDirSpec">If <c>true</c>, the returned path
 | 
			
		||||
		/// is guaranteed to be a valid directory path (for example <c>X:\\</c> instead
 | 
			
		||||
		/// of <c>X:</c>, overriding <paramref name="bAppendTerminatingChar" />).
 | 
			
		||||
		/// This should only be set to <c>true</c>, if the returned path is directly
 | 
			
		||||
		/// passed to some directory API.</param>
 | 
			
		||||
		/// <returns>Directory of the file. The return value is an empty string
 | 
			
		||||
		/// (<c>""</c>) if the input parameter is <c>null</c>.</returns>
 | 
			
		||||
		public static string GetFileDirectory(string strFile, bool bAppendTerminatingChar,
 | 
			
		||||
			bool bEnsureValidDirSpec)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strFile != null);
 | 
			
		||||
			if(strFile == null) throw new ArgumentNullException("strFile");
 | 
			
		||||
 | 
			
		||||
			int nLastSep = strFile.LastIndexOfAny(m_vDirSeps);
 | 
			
		||||
			if(nLastSep < 0) return strFile; // None
 | 
			
		||||
 | 
			
		||||
			if(bEnsureValidDirSpec && (nLastSep == 2) && (strFile[1] == ':') &&
 | 
			
		||||
				(strFile[2] == '\\')) // Length >= 3 and Windows root directory
 | 
			
		||||
				bAppendTerminatingChar = true;
 | 
			
		||||
 | 
			
		||||
			if(!bAppendTerminatingChar) return strFile.Substring(0, nLastSep);
 | 
			
		||||
			return EnsureTerminatingSeparator(strFile.Substring(0, nLastSep), false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Gets the file name of the specified file (full path). Example:
 | 
			
		||||
		/// if <paramref name="strPath" /> is <c>C:\\My Documents\\My File.kdb</c>
 | 
			
		||||
		/// the returned string is <c>My File.kdb</c>.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strPath">Full path of a file.</param>
 | 
			
		||||
		/// <returns>File name of the specified file. The return value is
 | 
			
		||||
		/// an empty string (<c>""</c>) if the input parameter is <c>null</c>.</returns>
 | 
			
		||||
		public static string GetFileName(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
 | 
			
		||||
			int nLastSep = strPath.LastIndexOfAny(m_vDirSeps);
 | 
			
		||||
 | 
			
		||||
			if(nLastSep < 0) return strPath;
 | 
			
		||||
			if(nLastSep >= (strPath.Length - 1)) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			return strPath.Substring(nLastSep + 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Strip the extension of a file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strPath">Full path of a file with extension.</param>
 | 
			
		||||
		/// <returns>File name without extension.</returns>
 | 
			
		||||
		public static string StripExtension(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
 | 
			
		||||
			int nLastDirSep = strPath.LastIndexOfAny(m_vDirSeps);
 | 
			
		||||
			int nLastExtDot = strPath.LastIndexOf('.');
 | 
			
		||||
 | 
			
		||||
			if(nLastExtDot <= nLastDirSep) return strPath;
 | 
			
		||||
 | 
			
		||||
			return strPath.Substring(0, nLastExtDot);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the extension of a file.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strPath">Full path of a file with extension.</param>
 | 
			
		||||
		/// <returns>Extension without prepending dot.</returns>
 | 
			
		||||
		public static string GetExtension(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
 | 
			
		||||
			int nLastDirSep = strPath.LastIndexOfAny(m_vDirSeps);
 | 
			
		||||
			int nLastExtDot = strPath.LastIndexOf('.');
 | 
			
		||||
 | 
			
		||||
			if(nLastExtDot <= nLastDirSep) return string.Empty;
 | 
			
		||||
			if(nLastExtDot == (strPath.Length - 1)) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			return strPath.Substring(nLastExtDot + 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Ensure that a path is terminated with a directory separator character.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strPath">Input path.</param>
 | 
			
		||||
		/// <param name="bUrl">If <c>true</c>, a slash (<c>/</c>) is appended to
 | 
			
		||||
		/// the string if it's not terminated already. If <c>false</c>, the
 | 
			
		||||
		/// default system directory separator character is used.</param>
 | 
			
		||||
		/// <returns>Path having a directory separator as last character.</returns>
 | 
			
		||||
		public static string EnsureTerminatingSeparator(string strPath, bool bUrl)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strPath != null); if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
 | 
			
		||||
			int nLength = strPath.Length;
 | 
			
		||||
			if(nLength <= 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			char chLast = strPath[nLength - 1];
 | 
			
		||||
 | 
			
		||||
			for(int i = 0; i < m_vDirSeps.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				if(chLast == m_vDirSeps[i]) return strPath;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(bUrl) return (strPath + '/');
 | 
			
		||||
			return (strPath + Path.DirectorySeparatorChar);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* /// <summary>
 | 
			
		||||
		/// File access mode enumeration. Used by the <c>FileAccessible</c>
 | 
			
		||||
		/// method.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		public enum FileAccessMode
 | 
			
		||||
		{
 | 
			
		||||
			/// <summary>
 | 
			
		||||
			/// Opening a file in read mode. The specified file must exist.
 | 
			
		||||
			/// </summary>
 | 
			
		||||
			Read = 0,
 | 
			
		||||
 | 
			
		||||
			/// <summary>
 | 
			
		||||
			/// Opening a file in create mode. If the file exists already, it
 | 
			
		||||
			/// will be overwritten. If it doesn't exist, it will be created.
 | 
			
		||||
			/// The return value is <c>true</c>, if data can be written to the
 | 
			
		||||
			/// file.
 | 
			
		||||
			/// </summary>
 | 
			
		||||
			Create
 | 
			
		||||
		} */
 | 
			
		||||
 | 
			
		||||
		/* /// <summary>
 | 
			
		||||
		/// Test if a specified path is accessible, either in read or write mode.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <param name="strFilePath">Path to test.</param>
 | 
			
		||||
		/// <param name="fMode">Requested file access mode.</param>
 | 
			
		||||
		/// <returns>Returns <c>true</c> if the specified path is accessible in
 | 
			
		||||
		/// the requested mode, otherwise the return value is <c>false</c>.</returns>
 | 
			
		||||
		public static bool FileAccessible(string strFilePath, FileAccessMode fMode)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strFilePath != null);
 | 
			
		||||
			if(strFilePath == null) throw new ArgumentNullException("strFilePath");
 | 
			
		||||
 | 
			
		||||
			if(fMode == FileAccessMode.Read)
 | 
			
		||||
			{
 | 
			
		||||
				FileStream fs;
 | 
			
		||||
 | 
			
		||||
				try { fs = File.OpenRead(strFilePath); }
 | 
			
		||||
				catch(Exception) { return false; }
 | 
			
		||||
				if(fs == null) return false;
 | 
			
		||||
 | 
			
		||||
				fs.Close();
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			else if(fMode == FileAccessMode.Create)
 | 
			
		||||
			{
 | 
			
		||||
				FileStream fs;
 | 
			
		||||
 | 
			
		||||
				try { fs = File.Create(strFilePath); }
 | 
			
		||||
				catch(Exception) { return false; }
 | 
			
		||||
				if(fs == null) return false;
 | 
			
		||||
 | 
			
		||||
				fs.Close();
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		} */
 | 
			
		||||
 | 
			
		||||
		public static string GetQuotedAppPath(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			int nFirst = strPath.IndexOf('\"');
 | 
			
		||||
			int nSecond = strPath.IndexOf('\"', nFirst + 1);
 | 
			
		||||
 | 
			
		||||
			if((nFirst >= 0) && (nSecond >= 0))
 | 
			
		||||
				return strPath.Substring(nFirst + 1, nSecond - nFirst - 1);
 | 
			
		||||
 | 
			
		||||
			return strPath;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string FileUrlToPath(string strUrl)
 | 
			
		||||
		{
 | 
			
		||||
			Debug.Assert(strUrl != null);
 | 
			
		||||
			if(strUrl == null) throw new ArgumentNullException("strUrl");
 | 
			
		||||
 | 
			
		||||
			string str = strUrl;
 | 
			
		||||
			if(str.StartsWith(@"file:///", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
				str = str.Substring(8, str.Length - 8);
 | 
			
		||||
 | 
			
		||||
			str = str.Replace('/', Path.DirectorySeparatorChar);
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool UnhideFile(string strFile)
 | 
			
		||||
		{
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
			return false;
 | 
			
		||||
#else
 | 
			
		||||
			if(strFile == null) throw new ArgumentNullException("strFile");
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				FileAttributes fa = File.GetAttributes(strFile);
 | 
			
		||||
				if((long)(fa & FileAttributes.Hidden) == 0) return false;
 | 
			
		||||
 | 
			
		||||
				return HideFile(strFile, false);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool HideFile(string strFile, bool bHide)
 | 
			
		||||
		{
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
			return false;
 | 
			
		||||
#else
 | 
			
		||||
			if(strFile == null) throw new ArgumentNullException("strFile");
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				FileAttributes fa = File.GetAttributes(strFile);
 | 
			
		||||
 | 
			
		||||
				if(bHide) fa = ((fa & ~FileAttributes.Normal) | FileAttributes.Hidden);
 | 
			
		||||
				else // Unhide
 | 
			
		||||
				{
 | 
			
		||||
					fa &= ~FileAttributes.Hidden;
 | 
			
		||||
					if((long)fa == 0) fa |= FileAttributes.Normal;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				File.SetAttributes(strFile, fa);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { }
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string MakeRelativePath(string strBaseFile, string strTargetFile)
 | 
			
		||||
		{
 | 
			
		||||
			if(strBaseFile == null) throw new ArgumentNullException("strBasePath");
 | 
			
		||||
			if(strTargetFile == null) throw new ArgumentNullException("strTargetPath");
 | 
			
		||||
			if(strBaseFile.Length == 0) return strTargetFile;
 | 
			
		||||
			if(strTargetFile.Length == 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			// Test whether on different Windows drives
 | 
			
		||||
			if((strBaseFile.Length >= 3) && (strTargetFile.Length >= 3))
 | 
			
		||||
			{
 | 
			
		||||
				if((strBaseFile[1] == ':') && (strTargetFile[1] == ':') &&
 | 
			
		||||
					(strBaseFile[2] == '\\') && (strTargetFile[2] == '\\') &&
 | 
			
		||||
					(strBaseFile[0] != strTargetFile[0]))
 | 
			
		||||
					return strTargetFile;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(NativeLib.IsUnix())
 | 
			
		||||
			{
 | 
			
		||||
				bool bBaseUnc = IsUncPath(strBaseFile);
 | 
			
		||||
				bool bTargetUnc = IsUncPath(strTargetFile);
 | 
			
		||||
				if((!bBaseUnc && bTargetUnc) || (bBaseUnc && !bTargetUnc))
 | 
			
		||||
					return strTargetFile;
 | 
			
		||||
 | 
			
		||||
				string strBase = GetShortestAbsolutePath(strBaseFile);
 | 
			
		||||
				string strTarget = GetShortestAbsolutePath(strTargetFile);
 | 
			
		||||
				string[] vBase = strBase.Split(m_vDirSeps);
 | 
			
		||||
				string[] vTarget = strTarget.Split(m_vDirSeps);
 | 
			
		||||
 | 
			
		||||
				int i = 0;
 | 
			
		||||
				while((i < (vBase.Length - 1)) && (i < (vTarget.Length - 1)) &&
 | 
			
		||||
					(vBase[i] == vTarget[i])) { ++i; }
 | 
			
		||||
 | 
			
		||||
				StringBuilder sbRel = new StringBuilder();
 | 
			
		||||
				for(int j = i; j < (vBase.Length - 1); ++j)
 | 
			
		||||
				{
 | 
			
		||||
					if(sbRel.Length > 0) sbRel.Append(Path.DirectorySeparatorChar);
 | 
			
		||||
					sbRel.Append("..");
 | 
			
		||||
				}
 | 
			
		||||
				for(int k = i; k < vTarget.Length; ++k)
 | 
			
		||||
				{
 | 
			
		||||
					if(sbRel.Length > 0) sbRel.Append(Path.DirectorySeparatorChar);
 | 
			
		||||
					sbRel.Append(vTarget[k]);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return sbRel.ToString();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
#if KeePassLibSD
 | 
			
		||||
			return strTargetFile;
 | 
			
		||||
#else
 | 
			
		||||
			try // Windows
 | 
			
		||||
			{
 | 
			
		||||
				const int nMaxPath = NativeMethods.MAX_PATH * 2;
 | 
			
		||||
				StringBuilder sb = new StringBuilder(nMaxPath + 2);
 | 
			
		||||
				if(NativeMethods.PathRelativePathTo(sb, strBaseFile, 0,
 | 
			
		||||
					strTargetFile, 0) == false)
 | 
			
		||||
					return strTargetFile;
 | 
			
		||||
 | 
			
		||||
				string str = sb.ToString();
 | 
			
		||||
				while(str.StartsWith(".\\")) str = str.Substring(2, str.Length - 2);
 | 
			
		||||
 | 
			
		||||
				return str;
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); return strTargetFile; }
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string MakeAbsolutePath(string strBaseFile, string strTargetFile)
 | 
			
		||||
		{
 | 
			
		||||
			if(strBaseFile == null) throw new ArgumentNullException("strBasePath");
 | 
			
		||||
			if(strTargetFile == null) throw new ArgumentNullException("strTargetPath");
 | 
			
		||||
			if(strBaseFile.Length == 0) return strTargetFile;
 | 
			
		||||
			if(strTargetFile.Length == 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			if(IsAbsolutePath(strTargetFile)) return strTargetFile;
 | 
			
		||||
 | 
			
		||||
			string strBaseDir = GetFileDirectory(strBaseFile, true, false);
 | 
			
		||||
			return GetShortestAbsolutePath(strBaseDir + strTargetFile);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool IsAbsolutePath(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
			if(strPath.Length == 0) return false;
 | 
			
		||||
 | 
			
		||||
			if(IsUncPath(strPath)) return true;
 | 
			
		||||
 | 
			
		||||
			try { return Path.IsPathRooted(strPath); }
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string GetShortestAbsolutePath(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
			if(strPath.Length == 0) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			// Path.GetFullPath is incompatible with UNC paths traversing over
 | 
			
		||||
			// different server shares (which are created by PathRelativePathTo);
 | 
			
		||||
			// we need to build the absolute path on our own...
 | 
			
		||||
			if(IsUncPath(strPath))
 | 
			
		||||
			{
 | 
			
		||||
				char chSep = strPath[0];
 | 
			
		||||
				Debug.Assert(Array.IndexOf<char>(m_vDirSeps, chSep) >= 0);
 | 
			
		||||
 | 
			
		||||
				List<string> l = new List<string>();
 | 
			
		||||
#if !KeePassLibSD
 | 
			
		||||
				string[] v = strPath.Split(m_vDirSeps, StringSplitOptions.None);
 | 
			
		||||
#else
 | 
			
		||||
				string[] v = strPath.Split(m_vDirSeps);
 | 
			
		||||
#endif
 | 
			
		||||
				Debug.Assert((v.Length >= 3) && (v[0].Length == 0) &&
 | 
			
		||||
					(v[1].Length == 0));
 | 
			
		||||
 | 
			
		||||
				foreach(string strPart in v)
 | 
			
		||||
				{
 | 
			
		||||
					if(strPart.Equals(".")) continue;
 | 
			
		||||
					else if(strPart.Equals(".."))
 | 
			
		||||
					{
 | 
			
		||||
						if(l.Count > 0) l.RemoveAt(l.Count - 1);
 | 
			
		||||
						else { Debug.Assert(false); }
 | 
			
		||||
					}
 | 
			
		||||
					else l.Add(strPart); // Do not ignore zero length parts
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				StringBuilder sb = new StringBuilder();
 | 
			
		||||
				for(int i = 0; i < l.Count; ++i)
 | 
			
		||||
				{
 | 
			
		||||
					// Don't test length of sb, might be 0 due to initial UNC seps
 | 
			
		||||
					if(i > 0) sb.Append(chSep);
 | 
			
		||||
 | 
			
		||||
					sb.Append(l[i]);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return sb.ToString();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			string str;
 | 
			
		||||
			try { str = Path.GetFullPath(strPath); }
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); return strPath; }
 | 
			
		||||
 | 
			
		||||
			Debug.Assert(str.IndexOf("\\..\\") < 0);
 | 
			
		||||
			foreach(char ch in m_vDirSeps)
 | 
			
		||||
			{
 | 
			
		||||
				string strSep = new string(ch, 1);
 | 
			
		||||
				str = str.Replace(strSep + "." + strSep, strSep);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static int GetUrlLength(string strText, int nOffset)
 | 
			
		||||
		{
 | 
			
		||||
			if(strText == null) throw new ArgumentNullException("strText");
 | 
			
		||||
			if(nOffset > strText.Length) throw new ArgumentException(); // Not >= (0 len)
 | 
			
		||||
 | 
			
		||||
			int iPosition = nOffset, nLength = 0, nStrLen = strText.Length;
 | 
			
		||||
 | 
			
		||||
			while(iPosition < nStrLen)
 | 
			
		||||
			{
 | 
			
		||||
				char ch = strText[iPosition];
 | 
			
		||||
				++iPosition;
 | 
			
		||||
 | 
			
		||||
				if((ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n'))
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				++nLength;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return nLength;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string RemoveScheme(string strUrl)
 | 
			
		||||
		{
 | 
			
		||||
			if(string.IsNullOrEmpty(strUrl)) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			int nNetScheme = strUrl.IndexOf(@"://", StrUtil.CaseIgnoreCmp);
 | 
			
		||||
			int nShScheme = strUrl.IndexOf(@":/", StrUtil.CaseIgnoreCmp);
 | 
			
		||||
			int nSmpScheme = strUrl.IndexOf(@":", StrUtil.CaseIgnoreCmp);
 | 
			
		||||
 | 
			
		||||
			if((nNetScheme < 0) && (nShScheme < 0) && (nSmpScheme < 0))
 | 
			
		||||
				return strUrl; // No scheme
 | 
			
		||||
 | 
			
		||||
			int nMin = Math.Min(Math.Min((nNetScheme >= 0) ? nNetScheme : int.MaxValue,
 | 
			
		||||
				(nShScheme >= 0) ? nShScheme : int.MaxValue),
 | 
			
		||||
				(nSmpScheme >= 0) ? nSmpScheme : int.MaxValue);
 | 
			
		||||
 | 
			
		||||
			if(nMin == nNetScheme) return strUrl.Substring(nMin + 3);
 | 
			
		||||
			if(nMin == nShScheme) return strUrl.Substring(nMin + 2);
 | 
			
		||||
			return strUrl.Substring(nMin + 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string ConvertSeparators(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			return ConvertSeparators(strPath, Path.DirectorySeparatorChar);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string ConvertSeparators(string strPath, char chSeparator)
 | 
			
		||||
		{
 | 
			
		||||
			if(string.IsNullOrEmpty(strPath)) return string.Empty;
 | 
			
		||||
 | 
			
		||||
			strPath = strPath.Replace('/', chSeparator);
 | 
			
		||||
			strPath = strPath.Replace('\\', chSeparator);
 | 
			
		||||
 | 
			
		||||
			return strPath;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool IsUncPath(string strPath)
 | 
			
		||||
		{
 | 
			
		||||
			if(strPath == null) throw new ArgumentNullException("strPath");
 | 
			
		||||
 | 
			
		||||
			return (strPath.StartsWith("\\\\") || strPath.StartsWith("//"));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string FilterFileName(string strName)
 | 
			
		||||
		{
 | 
			
		||||
			if(strName == null) { Debug.Assert(false); return string.Empty; }
 | 
			
		||||
 | 
			
		||||
			string str = strName;
 | 
			
		||||
 | 
			
		||||
			str = str.Replace('/', '-');
 | 
			
		||||
			str = str.Replace('\\', '-');
 | 
			
		||||
			str = str.Replace(":", string.Empty);
 | 
			
		||||
			str = str.Replace("*", string.Empty);
 | 
			
		||||
			str = str.Replace("?", string.Empty);
 | 
			
		||||
			str = str.Replace("\"", string.Empty);
 | 
			
		||||
			str = str.Replace(@"'", string.Empty);
 | 
			
		||||
			str = str.Replace('<', '(');
 | 
			
		||||
			str = str.Replace('>', ')');
 | 
			
		||||
			str = str.Replace('|', '-');
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/// <summary>
 | 
			
		||||
		/// Get the host component of an URL.
 | 
			
		||||
		/// This method is faster and more fault-tolerant than creating
 | 
			
		||||
		/// an <code>Uri</code> object and querying its <code>Host</code>
 | 
			
		||||
		/// property.
 | 
			
		||||
		/// </summary>
 | 
			
		||||
		/// <example>
 | 
			
		||||
		/// For the input <code>s://u:p@d.tld:p/p?q#f</code> the return
 | 
			
		||||
		/// value is <code>d.tld</code>.
 | 
			
		||||
		/// </example>
 | 
			
		||||
		public static string GetHost(string strUrl)
 | 
			
		||||
		{
 | 
			
		||||
			if(strUrl == null) { Debug.Assert(false); return string.Empty; }
 | 
			
		||||
 | 
			
		||||
			StringBuilder sb = new StringBuilder();
 | 
			
		||||
			bool bInExtHost = false;
 | 
			
		||||
			for(int i = 0; i < strUrl.Length; ++i)
 | 
			
		||||
			{
 | 
			
		||||
				char ch = strUrl[i];
 | 
			
		||||
				if(bInExtHost)
 | 
			
		||||
				{
 | 
			
		||||
					if(ch == '/')
 | 
			
		||||
					{
 | 
			
		||||
						if(sb.Length == 0) { } // Ignore leading '/'s
 | 
			
		||||
						else break;
 | 
			
		||||
					}
 | 
			
		||||
					else sb.Append(ch);
 | 
			
		||||
				}
 | 
			
		||||
				else // !bInExtHost
 | 
			
		||||
				{
 | 
			
		||||
					if(ch == ':') bInExtHost = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			string str = sb.ToString();
 | 
			
		||||
			if(str.Length == 0) str = strUrl;
 | 
			
		||||
 | 
			
		||||
			// Remove the login part
 | 
			
		||||
			int nLoginLen = str.IndexOf('@');
 | 
			
		||||
			if(nLoginLen >= 0) str = str.Substring(nLoginLen + 1);
 | 
			
		||||
 | 
			
		||||
			// Remove the port
 | 
			
		||||
			int iPort = str.LastIndexOf(':');
 | 
			
		||||
			if(iPort >= 0) str = str.Substring(0, iPort);
 | 
			
		||||
 | 
			
		||||
			return str;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static bool AssemblyEquals(string strExt, string strShort)
 | 
			
		||||
		{
 | 
			
		||||
			if((strExt == null) || (strShort == null)) { Debug.Assert(false); return false; }
 | 
			
		||||
 | 
			
		||||
			if(strExt.Equals(strShort, StrUtil.CaseIgnoreCmp) ||
 | 
			
		||||
				strExt.StartsWith(strShort + ",", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
				return true;
 | 
			
		||||
 | 
			
		||||
			if(!strShort.EndsWith(".dll", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
			{
 | 
			
		||||
				if(strExt.Equals(strShort + ".dll", StrUtil.CaseIgnoreCmp) ||
 | 
			
		||||
					strExt.StartsWith(strShort + ".dll,", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
					return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(!strShort.EndsWith(".exe", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
			{
 | 
			
		||||
				if(strExt.Equals(strShort + ".exe", StrUtil.CaseIgnoreCmp) ||
 | 
			
		||||
					strExt.StartsWith(strShort + ".exe,", StrUtil.CaseIgnoreCmp))
 | 
			
		||||
					return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static string GetTempPath()
 | 
			
		||||
		{
 | 
			
		||||
			string strDir;
 | 
			
		||||
			if(NativeLib.IsUnix())
 | 
			
		||||
				strDir = NativeMethods.GetUserRuntimeDir();
 | 
			
		||||
			else strDir = Path.GetTempPath();
 | 
			
		||||
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				if(Directory.Exists(strDir) == false)
 | 
			
		||||
					Directory.CreateDirectory(strDir);
 | 
			
		||||
			}
 | 
			
		||||
			catch(Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
			return strDir;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user