예제 #1
0
        public override void MigrateToKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = -1;
            if (!m_bInitialized)
            {
                return;
            }
            EntriesOverall = EntriesMigrated = 0;

            List <PwEntry> lEntries = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists("TOTP Seed")).ToList();

            EntriesOverall = lEntries.Count;
            if (lEntries.Count == 0)
            {
                return;
            }

            if (!OTPDAO.EnsureOTPSetupPossible(lEntries[0]))
            {
                return;
            }
            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries[0]);
            InitLogger("KeeTrayTOTP -> KeePassOTP", lEntries.Count);
            try
            {
                foreach (PwEntry pe in lEntries)
                {
                    IncreaseLogger();
                    string seed     = pe.Strings.ReadSafe("TOTP Seed");
                    string settings = pe.Strings.ReadSafe("TOTP Settings");
                    if (string.IsNullOrEmpty(settings))
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: not defined");
                        continue;
                    }
                    var parameters = settings.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parameters.Count() < 2)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: " + settings);
                        continue;
                    }
                    var otp = OTPDAO.GetOTP(pe);
                    otp.OTPSeed      = new ProtectedString(true, MigrateString(seed));
                    otp.TOTPTimestep = MigrateInt(parameters[0], 30);
                    int l = MigrateInt(parameters[1], -1);
                    if (l == -1)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: " + settings);
                        continue;
                    }
                    otp.Length = l;
                    if ((parameters.Count() > 2) && !string.IsNullOrEmpty(parameters[2]))
                    {
                        otp.TimeCorrectionUrl = parameters[2];
                    }
                    if (otp.Valid)
                    {
                        EntriesMigrated++;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                        if (bRemove)
                        {
                            pe.Strings.Remove("TOTP Seed");
                            pe.Strings.Remove("TOTP Settings");
                        }
                    }
                    else
                    {
                        string s = string.Empty;
                        for (int i = 0; i < parameters.Count(); i++)
                        {
                            if (parameters[i].ToLowerInvariant().StartsWith("key="))
                            {
                                s += "key=<secret>";
                            }
                            else
                            {
                                s += parameters[i];
                            }
                            if (i < parameters.Count() - 1)
                            {
                                s += "&";
                            }
                        }
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: " + s);
                    }
                }
            }
            finally
            {
                EndLogger();
            }
            MigratePlaceholder(OtherPluginPlaceholder, Config.Placeholder, false);
        }
예제 #2
0
        public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = -1;
            if (!m_bInitialized)
            {
                return;
            }
            EntriesOverall = EntriesMigrated = 0;

            OTPDAO.OTPHandler_DB h = OTPDAO.GetOTPHandler(m_db);
            if ((h != null) && !h.EnsureOTPUsagePossible(null))
            {
                return;
            }

            PwObjectList <PwEntry> lEntries = m_db.RootGroup.GetEntries(true);

            if (lEntries.Count() == 0)
            {
                return;
            }

            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries.GetAt(0));
            InitLogger("KeePassOTP -> KeeTrayTOTP", lEntries.Count());
            try
            {
                foreach (PwEntry pe in lEntries)
                {
                    IncreaseLogger();
                    KPOTP otp = OTPDAO.GetOTP(pe);
                    if (!otp.Valid)
                    {
                        continue;
                    }
                    EntriesOverall++;
                    if (otp.Encoding != KPOTPEncoding.BASE32)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Encoding not supported: " + otp.Encoding.ToString());
                        continue;
                    }
                    if (otp.Hash != KPOTPHash.SHA1)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Hash not supported: " + otp.Hash.ToString());
                        continue;
                    }
                    if (otp.Type != KPOTPType.TOTP)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Type not supported: " + otp.Type.ToString());
                        continue;
                    }
                    string settings = otp.TOTPTimestep.ToString() + ";" + otp.Length.ToString();
                    if (otp.TimeCorrectionUrlOwn)
                    {
                        settings += ";" + pe.Strings.ReadSafe(PwDefs.UrlField);
                    }
                    else if (!string.IsNullOrEmpty(otp.TimeCorrectionUrl))
                    {
                        settings += ";" + otp.TimeCorrectionUrl;
                    }
                    pe.Strings.Set("TOTP Seed", otp.OTPSeed);
                    pe.Strings.Set("TOTP Settings", new ProtectedString(false, settings));
                    EntriesMigrated++;
                    if (bRemove)
                    {
                        otp.OTPSeed = ProtectedString.EmptyEx;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                    }
                }
            }
            finally { EndLogger(); }
            MigratePlaceholder(Config.Placeholder, OtherPluginPlaceholder, false);
        }
