1 /*
2   KeePass Password Safe - The Open-Source Password Manager
3   Copyright (C) 2003-2021 Dominik Reichl <dominik.reichl@t-online.de>
4 
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19 
20 using System;
21 using System.Collections.Generic;
22 using System.ComponentModel;
23 using System.Text;
24 using System.Xml.Serialization;
25 
26 using KeePass.Util;
27 
28 using KeePassLib;
29 using KeePassLib.Keys;
30 using KeePassLib.Serialization;
31 using KeePassLib.Utility;
32 
33 namespace KeePass.App.Configuration
34 {
35 	public sealed class AceKeyAssoc
36 	{
37 		private string m_strDb = string.Empty;
38 		public string DatabasePath
39 		{
40 			get { return m_strDb; }
41 			set
42 			{
43 				if(value == null) throw new ArgumentNullException("value");
44 				m_strDb = value;
45 			}
46 		}
47 
48 		private bool m_bPassword = false;
49 		[DefaultValue(false)]
50 		public bool Password
51 		{
52 			get { return m_bPassword; }
53 			set { m_bPassword = value; }
54 		}
55 
56 		private string m_strKey = string.Empty;
57 		[DefaultValue("")]
58 		public string KeyFilePath
59 		{
60 			get { return m_strKey; }
61 			set
62 			{
63 				if(value == null) throw new ArgumentNullException("value");
64 				m_strKey = value;
65 			}
66 		}
67 
68 		private string m_strProv = string.Empty;
69 		[DefaultValue("")]
70 		public string KeyProvider
71 		{
72 			get { return m_strProv; }
73 			set
74 			{
75 				if(value == null) throw new ArgumentNullException("value");
76 				m_strProv = value;
77 			}
78 		}
79 
80 		private bool m_bUserAcc = false;
81 		[DefaultValue(false)]
82 		public bool UserAccount
83 		{
84 			get { return m_bUserAcc; }
85 			set { m_bUserAcc = value; }
86 		}
87 
AceKeyAssoc()88 		public AceKeyAssoc() { }
89 	}
90 
91 	public sealed class AceDefaults
92 	{
AceDefaults()93 		public AceDefaults()
94 		{
95 		}
96 
97 		private int m_nNewEntryExpireDays = -1;
98 		[DefaultValue(-1)]
99 		public int NewEntryExpiresInDays
100 		{
101 			get { return m_nNewEntryExpireDays; }
102 			set { m_nNewEntryExpireDays = value; }
103 		}
104 
105 		private uint m_uDefaultOptionsTab = 0;
106 		public uint OptionsTabIndex
107 		{
108 			get { return m_uDefaultOptionsTab; }
109 			set { m_uDefaultOptionsTab = value; }
110 		}
111 
112 		private const string DefaultTanChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
113 		private string m_strTanChars = DefaultTanChars;
114 		[DefaultValue(DefaultTanChars)]
115 		public string TanCharacters
116 		{
117 			get { return m_strTanChars; }
118 			set
119 			{
120 				if(value == null) throw new ArgumentNullException("value");
121 				m_strTanChars = value;
122 			}
123 		}
124 
125 		private bool m_bExpireTansOnUse = true;
126 		[DefaultValue(true)]
127 		public bool TanExpiresOnUse
128 		{
129 			get { return m_bExpireTansOnUse; }
130 			set { m_bExpireTansOnUse = value; }
131 		}
132 
133 		private string m_strDbSaveAsPath = string.Empty;
134 		[DefaultValue("")]
135 		public string FileSaveAsDirectory
136 		{
137 			get { return m_strDbSaveAsPath; }
138 			set
139 			{
140 				if(value == null) throw new ArgumentNullException("value");
141 				m_strDbSaveAsPath = value;
142 			}
143 		}
144 
145 		private bool m_bRememberKeySources = true;
146 		[DefaultValue(true)]
147 		public bool RememberKeySources
148 		{
149 			get { return m_bRememberKeySources; }
150 			set { m_bRememberKeySources = value; }
151 		}
152 
153 		private List<AceKeyAssoc> m_vKeySources = new List<AceKeyAssoc>();
154 		[XmlArrayItem("Association")]
155 		public List<AceKeyAssoc> KeySources
156 		{
157 			get { return m_vKeySources; }
158 			set
159 			{
160 				if(value == null) throw new ArgumentNullException("value");
161 				m_vKeySources = value;
162 			}
163 		}
164 
165 		private string m_strCustomColors = string.Empty;
166 		[DefaultValue("")]
167 		public string CustomColors
168 		{
169 			get { return m_strCustomColors; }
170 			set
171 			{
172 				if(value == null) throw new ArgumentNullException("value");
173 				m_strCustomColors = value;
174 			}
175 		}
176 
177 		private bool m_bExportMasterKeySpec = false;
178 		[DefaultValue(false)]
179 		public bool ExportMasterKeySpec
180 		{
181 			get { return m_bExportMasterKeySpec; }
182 			set { m_bExportMasterKeySpec = value; }
183 		}
184 
185 		private bool m_bExportParentGroups = false;
186 		[DefaultValue(false)]
187 		public bool ExportParentGroups
188 		{
189 			get { return m_bExportParentGroups; }
190 			set { m_bExportParentGroups = value; }
191 		}
192 
193 		private bool m_bExportPostOpen = false;
194 		[DefaultValue(false)]
195 		public bool ExportPostOpen
196 		{
197 			get { return m_bExportPostOpen; }
198 			set { m_bExportPostOpen = value; }
199 		}
200 
201 		private bool m_bExportPostShow = false;
202 		[DefaultValue(false)]
203 		public bool ExportPostShow
204 		{
205 			get { return m_bExportPostShow; }
206 			set { m_bExportPostShow = value; }
207 		}
208 
209 		private string m_strWinFavsBaseName = string.Empty;
210 		[DefaultValue("")]
211 		public string WinFavsBaseFolderName
212 		{
213 			get { return m_strWinFavsBaseName; }
214 			set
215 			{
216 				if(value == null) throw new ArgumentNullException("value");
217 				m_strWinFavsBaseName = value;
218 			}
219 		}
220 
221 		private string m_strWinFavsFilePrefix = string.Empty;
222 		[DefaultValue("")]
223 		public string WinFavsFileNamePrefix
224 		{
225 			get { return m_strWinFavsFilePrefix; }
226 			set
227 			{
228 				if(value == null) throw new ArgumentNullException("value");
229 				m_strWinFavsFilePrefix = value;
230 			}
231 		}
232 
233 		private string m_strWinFavsFileSuffix = string.Empty;
234 		[DefaultValue("")]
235 		public string WinFavsFileNameSuffix
236 		{
237 			get { return m_strWinFavsFileSuffix; }
238 			set
239 			{
240 				if(value == null) throw new ArgumentNullException("value");
241 				m_strWinFavsFileSuffix = value;
242 			}
243 		}
244 
245 		private bool m_bCollapseRecycleBin = false;
246 		[DefaultValue(false)]
247 		public bool RecycleBinCollapse
248 		{
249 			get { return m_bCollapseRecycleBin; }
250 			set { m_bCollapseRecycleBin = value; }
251 		}
252 
GetKeyAssocID(IOConnectionInfo iocDb)253 		private static string GetKeyAssocID(IOConnectionInfo iocDb)
254 		{
255 			if(iocDb == null) throw new ArgumentNullException("iocDb");
256 
257 			string strDb = iocDb.Path;
258 			if((strDb.Length > 0) && iocDb.IsLocalFile() &&
259 				!UrlUtil.IsAbsolutePath(strDb))
260 				strDb = UrlUtil.MakeAbsolutePath(WinUtil.GetExecutable(), strDb);
261 
262 			return strDb;
263 		}
264 
GetKeyAssocIndex(string strID)265 		private int GetKeyAssocIndex(string strID)
266 		{
267 			for(int i = 0; i < m_vKeySources.Count; ++i)
268 			{
269 				if(strID.Equals(m_vKeySources[i].DatabasePath, StrUtil.CaseIgnoreCmp))
270 					return i;
271 			}
272 
273 			return -1;
274 		}
275 
SetKeySources(IOConnectionInfo iocDb, CompositeKey cmpKey)276 		public void SetKeySources(IOConnectionInfo iocDb, CompositeKey cmpKey)
277 		{
278 			string strID = GetKeyAssocID(iocDb);
279 			int idx = GetKeyAssocIndex(strID);
280 
281 			if((cmpKey == null) || !m_bRememberKeySources)
282 			{
283 				if(idx >= 0) m_vKeySources.RemoveAt(idx);
284 				return;
285 			}
286 
287 			AceKeyAssoc a = new AceKeyAssoc();
288 			a.DatabasePath = strID;
289 
290 			IUserKey kcpPassword = cmpKey.GetUserKey(typeof(KcpPassword));
291 			a.Password = (kcpPassword != null);
292 
293 			IUserKey kcpFile = cmpKey.GetUserKey(typeof(KcpKeyFile));
294 			if(kcpFile != null)
295 			{
296 				string strKeyFile = ((KcpKeyFile)kcpFile).Path;
297 				if(!string.IsNullOrEmpty(strKeyFile) && !StrUtil.IsDataUri(strKeyFile))
298 				{
299 					if(!UrlUtil.IsAbsolutePath(strKeyFile))
300 						strKeyFile = UrlUtil.MakeAbsolutePath(WinUtil.GetExecutable(),
301 							strKeyFile);
302 
303 					a.KeyFilePath = strKeyFile;
304 				}
305 			}
306 
307 			IUserKey kcpCustom = cmpKey.GetUserKey(typeof(KcpCustomKey));
308 			if(kcpCustom != null)
309 				a.KeyProvider = ((KcpCustomKey)kcpCustom).Name;
310 
311 			IUserKey kcpUser = cmpKey.GetUserKey(typeof(KcpUserAccount));
312 			a.UserAccount = (kcpUser != null);
313 
314 			bool bAtLeastOne = (a.Password || (a.KeyFilePath.Length > 0) ||
315 				(a.KeyProvider.Length > 0) || a.UserAccount);
316 			if(bAtLeastOne)
317 			{
318 				if(idx >= 0) m_vKeySources[idx] = a;
319 				else m_vKeySources.Add(a);
320 			}
321 			else if(idx >= 0) m_vKeySources.RemoveAt(idx);
322 		}
323 
GetKeySources(IOConnectionInfo iocDb)324 		public AceKeyAssoc GetKeySources(IOConnectionInfo iocDb)
325 		{
326 			string strID = GetKeyAssocID(iocDb);
327 			int idx = GetKeyAssocIndex(strID);
328 
329 			if(!m_bRememberKeySources) return null;
330 
331 			if(idx >= 0) return m_vKeySources[idx];
332 			return null;
333 		}
334 	}
335 }
336