/// <summary> /// Load the authenticator and configuration settings /// </summary> /// <param name="form">parent winform</param> /// <param name="configFile">name of configfile or null for auto</param> /// <param name="password">optional supplied password or null to prompt if necessatu</param> /// <returns>new WinAuthConfig settings</returns> public static WinAuthConfig LoadConfig(MainForm form, string configFile, string password) { WinAuthConfig config = new WinAuthConfig(); if (string.IsNullOrEmpty(configFile) == true) { configFile = GetLastFile(1); if (string.IsNullOrEmpty(configFile) == false && File.Exists(configFile) == false) { // ignore it if file does't exist configFile = null; } } if (string.IsNullOrEmpty(configFile) == true) { // do we have a file specific in the registry? string configDirectory = Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), WinAuth.APPLICATION_NAME); Directory.CreateDirectory(configDirectory); // check the old 1.3 file name configFile = Path.Combine(configDirectory, CONFIG_FILE_NAME_1_3); if (File.Exists(configFile) == false) { // check for default authenticator configFile = Path.Combine(configDirectory, DEFAULT_AUTHENTICATOR_FILE_NAME); } // if no config file, just return a blank config if (File.Exists(configFile) == false) { return config; } } // if no config file when one was specified; report an error if (File.Exists(configFile) == false) { MessageBox.Show(form, "Unable to find your configuration file \"" + configFile + "\"", form.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); return config; } DialogResult configloaded; do { configloaded = DialogResult.OK; try { XmlDocument doc = null; XmlNode node = null; try { doc = new XmlDocument(); doc.Load(configFile); // check and load older versions node = doc.SelectSingleNode("WinAuth"); } catch (XmlException ) { // cause by invalid format, so we try and load other type of authenticator } if (node == null) { // foreign file so we import (authenticator.xml from winauth_1.3, android BMA xml or Java rs) Authenticator auth = LoadAuthenticator(form, configFile); if (auth != null) { config.Authenticator = auth; } SetLastFile(configFile); // set this as the new last opened file return config; } // Show if BETA //if (new BetaForm().ShowDialog(form) != DialogResult.OK) //{ // return null; //} XmlAttribute versionAttr; decimal version = Authenticator.DEAFULT_CONFIG_VERSION; if ((versionAttr = node.Attributes["version"]) != null && (version = decimal.Parse(versionAttr.InnerText, System.Globalization.CultureInfo.InvariantCulture)) < (decimal)1.4) { // old version 1.3 file config = LoadConfig_1_3(form, configFile); if (string.IsNullOrEmpty(config.Filename) == true) { config.Filename = configFile; } else if (string.Compare(configFile, config.Filename, true) != 0) { // switch over from winauth.xml to authenticator.xml and remove old winauth.xml File.Delete(configFile); configFile = config.Filename; } SaveAuthenticator(form, configFile, config); SetLastFile(configFile); // set this as the new last opened file return config; } // set the filename as itself config.Filename = configFile; bool boolVal = false; node = doc.DocumentElement.SelectSingleNode("alwaysontop"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.AlwaysOnTop = boolVal; } node = doc.DocumentElement.SelectSingleNode("usetrayicon"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.UseTrayIcon = boolVal; } node = doc.DocumentElement.SelectSingleNode("startwithwindows"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.StartWithWindows = boolVal; } node = doc.DocumentElement.SelectSingleNode("autorefresh"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.AutoRefresh = boolVal; } node = doc.DocumentElement.SelectSingleNode("allowcopy"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.AllowCopy = boolVal; } node = doc.DocumentElement.SelectSingleNode("copyoncode"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.CopyOnCode = boolVal; } node = doc.DocumentElement.SelectSingleNode("hideserial"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.HideSerial = boolVal; } // load the authenticator(s) - may have multiple authenticators in future version XmlNodeList nodes = doc.DocumentElement.SelectNodes("authenticator"); if (nodes != null) { // get the local machine time diff long machineTimeDiff = GetMachineTimeDiff(); foreach (XmlNode authenticatorNode in nodes) { // load the data Authenticator auth = null; try { try { auth = new Authenticator(); auth.Load(authenticatorNode, password, version); config.Authenticator = auth; } catch (EncrpytedSecretDataException) { PasswordForm passwordForm = new PasswordForm(); int retries = 0; do { passwordForm.Password = string.Empty; DialogResult result = passwordForm.ShowDialog(form); if (result != System.Windows.Forms.DialogResult.OK) { break; } try { auth = new Authenticator(); auth.Load(authenticatorNode, passwordForm.Password, version); config.Authenticator = auth; break; } catch (BadPasswordException) { MessageBox.Show(form, "Invalid password", "Load Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); if (retries++ >= MAX_PASSWORD_RETRIES - 1) { break; } } } while (true); } // adjust the time diff from the local machine if (auth != null && machineTimeDiff != 0) { auth.ServerTimeDiff = machineTimeDiff; } } catch (InvalidUserDecryptionException) { MessageBox.Show(form, "The authenticator was encrypted using a different Windows User account.", "Load Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (InvalidMachineDecryptionException) { MessageBox.Show(form, "The authenticator was encrypted using a different Windows computer.", "Load Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (InvalidConfigDataException) { MessageBox.Show(form, "The authenticator data in " + configFile + " is not valid", "Load Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); } catch (Exception ex) { MessageBox.Show(form, "Unable to load authenticator from " + configFile + ": " + ex.Message, "Load Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } // get the autologin node after we have gotten the pasword node = doc.DocumentElement.SelectSingleNode("autologin"); if (node != null && node.InnerText.Length != 0 && config.Authenticator != null) { config.AutoLogin = new HoyKeySequence(node, config.Authenticator.Password, version); } } catch (Exception ex) { configloaded = MessageBox.Show(form, "An error occured while loading your configuration file \"" + configFile + "\": " + ex.Message + "\n\nIt may be corrupted or in use by another application.", form.Text, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error); if (configloaded == DialogResult.Abort) { return null; } } } while (configloaded == DialogResult.Retry); SetLastFile(configFile); // set this as the new last opened file return config; }
/// <summary> /// Load the application configuration data for a 1.3 version /// </summary> /// <param name="form">parent winform</param> /// <param name="configFile">name of configuration file</param> /// <returns>new WinAuthConfig</returns> private static WinAuthConfig LoadConfig_1_3(MainForm form, string configFile) { WinAuthConfig config = new WinAuthConfig(); if (File.Exists(configFile) == false) { return config; } XmlDocument doc = new XmlDocument(); doc.Load(configFile); bool boolVal = false; // load the system config XmlNode node = doc.DocumentElement.SelectSingleNode("AlwaysOnTop"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.AlwaysOnTop = boolVal; } node = doc.DocumentElement.SelectSingleNode("UseTrayIcon"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.UseTrayIcon = boolVal; } node = doc.DocumentElement.SelectSingleNode("StartWithWindows"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.StartWithWindows = boolVal; } // load the authenticator config node = doc.DocumentElement.SelectSingleNode("AutoRefresh"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.AutoRefresh = boolVal; } node = doc.DocumentElement.SelectSingleNode("AllowCopy"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.AllowCopy = boolVal; } node = doc.DocumentElement.SelectSingleNode("CopyOnCode"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.CopyOnCode = boolVal; } node = doc.DocumentElement.SelectSingleNode("HideSerial"); if (node != null && bool.TryParse(node.InnerText, out boolVal) == true) { config.HideSerial = boolVal; } node = doc.DocumentElement.SelectSingleNode("AutoLogin"); if (node != null && node.InnerText.Length != 0) { config.AutoLogin = new HoyKeySequence(node.InnerText); } node = doc.DocumentElement.SelectSingleNode("AuthenticatorFile"); if (node != null && node.InnerText.Length != 0) { // load the authenticaotr.xml file string filename = node.InnerText; if (File.Exists(filename) == true) { Authenticator auth = LoadAuthenticator(form, filename); if (auth != null) { config.Authenticator = auth; } } config.Filename = filename; } return config; }
/// <summary> /// Send the keys to the expected window or current window if null /// </summary> /// <param name="keys">stirng to send</param> public void SendKeys(MainForm form, string keys, string code) { if (m_hWnd != IntPtr.Zero && m_hWnd != WinAPI.GetForegroundWindow()) { WinAPI.SetForegroundWindow(m_hWnd); System.Threading.Thread.Sleep(200); } // wait until the control key has been lifted while (WinAPI.GetKeyState((UInt16)WinAPI.VirtualKeyCode.VK_CONTROL) < 0) { System.Threading.Thread.Sleep(200); } // replace any {CODE} items keys = Regex.Replace(keys, @"\{\s*CODE\s*\}", code, RegexOptions.Singleline); // clear events and stop input Application.DoEvents(); bool blocked = WinAPI.BlockInput(true); try { // for now just split into parts and run each foreach (Match match in Regex.Matches(keys, @"\{.*?\}|[^\{]*", RegexOptions.Singleline)) { // split into either {CMD d w} or just plain text if (match.Success == true) { string single = match.Value; if (single.Length == 0) { continue; } if (single[0] == '{') { // send command {COMMAND delay repeat} Match cmdMatch = Regex.Match(single.Trim(), @"\{([^\s]+)\s*(\d*)\s*(\d*)\}"); if (cmdMatch.Success == true) { // extract the command and any optional delay and repeat string cmd = cmdMatch.Groups[1].Value.ToUpper(); int delay = 0; if (cmdMatch.Groups[2].Success == true && cmdMatch.Groups[2].Value.Length != 0) { int.TryParse(cmdMatch.Groups[2].Value, out delay); } int repeat = 1; if (cmdMatch.Groups[3].Success == true && cmdMatch.Groups[3].Value.Length != 0) { int.TryParse(cmdMatch.Groups[3].Value, out repeat); } // run the command switch (cmd) { case "TAB": SendKey('\t', delay, repeat); break; case "ENTER": SendKey('\n', delay, repeat); break; case "WAIT": for (; repeat > 0; repeat--) { System.Threading.Thread.Sleep(delay); } break; case "COPY": form.Invoke(new MainForm.SetClipboardDataDelegate(form.SetClipboardData), new object[] {code}); break; case "PASTE": string clipboard = form.Invoke(new MainForm.GetClipboardDataDelegate(form.GetClipboardData), new object[] { typeof(string) }) as string; if (string.IsNullOrEmpty(clipboard) == false) { foreach (char key in clipboard) { SendKey(key); } } break; case "EXIT": Application.Exit(); break; default: //Enum.Parse(typeof(WinAPI.VirtualKeyCode), "VK_" + cmd, true); //SendKey('\t', delay, repeat); break; } } } else { // plain text - send verbatim //foreach (char key in single) //{ // SendKey(key); //} SendKey(single); } } } } finally { // resume input if (blocked == true) { WinAPI.BlockInput(false); } Application.DoEvents(); } }