예제 #3
0
        public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = -1;
            if (!m_bInitialized)
            {
                return;
            }
            EntriesOverall = EntriesMigrated = 0;

            OTPDAO.OTPHandler_DB h = OTPDAO.GetOTPHandler(m_db);
            if ((h != null) && !h.EnsureOTPUsagePossible(null))
            {
                return;
            }

            PwObjectList <PwEntry> lEntries = m_db.RootGroup.GetEntries(true);

            if (lEntries.Count() == 0)
            {
                return;
            }

            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries.GetAt(0));
            InitLogger("KeePassOTP -> KeeOTP", lEntries.Count());
            try
            {
                foreach (PwEntry pe in lEntries)
                {
                    IncreaseLogger();
                    KPOTP otp = OTPDAO.GetOTP(pe);
                    if (!otp.Valid)
                    {
                        continue;
                    }
                    EntriesOverall++;
                    if (otp.Encoding != KPOTPEncoding.BASE32)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Encoding not supported: " + otp.Encoding.ToString());
                        continue;
                    }
                    if (otp.Hash != KPOTPHash.SHA1)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Hash not supported: " + otp.Hash.ToString());
                        continue;
                    }
                    if (otp.Type != KPOTPType.TOTP)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Type not supported: " + otp.Type.ToString());
                        continue;
                    }

                    string s = "key=" + otp.OTPSeed.ReadString();
                    if (otp.Length != 6)
                    {
                        s += "&size=" + otp.Length.ToString();
                    }
                    if (otp.Type == KPOTPType.HOTP)
                    {
                        s += "&type=hotp";
                        if (otp.HOTPCounter > 0)
                        {
                            s += "&counter=" + otp.HOTPCounter.ToString();
                        }
                    }
                    if ((otp.Type == KPOTPType.TOTP) && (otp.TOTPTimestep != 30))
                    {
                        s += "&step=" + otp.TOTPTimestep.ToString();
                    }
                    pe.Strings.Set("otp", new ProtectedString(true, s));
                    if (pe.Strings.Exists("otp"))
                    {
                        EntriesMigrated++;
                    }
                    if (bRemove)
                    {
                        otp.OTPSeed = ProtectedString.EmptyEx;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                    }
                }
            }
            finally
            {
                EndLogger();
            }
            MigratePlaceholder(Config.Placeholder, OtherPluginPlaceholder, false);
        }
