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.Text;
23 using System.IO;
24 using System.Net.NetworkInformation;
25 using System.Windows.Forms;
26 using System.Diagnostics;
27 
28 using KeePass.Resources;
29 using KeePass.UI;
30 
31 using KeePassLib;
32 using KeePassLib.Serialization;
33 using KeePassLib.Utility;
34 
35 namespace KeePass.Ecas
36 {
37 	internal sealed class EcasDefaultConditionProvider : EcasConditionProvider
38 	{
EcasDefaultConditionProvider()39 		public EcasDefaultConditionProvider()
40 		{
41 			m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] {
42 				0x9F, 0x11, 0xD0, 0xBD, 0xEC, 0xE9, 0x45, 0x3B,
43 				0xA5, 0x45, 0x26, 0x1F, 0xF7, 0xA4, 0xFF, 0x1F }),
44 				KPRes.EnvironmentVariable, PwIcon.Console, new EcasParameter[] {
45 					new EcasParameter(KPRes.Name, EcasValueType.String, null),
46 					new EcasParameter(KPRes.Value + " - " + KPRes.Comparison,
47 						EcasValueType.EnumStrings, EcasUtil.StdStringCompare),
48 					new EcasParameter(KPRes.Value, EcasValueType.String, null) },
49 				IsMatchEnvironmentVar));
50 
51 			m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] {
52 				0xB9, 0x0F, 0xF8, 0x07, 0x73, 0x38, 0x4F, 0xEA,
53 				0xBB, 0x2E, 0xBC, 0x0B, 0xEA, 0x3B, 0x98, 0xC3 }),
54 				KPRes.String, PwIcon.Configuration, new EcasParameter[] {
55 					new EcasParameter(KPRes.String, EcasValueType.String, null),
56 					new EcasParameter(KPRes.Value + " - " + KPRes.Comparison,
57 						EcasValueType.EnumStrings, EcasUtil.StdStringCompare),
58 					new EcasParameter(KPRes.Value, EcasValueType.String, null) },
59 				IsMatchString));
60 
61 			m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] {
62 				0xCB, 0x4A, 0x9E, 0x34, 0x56, 0x8C, 0x4C, 0x95,
63 				0xAD, 0x67, 0x4D, 0x1C, 0xA1, 0x04, 0x19, 0xBC }),
64 				KPRes.FileExists, PwIcon.PaperReady, new EcasParameter[] {
65 					new EcasParameter(KPRes.FileOrUrl, EcasValueType.String, null) },
66 				IsMatchFileExists));
67 
68 			m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] {
69 				0x2A, 0x22, 0x83, 0xA8, 0x9D, 0x13, 0x41, 0xE8,
70 				0x99, 0x87, 0x8B, 0xAC, 0x21, 0x8D, 0x81, 0xF4 }),
71 				KPRes.RemoteHostReachable, PwIcon.NetworkServer, new EcasParameter[] {
72 					new EcasParameter(KPRes.Host, EcasValueType.String, null) },
73 				IsHostReachable));
74 
75 			m_conditions.Add(new EcasConditionType(new PwUuid(new byte[] {
76 				0xD3, 0xCA, 0xFA, 0xEF, 0x28, 0x2A, 0x46, 0x4A,
77 				0x99, 0x90, 0xD8, 0x65, 0xFC, 0xE0, 0x16, 0xED }),
78 				KPRes.DatabaseHasUnsavedChanges, PwIcon.PaperFlag, new EcasParameter[] {
79 					new EcasParameter(KPRes.Database, EcasValueType.EnumStrings,
80 						new EcasEnum(new EcasEnumItem[] {
81 							new EcasEnumItem(0, KPRes.Active),
82 							new EcasEnumItem(1, KPRes.Triggering) })) },
83 				IsDatabaseModified));
84 		}
85 
IsMatchEnvironmentVar(EcasCondition c, EcasContext ctx)86 		private static bool IsMatchEnvironmentVar(EcasCondition c, EcasContext ctx)
87 		{
88 			string strName = EcasUtil.GetParamString(c.Parameters, 0, true);
89 			uint uCompareType = EcasUtil.GetParamEnum(c.Parameters, 1,
90 				EcasUtil.StdStringCompareEquals, EcasUtil.StdStringCompare);
91 			string strValue = EcasUtil.GetParamString(c.Parameters, 2, true);
92 
93 			if(string.IsNullOrEmpty(strName) || (strValue == null))
94 				return false;
95 
96 			try
97 			{
98 				string strVar = Environment.GetEnvironmentVariable(strName);
99 				if(strVar == null) return false;
100 
101 				return EcasUtil.CompareStrings(strVar, strValue, uCompareType);
102 			}
103 			catch(Exception) { Debug.Assert(false); }
104 
105 			return false;
106 		}
107 
IsMatchString(EcasCondition c, EcasContext ctx)108 		private static bool IsMatchString(EcasCondition c, EcasContext ctx)
109 		{
110 			string str = EcasUtil.GetParamString(c.Parameters, 0, true);
111 			uint uCompareType = EcasUtil.GetParamEnum(c.Parameters, 1,
112 				EcasUtil.StdStringCompareEquals, EcasUtil.StdStringCompare);
113 			string strValue = EcasUtil.GetParamString(c.Parameters, 2, true);
114 
115 			if((str == null) || (strValue == null)) return false;
116 
117 			return EcasUtil.CompareStrings(str, strValue, uCompareType);
118 		}
119 
IsMatchFileExists(EcasCondition c, EcasContext ctx)120 		private static bool IsMatchFileExists(EcasCondition c, EcasContext ctx)
121 		{
122 			string strFile = EcasUtil.GetParamString(c.Parameters, 0, true);
123 			if(string.IsNullOrEmpty(strFile)) return true;
124 
125 			try
126 			{
127 				// return File.Exists(strFile);
128 
129 				IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
130 				return IOConnection.FileExists(ioc);
131 			}
132 			catch(Exception) { }
133 
134 			return false;
135 		}
136 
IsHostReachable(EcasCondition c, EcasContext ctx)137 		private static bool IsHostReachable(EcasCondition c, EcasContext ctx)
138 		{
139 			string strHost = EcasUtil.GetParamString(c.Parameters, 0, true);
140 			if(string.IsNullOrEmpty(strHost)) return true;
141 
142 			int[] vTimeOuts = { 250, 1250 };
143 			const string strBuffer = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
144 			byte[] pbBuffer = Encoding.ASCII.GetBytes(strBuffer);
145 
146 			try
147 			{
148 				Ping ping = new Ping(); // We have sufficient privileges?
149 				PingOptions options = new PingOptions(64, true);
150 
151 				foreach(int nTimeOut in vTimeOuts)
152 				{
153 					PingReply reply = ping.Send(strHost, nTimeOut, pbBuffer, options);
154 					if(reply.Status == IPStatus.Success) return true;
155 				}
156 
157 				return false;
158 			}
159 			catch(Exception) { }
160 
161 			return false;
162 		}
163 
IsDatabaseModified(EcasCondition c, EcasContext ctx)164 		private static bool IsDatabaseModified(EcasCondition c, EcasContext ctx)
165 		{
166 			PwDatabase pd = null;
167 
168 			uint uSel = EcasUtil.GetParamUInt(c.Parameters, 0, 0);
169 			if(uSel == 0)
170 				pd = Program.MainForm.ActiveDatabase;
171 			else if(uSel == 1)
172 				pd = ctx.Properties.Get<PwDatabase>(EcasProperty.Database);
173 			else { Debug.Assert(false); }
174 
175 			if((pd == null) || !pd.IsOpen) return false;
176 			return pd.Modified;
177 		}
178 	}
179 }
180