Ejemplo n.º 1
0
        protected bool ReadXmlInternal(XmlReader reader, string password = null)
        {
            bool changed = false;

            decimal version;

            if (decimal.TryParse(reader.GetAttribute("version"), System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out version) == true)
            {
                Version = version;

                if (version > WinAuthConfig.CURRENTVERSION)
                {
                    // ensure we don't overwrite a newer config
                    throw new WinAuthInvalidNewerConfigException(string.Format(strings.ConfigIsNewer, version));
                }
            }

            string encrypted = reader.GetAttribute("encrypted");

            this.PasswordType = Authenticator.DecodePasswordTypes(encrypted);
            if (this.PasswordType != Authenticator.PasswordTypes.None)
            {
                // read the encrypted text from the node
                string data = reader.ReadElementContentAsString();
                // decrypt
                YubiKey yubi = null;
                if ((this.PasswordType & (Authenticator.PasswordTypes.YubiKeySlot1 | Authenticator.PasswordTypes.YubiKeySlot2)) != 0 /* && this.Yubi == null */)
                {
                    yubi = YubiKey.CreateInstance();
                }
                data = Authenticator.DecryptSequence(data, this.PasswordType, password, yubi);

                using (MemoryStream ms = new MemoryStream(Authenticator.StringToByteArray(data)))
                {
                    reader  = XmlReader.Create(ms);
                    changed = ReadXml(reader, password);
                }

                this.PasswordType = Authenticator.DecodePasswordTypes(encrypted);
                this.Password     = password;
                this.Yubi         = yubi;

                return(changed);
            }

            reader.MoveToContent();
            if (reader.IsEmptyElement)
            {
                reader.Read();
                return(changed);
            }

            bool   defaultAutoRefresh = true;
            bool   defaultAllowCopy   = false;
            bool   defaultCopyOnCode  = false;
            bool   defaultHideSerial  = true;
            string defaultSkin        = null;

            reader.Read();
            while (reader.EOF == false)
            {
                if (reader.IsStartElement())
                {
                    switch (reader.Name)
                    {
                    case "config":
                        changed = ReadXmlInternal(reader, password) || changed;
                        break;

                    // 3.2 has new layout
                    case "data":
                    {
                        encrypted         = reader.GetAttribute("encrypted");
                        this.PasswordType = Authenticator.DecodePasswordTypes(encrypted);
                        if (this.PasswordType != Authenticator.PasswordTypes.None)
                        {
                            HashAlgorithm hasher;
                            string        hash = reader.GetAttribute("sha1");
                            if (string.IsNullOrEmpty(hash) == false)
                            {
                                hasher = Authenticator.SafeHasher("SHA1");
                            }
                            else
                            {
                                // old version has md5
                                hash   = reader.GetAttribute("md5");
                                hasher = Authenticator.SafeHasher("MD5");
                            }
                            // read the encrypted text from the node
                            string data = reader.ReadElementContentAsString();

                            hasher.ComputeHash(Authenticator.StringToByteArray(data));
                            hasher.Dispose();

                            // decrypt
                            YubiKey yubi = null;
                            if ((this.PasswordType & (Authenticator.PasswordTypes.YubiKeySlot1 | Authenticator.PasswordTypes.YubiKeySlot2)) != 0 /* && this.Yubi == null */)
                            {
                                yubi = YubiKey.CreateInstance();
                            }
                            data = Authenticator.DecryptSequence(data, this.PasswordType, password, yubi);
                            byte[] plain = Authenticator.StringToByteArray(data);

                            using (MemoryStream ms = new MemoryStream(plain))
                            {
                                var datareader = XmlReader.Create(ms);
                                changed = ReadXmlInternal(datareader, password) || changed;
                            }

                            this.PasswordType = Authenticator.DecodePasswordTypes(encrypted);
                            this.Password     = password;
                            this.Yubi         = yubi;
                        }
                    }
                    break;

                    case "alwaysontop":
                        _alwaysOnTop = reader.ReadElementContentAsBoolean();
                        break;

                    case "usetrayicon":
                        _useTrayIcon = reader.ReadElementContentAsBoolean();
                        break;

                    case "notifyaction":
                        string s = reader.ReadElementContentAsString();
                        if (string.IsNullOrEmpty(s) == false)
                        {
                            try {
                                _notifyAction = (NotifyActions)Enum.Parse(typeof(NotifyActions), s, true);
                            }
                            catch (Exception) { }
                        }
                        break;

                    case "startwithwindows":
                        _startWithWindows = reader.ReadElementContentAsBoolean();
                        break;

                    case "autosize":
                        _autoSize = reader.ReadElementContentAsBoolean();
                        break;

                    case "left":
                        _position.X = reader.ReadElementContentAsInt();
                        break;

                    case "top":
                        _position.Y = reader.ReadElementContentAsInt();
                        break;

                    case "width":
                        _width = reader.ReadElementContentAsInt();
                        break;

                    case "height":
                        _height = reader.ReadElementContentAsInt();
                        break;

                    case "shadowtype":
                        _shadowType = reader.ReadElementContentAsString();
                        break;

                    case "pgpkey":
                        _pgpKey = reader.ReadElementContentAsString();
                        break;

                    case "settings":
                        XmlSerializer serializer = new XmlSerializer(typeof(setting[]), new XmlRootAttribute()
                        {
                            ElementName = "settings"
                        });
                        _settings = ((setting[])serializer.Deserialize(reader)).ToDictionary(e => e.Key, e => e.Value);
                        break;

                    // previous setting used as defaults for new
                    case "autorefresh":
                        defaultAutoRefresh = reader.ReadElementContentAsBoolean();
                        break;

                    case "allowcopy":
                        defaultAllowCopy = reader.ReadElementContentAsBoolean();
                        break;

                    case "copyoncode":
                        defaultCopyOnCode = reader.ReadElementContentAsBoolean();
                        break;

                    case "hideserial":
                        defaultHideSerial = reader.ReadElementContentAsBoolean();
                        break;

                    case "skin":
                        defaultSkin = reader.ReadElementContentAsString();
                        break;

                    case "WinAuthAuthenticator":
                        var wa = new WinAuthAuthenticator();
                        changed = wa.ReadXml(reader, password) || changed;
                        this.Add(wa);
                        if (this.CurrentAuthenticator == null)
                        {
                            this.CurrentAuthenticator = wa;
                        }
                        break;

                    // for old 2.x configs
                    case "authenticator":
                        var waold = new WinAuthAuthenticator();
                        waold.AuthenticatorData = Authenticator.ReadXmlv2(reader, password);
                        if (waold.AuthenticatorData is BattleNetAuthenticator)
                        {
                            waold.Name = "Battle.net";
                        }
                        else if (waold.AuthenticatorData is GuildWarsAuthenticator)
                        {
                            waold.Name = "GuildWars 2";
                        }
                        else if (waold.AuthenticatorData is GuildWarsAuthenticator)
                        {
                            waold.Name = "Authenticator";
                        }
                        this.Add(waold);
                        this.CurrentAuthenticator = waold;
                        waold.AutoRefresh         = defaultAutoRefresh;
                        waold.AllowCopy           = defaultAllowCopy;
                        waold.CopyOnCode          = defaultCopyOnCode;
                        waold.HideSerial          = defaultHideSerial;
                        break;

                    // old 2.x auto login script
                    case "autologin":
                        var hks = new HoyKeySequence();
                        hks.ReadXml(reader, password);
                        if (hks.HotKey != 0)
                        {
                            if (this.CurrentAuthenticator.HotKey == null)
                            {
                                this.CurrentAuthenticator.HotKey = new HotKey();
                            }
                            HotKey hotkey = this.CurrentAuthenticator.HotKey;
                            hotkey.Action    = HotKey.HotKeyActions.Inject;
                            hotkey.Key       = hks.HotKey;
                            hotkey.Modifiers = hks.Modifiers;
                            if (hks.WindowTitleRegex == true && string.IsNullOrEmpty(hks.WindowTitle) == false)
                            {
                                hotkey.Window = "/" + Regex.Escape(hks.WindowTitle);
                            }
                            else if (string.IsNullOrEmpty(hks.WindowTitle) == false)
                            {
                                hotkey.Window = hks.WindowTitle;
                            }
                            else if (string.IsNullOrEmpty(hks.ProcessName) == false)
                            {
                                hotkey.Window = hks.ProcessName;
                            }
                            if (hks.Advanced == true)
                            {
                                hotkey.Action   = HotKey.HotKeyActions.Advanced;
                                hotkey.Advanced = hks.AdvancedScript;
                            }
                        }
                        break;

                    default:
                        reader.Skip();
                        break;
                    }
                }
                else
                {
                    reader.Read();
                    break;
                }
            }

            return(changed);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Write the data as xml into an XmlWriter
        /// </summary>
        /// <param name="writer">XmlWriter to write config</param>
        public void WriteXmlString(XmlWriter writer, bool includeFilename = false, bool includeSettings = true)
        {
            writer.WriteStartDocument(true);
            //
            if (includeFilename == true && string.IsNullOrEmpty(this.Filename) == false)
            {
                writer.WriteComment(this.Filename);
            }
            //
            writer.WriteStartElement("WinAuth");
            writer.WriteAttributeString("version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(2));
            //
            writer.WriteStartElement("alwaysontop");
            writer.WriteValue(this.AlwaysOnTop);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("usetrayicon");
            writer.WriteValue(this.UseTrayIcon);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("notifyaction");
            writer.WriteValue(Enum.GetName(typeof(NotifyActions), this.NotifyAction));
            writer.WriteEndElement();
            //
            writer.WriteStartElement("startwithwindows");
            writer.WriteValue(this.StartWithWindows);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("autosize");
            writer.WriteValue(this.AutoSize);
            writer.WriteEndElement();
            //
            if (this.Position.IsEmpty == false)
            {
                writer.WriteStartElement("left");
                writer.WriteValue(this.Position.X);
                writer.WriteEndElement();
                writer.WriteStartElement("top");
                writer.WriteValue(this.Position.Y);
                writer.WriteEndElement();
            }
            //
            writer.WriteStartElement("width");
            writer.WriteValue(this.Width);
            writer.WriteEndElement();
            //
            writer.WriteStartElement("height");
            writer.WriteValue(this.Height);
            writer.WriteEndElement();
            //
            if (string.IsNullOrEmpty(this.ShadowType) == false)
            {
                writer.WriteStartElement("shadowtype");
                writer.WriteValue(this.ShadowType);
                writer.WriteEndElement();
            }
            //
            if (string.IsNullOrEmpty(this.PGPKey) == false)
            {
                writer.WriteStartElement("pgpkey");
                writer.WriteCData(this.PGPKey);
                writer.WriteEndElement();
            }

            if (PasswordType != Authenticator.PasswordTypes.None)
            {
                writer.WriteStartElement("data");

                StringBuilder encryptedTypes = new StringBuilder();
                if ((PasswordType & Authenticator.PasswordTypes.Explicit) != 0)
                {
                    encryptedTypes.Append("y");
                }
                if ((PasswordType & Authenticator.PasswordTypes.User) != 0)
                {
                    encryptedTypes.Append("u");
                }
                if ((PasswordType & Authenticator.PasswordTypes.Machine) != 0)
                {
                    encryptedTypes.Append("m");
                }
                if ((PasswordType & Authenticator.PasswordTypes.YubiKeySlot1) != 0)
                {
                    encryptedTypes.Append("a");
                }
                if ((PasswordType & Authenticator.PasswordTypes.YubiKeySlot2) != 0)
                {
                    encryptedTypes.Append("b");
                }
                writer.WriteAttributeString("encrypted", encryptedTypes.ToString());

                byte[] data;
                using (MemoryStream ms = new MemoryStream())
                {
                    XmlWriterSettings settings = new XmlWriterSettings();
                    settings.Indent   = true;
                    settings.Encoding = Encoding.UTF8;
                    using (XmlWriter encryptedwriter = XmlWriter.Create(ms, settings))
                    {
                        encryptedwriter.WriteStartElement("config");
                        foreach (WinAuthAuthenticator wa in this)
                        {
                            wa.WriteXmlString(encryptedwriter);
                        }
                        encryptedwriter.WriteEndElement();
                    }

                    data = ms.ToArray();
                }

                using (var hasher = Authenticator.SafeHasher("SHA1"))
                {
                    string encdata = Authenticator.EncryptSequence(Authenticator.ByteArrayToString(data), PasswordType, Password, this.Yubi);
                    string enchash = Authenticator.ByteArrayToString(hasher.ComputeHash(Authenticator.StringToByteArray(encdata)));
                    writer.WriteAttributeString("sha1", enchash);
                    writer.WriteString(encdata);
                }

                writer.WriteEndElement();
            }
            else
            {
                foreach (WinAuthAuthenticator wa in this)
                {
                    wa.WriteXmlString(writer);
                }
            }

            if (includeSettings == true && _settings.Count != 0)
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add(string.Empty, string.Empty);
                XmlSerializer serializer = new XmlSerializer(typeof(setting[]), new XmlRootAttribute()
                {
                    ElementName = "settings"
                });
                serializer.Serialize(writer, _settings.Select(e => new setting {
                    Key = e.Key, Value = e.Value
                }).ToArray(), ns);
            }

            // close WinAuth
            writer.WriteEndElement();

            // end document
            writer.WriteEndDocument();
        }