예제 #4
0
        public override void MigrateToKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = -1;
            if (!m_bInitialized)
            {
                return;
            }
            EntriesOverall = EntriesMigrated = 0;

            List <PwEntry> lEntries = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists("otp")).ToList();

            EntriesOverall = lEntries.Count;
            if (lEntries.Count == 0)
            {
                return;
            }

            if (!OTPDAO.EnsureOTPSetupPossible(lEntries[0]))
            {
                return;
            }
            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries[0]);
            InitLogger("KeeOTP -> KeePassOTP", lEntries.Count);
            try
            {
                foreach (PwEntry pe in lEntries)
                {
                    IncreaseLogger();
                    string old = pe.Strings.ReadSafe("otp");
                    if (string.IsNullOrEmpty(old))
                    {
                        continue;
                    }
                    var parameters = old.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries);
                    var otp        = OTPDAO.GetOTP(pe);
                    foreach (var parameter in parameters)
                    {
                        var kvp = parameter.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                        if (kvp.Length != 2)
                        {
                            continue;
                        }
                        switch (kvp[0].ToLowerInvariant())
                        {
                        case "key":
                            otp.OTPSeed = new ProtectedString(true, MigrateString(kvp[1]));
                            break;

                        case "type":
                            otp.Type = kvp[1].ToLower() != "hotp" ? KPOTPType.TOTP : KPOTPType.HOTP;
                            break;

                        case "step":
                            otp.TOTPTimestep = MigrateInt(kvp[1], 30);
                            break;

                        case "counter":
                            otp.HOTPCounter = MigrateInt(kvp[1], 0);
                            break;

                        case "size":
                            otp.Length = MigrateInt(kvp[1], 6);
                            break;

                        default: break;
                        }
                    }
                    if (otp.Valid)
                    {
                        EntriesMigrated++;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                        pe.Touch(true);
                        //Only remove setting if we migrated to OTP-DB
                        //Do not remove if KeePassOTP stores OTP data within the entry
                        if (bRemove && Config.UseDBForOTPSeeds(pe.GetDB()))
                        {
                            pe.Strings.Remove("otp");
                        }
                    }
                    else
                    {
                        string s = string.Empty;
                        for (int i = 0; i < parameters.Count(); i++)
                        {
                            if (parameters[i].ToLowerInvariant().StartsWith("key="))
                            {
                                s += "key=<secret>";
                            }
                            else
                            {
                                s += parameters[i];
                            }
                            if (i < parameters.Count() - 1)
                            {
                                s += "&";
                            }
                        }
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: " + s);
                    }
                }
            }
            finally { EndLogger(); }
            MigratePlaceholder(OtherPluginPlaceholder, Config.Placeholder, false);
        }
