/* KeePass Password Safe - The Open-Source Password Manager Copyright (C) 2003-2012 Dominik Reichl 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 ModernKeePassLib.Interfaces; using ModernKeePassLib.Utility; using Windows.Storage; namespace ModernKeePassLib.Serialization { public enum IOCredSaveMode { /// /// Do not remember user name or password. /// NoSave = 0, /// /// Remember the user name only, not the password. /// UserNameOnly, /// /// Save both user name and password. /// SaveCred } public enum IOCredProtMode { None = 0, Obf } /* public enum IOFileFormatHint { None = 0, Deprecated } */ public sealed class IOConnectionInfo : IDeepCloneable { // private IOFileFormatHint m_ioHint = IOFileFormatHint.None; public StorageFile StorageFile { get; set; } 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(); } /* /// /// Serialize the current connection info to a string. Credentials /// are only serialized if the SaveCredentials property /// is true. /// /// Input object to be serialized. /// Serialized object as string. 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; } */ /* /// /// Very simple string protection. Doesn't really encrypt the input /// string, only encodes it that it's not readable on the first glance. /// /// The string to encode/decode. /// If true, the string will be encoded, /// otherwise it'll be decoded. /// Encoded/decoded string. 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 static IOConnectionInfo FromFile(StorageFile file) { IOConnectionInfo ioc = new IOConnectionInfo(); ioc.Path = file.Path; ioc.CredSaveMode = IOCredSaveMode.NoSave; ioc.StorageFile = file; return ioc; } public bool CanProbablyAccess() { Debug.Assert(false, "not yet implemented"); return false; #if TODO if(IsLocalFile()) return File.Exists(m_strUrl); return true; #endif } public bool IsLocalFile() { 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; } } public override bool Equals(object obj) { if (!(obj is IOConnectionInfo)) return false; IOConnectionInfo ioc = obj as IOConnectionInfo; if (ioc.Path != this.Path) return false; if (ioc.UserName != this.UserName) return false; if (ioc.Password != this.Password) return false; return true; } } }