/// <summary>
        /// Perform a verification of the restore code in the background by checking it with the servers
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void VerifyRestoreCode(object sender, DoWorkEventArgs e)
        {
            Authenticator auth = e.Argument as Authenticator;

            // check if this authenticator is too old to be restored
            try
            {
                Authenticator testrestore = new Authenticator();
                testrestore.Restore(auth.Serial, auth.RestoreCode);
                auth.RestoreCodeVerified = true;
                e.Result = null;
            }
            catch (InvalidRestoreCodeException)
            {
                e.Result = "This authenticator was created before the restore capability existed and so the restore code will not work.\n\n"
                        + "You will need to remove this authenticator from your Battle.net account and create a new one.";
            }
            catch (InvalidRestoreResponseException)
            {
                // ignore the validation if servers are down
            }
            catch (Exception ex2)
            {
                e.Result = "Oops. An error (" + ex2.Message + ") occured whilst validating your restore code."
                        + "Please log a ticket at http://code.google.com/p/winauth so we can fix this.";
            }
        }
        /// <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>
        /// Import and authenticator file of different formats
        /// </summary>
        /// <param name="configFile">filename to load</param>
        /// <param name="password">optional password</param>
        /// <returns>new Authenticator</returns>
        public static Authenticator ImportAuthenticator(string configFile, string password)
        {
            using (FileStream fs = new FileStream(configFile, FileMode.Open))
            {
                Authenticator auth = new Authenticator();

                // read the file
                string ext = Path.GetExtension(configFile).ToLower();
                if (ext == ".xml")
                {
                    // load ours or the Android XML file
                    auth.Load(fs, Authenticator.FileFormat.WinAuth, password);
                }
                else
                {
                    // load the Java MIDP recordfile
                    auth.Load(fs, Authenticator.FileFormat.Midp, password);
                }
                return auth;
            }
        }
        /// <summary>
        /// Write data into the XmlWriter
        /// </summary>
        /// <param name="writer">XmlWriter to write to</param>
        public void WriteXmlString(XmlWriter writer, Authenticator.PasswordTypes passwordType, string password)
        {
            writer.WriteStartElement("autologin");

            writer.WriteStartElement("modifiers");
            writer.WriteString(Authenticator.ByteArrayToString(BitConverter.GetBytes((int)Modifiers)));
            writer.WriteEndElement();
            //
            writer.WriteStartElement("hotkey");
            writer.WriteString(Authenticator.ByteArrayToString(BitConverter.GetBytes((ushort)HotKey)));
            writer.WriteEndElement();
            //
            writer.WriteStartElement("windowtitle");
            writer.WriteCData(WindowTitle ?? string.Empty);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("processname");
            writer.WriteCData(ProcessName ?? string.Empty);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("windowtitleregex");
            writer.WriteValue(WindowTitleRegex);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("advanced");
            writer.WriteValue(Advanced);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("script");
            string script = AdvancedScript.Replace("\n", string.Empty);

            StringBuilder passwordTypeAttribue = new StringBuilder();
            if ((passwordType & Authenticator.PasswordTypes.Explicit) != 0)
            {
                byte[] plain = Encoding.UTF8.GetBytes(script);
                script = Authenticator.ByteArrayToString(plain);
                script = Authenticator.Encrypt(script, password);
                passwordTypeAttribue.Append("y");
            }
            if ((passwordType & Authenticator.PasswordTypes.User) != 0)
            {
                byte[] plain = Encoding.UTF8.GetBytes(script);
                byte[] cipher = ProtectedData.Protect(plain, null, DataProtectionScope.CurrentUser);
                script = Authenticator.ByteArrayToString(cipher);
                passwordTypeAttribue.Append("u");
            }
            if ((passwordType & Authenticator.PasswordTypes.Machine) != 0)
            {
                // we encrypt the data using the Local Machine account key
                byte[] plain = Encoding.UTF8.GetBytes(script);
                byte[] cipher = ProtectedData.Protect(plain, null, DataProtectionScope.LocalMachine);
                script = Authenticator.ByteArrayToString(cipher);
                passwordTypeAttribue.Append("m");
            }
            writer.WriteAttributeString("encrypted", passwordTypeAttribue.ToString());
            writer.WriteCData(script);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
Beispiel #5
0
        /// <summary>
        /// Enroll a new Authenticator
        /// </summary>
        /// <returns></returns>
        private bool Enroll()
        {
            // already have one?
            if (Authenticator != null)
            {
                DialogResult warning = MessageBox.Show(this, "WARNING: You already have an authenticator registered.\n\n"
                    + "You will NOT be able to access your Battle.net account if you continue and this authenticator is overwritten.\n\n"
                    + "Do you still want to create a new authenticator?", "New  Authenticator", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
                if (warning != System.Windows.Forms.DialogResult.Yes)
                {
                    return false;
                }
            }

            // initialise the new authenticator
            Authenticator authenticator = null;
            try
            {
                // get the current country code
                string region = (RegionInfo.CurrentRegion != null ? RegionInfo.CurrentRegion.TwoLetterISORegionName : null);
                EnrollForm enrollform = new EnrollForm();
                enrollform.CurrentRegion = region;
                if (enrollform.ShowDialog(this) != System.Windows.Forms.DialogResult.OK)
                {
                    return false;
                }
                region = enrollform.CurrentRegion;

                // create and enroll a new authenticator
                authenticator = new Authenticator();
                authenticator.Enroll(region);
            }
            catch (Exception ex)
            {
                MessageBox.Show(this,
                    "There was an error registering your authenticator:\n\n" + ex.Message + "\n\nThis may be because the Battle.net servers are unavailable. Please try again later.",
                    "New Authenticator", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            // prompt now done
            if (MessageBox.Show(this,
                "Your authenticator has been created and registered.\n\n"
                + "You will now be prompted to save it to a file on your computer before you can add it to your account.\n\n"
                + "1. Choose a file to save your new authenticator.\n"
                + "2. Select the encrpytion option.\n"
                + "3. Add your authenticator to your Battle.net account.\n\n"
                + "Click \"OK\" to save your authenticator.",
                "New Registered Authenticator", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) != DialogResult.OK)
            {
                return false;
            }

            // remember old config
            WinAuthConfig oldconfig = Config;
            // set the new authenticator
            Config = Config.Clone() as WinAuthConfig;
            Config.Authenticator = authenticator;
            Config.AutoLogin = null; // clear autologin
            // save config data
            if (SaveAuthenticator(null) == false)
            {
                // restore authenticator
                Config = oldconfig;
                return false;
            }

            // refresh this machine time diff based on this new authenticator
            WinAuthHelper.SetMachineTimeDiff(authenticator.ServerTimeDiff);

            // unhook and rehook hotkey
            HookHotkey(this.Config);

            // set filename and window title
            notifyIcon.Text = this.Text = WinAuth.APPLICATION_TITLE + " - " + Path.GetFileNameWithoutExtension(Config.Filename);

            // prompt to backup
            InitializedForm initForm = new InitializedForm();
            initForm.Authenticator = Config.Authenticator;
            if (initForm.ShowDialog(this) == System.Windows.Forms.DialogResult.Yes)
            {
                BackupData();
            }

            // show the new code
            ShowCode();

            return true;
        }
Beispiel #6
0
        /// <summary>
        /// Click the OK button to restore the authenticator
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOk_Click_1(object sender, EventArgs e)
        {
            string serial = (serial1Field.Text + serial2Field.Text + serial3Field.Text + serial4Field.Text).Trim().ToUpper();
            if (serial.Length != 14)
            {
                MessageBox.Show(this, "Invalid serial number.\n\n - must be something like US-1234-1234-1234.", WinAuth.APPLICATION_NAME, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            string restorecode = restoreCodeField.Text.Trim().ToUpper();
            if (restorecode.Length != 10)
            {
                MessageBox.Show(this, "Invalid restore code.\n\n - must contain 10 letters and numbers.", WinAuth.APPLICATION_NAME, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            // restore the authenticator
            try
            {
                Authenticator auth = new Authenticator();
                auth.Restore(serial, restorecode);
                this.Authenticator = auth;

                MessageBox.Show(this, "Your authenticator has been restored.\n\nYou will now be prompted where to save your new authenticator and choose your encryption level.", WinAuth.APPLICATION_NAME, MessageBoxButtons.OK, MessageBoxIcon.Information);

                // ok to continue
                DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            catch (InvalidRestoreResponseException re)
            {
                MessageBox.Show(this, re.Message, WinAuth.APPLICATION_NAME, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }
        }