예제 #5
0
        public override void MigrateFromKeePassOTP(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = -1;
            if (!m_bInitialized)
            {
                return;
            }
            EntriesOverall = EntriesMigrated = 0;

            OTPDAO.OTPHandler_DB h = OTPDAO.GetOTPHandler(m_db);
            if ((h != null) && !h.EnsureOTPUsagePossible(null))
            {
                return;
            }

            PwObjectList <PwEntry> lEntries = m_db.RootGroup.GetEntries(true);

            if (lEntries.Count() == 0)
            {
                return;
            }

            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries.GetAt(0));
            InitLogger("KeePassOTP -> KeeTrayTOTP", lEntries.Count());
            try
            {
                foreach (PwEntry pe in lEntries)
                {
                    IncreaseLogger();
                    KPOTP otp = OTPDAO.GetOTP(pe);
                    if (!otp.Valid)
                    {
                        continue;
                    }
                    EntriesOverall++;
                    if (otp.Type != KPOTPType.HOTP && otp.Type != KPOTPType.TOTP)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "Type not supported: " + otp.Type.ToString());
                        continue;
                    }

                    if (otp.Type == KPOTPType.TOTP)
                    {
                        if (Tools.KeePassVersion < m_vKeePass247)
                        {
                            PluginDebug.AddError("Migration of entry failed",
                                                 "Uuid: " + pe.Uuid.ToHexString(),
                                                 "Type not supported: " + otp.Type.ToString(),
                                                 "Minimum required KeePass version: " + m_vKeePass247.ToString());
                        }
                        foreach (var line in m_dTotpStrings)
                        {
                            if (line.Key == otp.Encoding)
                            {
                                pe.Strings.Set(line.Value, otp.OTPSeed);
                            }
                            else
                            {
                                pe.Strings.Remove(line.Value);
                            }
                        }

                        if (otp.TOTPTimestep == 30)
                        {
                            pe.Strings.Remove(TOTPPERIOD);
                        }
                        else
                        {
                            pe.Strings.Set(TOTPPERIOD, new ProtectedString(false, otp.TOTPTimestep.ToString()));
                        }

                        if (otp.Length == 6)
                        {
                            pe.Strings.Remove(TOTPLENGTH);
                        }
                        else
                        {
                            pe.Strings.Set(TOTPLENGTH, new ProtectedString(false, otp.Length.ToString()));
                        }

                        if (otp.Hash == KPOTPHash.SHA1)
                        {
                            pe.Strings.Remove(TOTPHASH);
                        }
                        else if (otp.Hash == KPOTPHash.SHA256)
                        {
                            pe.Strings.Set(TOTPHASH, new ProtectedString(false, "HMAC-SHA-256"));
                        }
                        else if (otp.Hash == KPOTPHash.SHA512)
                        {
                            pe.Strings.Set(TOTPHASH, new ProtectedString(false, "HMAC-SHA-512"));
                        }

                        bool bDummy;
                        MigratePlaceholder(Config.Placeholder, PLACEHOLDER_TOTP, pe, out bDummy);
                    }
                    else if (otp.Type == KPOTPType.HOTP)
                    {
                        if (otp.Length != 6)
                        {
                            PluginDebug.AddError("Migration of entry failed",
                                                 "Uuid: " + pe.Uuid.ToHexString(),
                                                 "Length not supported: " + otp.Length.ToString());
                            continue;
                        }
                        if (otp.Hash != KPOTPHash.SHA1)
                        {
                            PluginDebug.AddError("Migration of entry failed",
                                                 "Uuid: " + pe.Uuid.ToHexString(),
                                                 "Hash not supported: " + otp.Hash.ToString());
                            continue;
                        }

                        foreach (var line in m_dHotpStrings)
                        {
                            if (line.Key == otp.Encoding)
                            {
                                pe.Strings.Set(line.Value, otp.OTPSeed);
                            }
                            else
                            {
                                pe.Strings.Remove(line.Value);
                            }
                        }
                        pe.Strings.Set(HOTP_COUNTER, new ProtectedString(false, otp.HOTPCounter.ToString()));

                        bool bDummy;
                        MigratePlaceholder(Config.Placeholder, PLACEHOLDER_HOTP, pe, out bDummy);
                    }

                    EntriesMigrated++;
                    if (bRemove)
                    {
                        otp.OTPSeed = ProtectedString.EmptyEx;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                    }
                }
            }
            finally { EndLogger(); }
            MigratePlaceholder(Config.Placeholder, PLACEHOLDER_TOTP);             //In case something is defined on group level (could be right, could be wrong, ...)
        }
예제 #6
0
        private void MigrateToKeePassOTP_Totp(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = 0;
            Dictionary <PwEntry, KPOTPEncoding> dEntries = new Dictionary <PwEntry, KPOTPEncoding>();

            foreach (KeyValuePair <KPOTPEncoding, string> kvp in m_dTotpStrings)
            {
                List <PwEntry> lHelp = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(kvp.Value)).ToList();
                foreach (PwEntry pe in lHelp)
                {
                    if (!dEntries.ContainsKey(pe))
                    {
                        dEntries[pe] = kvp.Key;
                    }
                }
            }
            EntriesOverall = dEntries.Count;
            if (dEntries.Count == 0)
            {
                return;
            }

            if (!OTPDAO.EnsureOTPSetupPossible(dEntries.Keys.First()))
            {
                return;
            }
            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(dEntries.Keys.First());
            InitLogger("KeePass -> KeePassOTP (TOTP)", dEntries.Count);
            try
            {
                foreach (KeyValuePair <PwEntry, KPOTPEncoding> kvp in dEntries)
                {
                    IncreaseLogger();
                    KPOTPEncoding enc = kvp.Value;
                    PwEntry       pe  = kvp.Key;

                    var otp = OTPDAO.GetOTP(pe);
                    otp.Encoding = enc;
                    otp.OTPSeed  = new ProtectedString(true, MigrateString(pe.Strings.ReadSafe(m_dTotpStrings[enc])));

                    string hash = pe.Strings.ReadSafe(TOTPHASH).ToLowerInvariant();
                    if (hash.Contains("sha-512"))
                    {
                        otp.Hash = KPOTPHash.SHA512;
                    }
                    else if (hash.Contains("sha-256"))
                    {
                        otp.Hash = KPOTPHash.SHA256;
                    }
                    else
                    {
                        otp.Hash = KPOTPHash.SHA1;
                    }

                    otp.Length       = MigrateInt(pe.Strings.ReadSafe(TOTPLENGTH), 6);
                    otp.TOTPTimestep = MigrateInt(pe.Strings.ReadSafe(TOTPPERIOD), 30);

                    otp.HOTPCounter = MigrateInt(pe.Strings.ReadSafe(HOTP_COUNTER), 0);
                    if (otp.Valid)
                    {
                        EntriesMigrated++;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                        if (bRemove)
                        {
                            pe.Strings.Remove(m_dTotpStrings[enc]);
                            pe.Strings.Remove(TOTPHASH);
                            pe.Strings.Remove(TOTPLENGTH);
                            pe.Strings.Remove(TOTPPERIOD);
                        }
                    }
                    else
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: " + m_dHotpStrings[enc]);
                    }
                }
            }
            finally
            {
                EndLogger();
            }
            MigratePlaceholder(PLACEHOLDER_TOTP, Config.Placeholder);
        }
예제 #7
0
        private void MigrateToKeePassOTP_Hotp(bool bRemove, out int EntriesOverall, out int EntriesMigrated)
        {
            EntriesOverall = EntriesMigrated = 0;
            List <PwEntry> lEntries = m_db.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(HOTP_COUNTER)).ToList();

            EntriesOverall = lEntries.Count;
            if (lEntries.Count == 0)
            {
                return;
            }

            if (!OTPDAO.EnsureOTPSetupPossible(lEntries[0]))
            {
                return;
            }
            OTPDAO.OTPHandler_Base handler = OTPDAO.GetOTPHandler(lEntries[0]);
            InitLogger("KeePass -> KeePassOTP (HOTP)", lEntries.Count);
            try
            {
                foreach (PwEntry pe in lEntries)
                {
                    IncreaseLogger();
                    KPOTPEncoding enc    = KPOTPEncoding.BASE32;
                    bool          bFound = false;
                    string        seed   = null;
                    foreach (KeyValuePair <KPOTPEncoding, string> kvp in m_dHotpStrings)
                    {
                        if (pe.Strings.Exists(kvp.Value))
                        {
                            enc    = kvp.Key;
                            seed   = pe.Strings.ReadSafe(kvp.Value);
                            bFound = true;
                            break;
                        }
                    }
                    if (!bFound)
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: not defined");
                        continue;
                    }
                    var otp = OTPDAO.GetOTP(pe);
                    otp.Type        = KPOTPType.HOTP;
                    otp.Encoding    = enc;
                    otp.OTPSeed     = new ProtectedString(true, MigrateString(seed));
                    otp.HOTPCounter = MigrateInt(pe.Strings.ReadSafe(HOTP_COUNTER), 0);
                    if (otp.Valid)
                    {
                        EntriesMigrated++;
                        try
                        {
                            handler.IgnoreBuffer = true;
                            OTPDAO.SaveOTP(otp, pe);
                        }
                        finally { handler.IgnoreBuffer = false; }
                        if (bRemove)
                        {
                            pe.Strings.Remove(m_dHotpStrings[enc]);
                            pe.Strings.Remove(HOTP_COUNTER);
                        }
                    }
                    else
                    {
                        PluginDebug.AddError("Migration of entry failed",
                                             "Uuid: " + pe.Uuid.ToHexString(),
                                             "OTP data: " + m_dHotpStrings[enc]);
                    }
                }
            }
            finally
            {
                EndLogger();
            }
            MigratePlaceholder(PLACEHOLDER_HOTP, Config.Placeholder);
        }