예제 #1
0
        private static int SanitizeSeeds(PwDatabase db)
        {
            //Get DB to work on
            PwDatabase otpdb = db;

            OTPDAO.OTPHandler_DB h = GetOTPHandler(db);
            if (h != null)
            {
                if (!h.EnsureOTPUsagePossible(null))
                {
                    return(-1);
                }
                otpdb = h.OTPDB;
            }
            int i = 0;

            foreach (PwEntry pe in otpdb.RootGroup.GetEntries(true))
            {
                KPOTP otp = OTPDAO.GetOTP(pe);
                if (!otp.Valid)
                {
                    continue;
                }
                otp.OTPSeed = otp.OTPSeed;
                if (otp.SanitizeChanged)
                {
                    i++;
                    pe.CreateBackup(otpdb);
                    pe.Strings.Set(Config.OTPFIELD, otp.OTPAuthString);
                }
            }
            return(i);
        }
예제 #2
0
 private void SprEngine_FilterCompile(object sender, SprEventArgs e)
 {
     if ((e.Context.Flags & SprCompileFlags.ExtActive) != SprCompileFlags.ExtActive)
     {
         return;
     }
     if (e.Text.IndexOf(Config.Placeholder, StringComparison.InvariantCultureIgnoreCase) >= 0)
     {
         OTPDAO.EnsureOTPUsagePossible(e.Context.Entry);
         KPOTP myOTP = OTPDAO.GetOTP(e.Context.Entry);
         if (!myOTP.Valid)
         {
             PluginDebug.AddError("Auto-Type OTP failed", 0, "Uuid: " + e.Context.Entry.Uuid.ToHexString());
         }
         else
         {
             PluginDebug.AddInfo("Auto-Type OTP success", 0, "Uuid: " + e.Context.Entry.Uuid.ToHexString());
         }
         e.Text = StrUtil.ReplaceCaseInsensitive(e.Text, Config.Placeholder, myOTP.GetOTP(false, true));
         if (myOTP.Valid && (myOTP.Type == KPOTPType.HOTP))
         {
             var newOTP = myOTP.Clone();
             newOTP.HOTPCounter++;
             OTPDAO.SaveOTP(newOTP, e.Context.Entry);
         }
     }
 }
예제 #3
0
        public override string GetCellData(string strColumnName, PwEntry pe)
        {
            if (strColumnName == null)
            {
                return(string.Empty);
            }
            if (pe == null)
            {
                return(string.Empty);
            }
            Random r = new Random();

            string otp       = string.Empty;
            bool   bForUsage = new System.Diagnostics.StackTrace().GetFrames().FirstOrDefault(x => x.GetMethod().Name == "OnPwListItemDrag") != null;

            if (bForUsage)
            {
                otp = OTPDAO.GetOTP(pe).GetOTP();
            }
            else
            {
                otp = OTPDAO.GetReadableOTP(pe);
            }
            if (!string.IsNullOrEmpty(otp))
            {
                if (bForUsage || strColumnName == OTPColumn_Verbose)
                {
                    return(otp);
                }
                return(PluginTranslation.PluginTranslate.TFADefined);
            }

            if (!Config.CheckTFA)
            {
                return(string.Empty);
            }
            string url = pe.Strings.ReadSafe(PwDefs.UrlField);

            if (string.IsNullOrEmpty(url))
            {
                return(string.Empty);
            }

            TFASites.TFAPossible TFAPossible = TFASites.IsTFAPossible(url);
            if (TFAPossible == TFASites.TFAPossible.Yes)
            {
                return(PluginTranslation.PluginTranslate.SetupTFA);
            }
            else if (TFAPossible == TFASites.TFAPossible.Unknown)
            {
                return("Checking 2FA");
            }
            else
            {
                return(string.Empty);
            }
        }
예제 #4
0
 private void OnEntryContextMenuOpening(object sender, EventArgs e)
 {
     m_ContextMenuCopy.ShortcutKeys = m_MainMenuCopy.ShortcutKeys = Config.Hotkey;
     if (m_host.MainWindow.GetSelectedEntriesCount() != 1)
     {
         m_ContextMenu.Enabled = m_ContextMenuAutotype.Enabled = false;
         m_MainMenu.Enabled    = m_MainMenuAutotype.Enabled = false;
     }
     else
     {
         KPOTP myOTP = OTPDAO.GetOTP(m_host.MainWindow.GetSelectedEntry(true));
         m_ContextMenu.Enabled     = m_MainMenu.Enabled = true;
         m_ContextMenuCopy.Enabled = m_ContextMenuAutotype.Enabled = m_ContextMenuQRCode.Enabled = myOTP.Valid;
         m_MainMenuCopy.Enabled    = m_MainMenuAutotype.Enabled = m_MainMenuQRCode.Enabled = myOTP.Valid;
     }
 }
예제 #5
0
        private static int ProcessReferences(PwDatabase db)
        {
            //Get DB to work on
            PwDatabase otpdb = db;

            OTPDAO.OTPHandler_DB h = GetOTPHandler(db);
            if (h != null)
            {
                if (!h.EnsureOTPUsagePossible(null))
                {
                    return(-1);
                }
                otpdb = h.OTPDB;
            }
            if (otpdb == null || !otpdb.IsOpen)
            {
                return(-1);
            }
            int i = 0;
            var b = new OTPHandler_Base();

            foreach (PwEntry pe in otpdb.RootGroup.GetEntries(true))
            {
                KPOTP otp = OTPDAO.GetOTP(pe);
                if (!otp.Valid)
                {
                    continue;
                }
                if (!otp.Issuer.ToLowerInvariant().Contains("{ref:") && !otp.Label.ToLowerInvariant().EndsWith("{ref"))
                {
                    continue;
                }
                PwEntry peMain = h is OTPHandler_DB ? (h as OTPHandler_DB).GetMainPwEntry(pe) : pe;
                b.InitIssuerLabel(otp, peMain);
                pe.CreateBackup(otpdb);
                pe.Strings.Set(Config.OTPFIELD, otp.OTPAuthString);
                i++;
            }
            return(i);
        }
예제 #6
0
        private void OnOTPSetup(object sender, EventArgs e)
        {
            if (m_host.MainWindow.GetSelectedEntriesCount() != 1)
            {
                return;
            }
            PwEntry pe = m_host.MainWindow.GetSelectedEntry(true);

            if (!OTPDAO.EnsureOTPSetupPossible(pe))
            {
                return;
            }
            var otpSetup = new KeePassOTPSetup();

            Tools.GlobalWindowManager(otpSetup);
            otpSetup.OTP      = OTPDAO.GetOTP(pe);
            otpSetup.EntryUrl = pe.Strings.GetSafe(PwDefs.UrlField).ReadString();
            otpSetup.InitEx();
            if (otpSetup.ShowDialog(m_host.MainWindow) == DialogResult.OK)
            {
                OTPDAO.SaveOTP(otpSetup.OTP, pe);
            }
            otpSetup.Dispose();
        }
예제 #7
0
        internal static bool CopyOTP(PwEntry pe)
        {
            if (!OTPDAO.EnsureOTPUsagePossible(pe))
            {
                PluginDebug.AddError("Copy OTP failed", 0, "Uuid: " + pe.Uuid.ToHexString(), "OTP db not unlocked");
                return(false);
            }
            KPOTP myOTP = OTPDAO.GetOTP(pe);

            if (!myOTP.Valid)
            {
                PluginDebug.AddError("Copy OTP failed", 0, "Uuid: " + pe.Uuid.ToHexString());
                return(false);
            }
            ClipboardUtil.CopyAndMinimize(myOTP.GetOTP(false, true), true, Program.MainForm, pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe));
            Program.MainForm.StartClipboardCountdown();
            PluginDebug.AddInfo("Copy OTP success", 0, "Uuid: " + pe.Uuid.ToString());
            if (myOTP.Type == KPOTPType.HOTP)
            {
                myOTP.HOTPCounter++;
                OTPDAO.SaveOTP(myOTP, pe);
            }
            return(true);
        }
예제 #8
0
        private static int OTPAuthFormatCorrection(PwDatabase db)
        {
            //Get DB to work on
            PwDatabase otpdb = db;

            OTPDAO.OTPHandler_DB h = GetOTPHandler(db);
            if (h != null)
            {
                if (!h.EnsureOTPUsagePossible(null))
                {
                    return(-1);
                }
                otpdb = h.OTPDB;
            }
            int i = 0;

            foreach (PwEntry pe in otpdb.RootGroup.GetEntries(true).Where(x => x.Strings.Exists(Config.OTPFIELD)))
            {
                //Don't compare strings because strings are not protected and will remain in memory
                char[] ps = pe.Strings.Get(Config.OTPFIELD).ReadChars();
                try
                {
                    if (ps.Length < 15)
                    {
                        continue;
                    }
                    bool bConvert = false;
                    foreach (char[] check in lOTPAuthStart)
                    {
                        if (check.Length > ps.Length)
                        {
                            continue;
                        }
                        bConvert = true;
                        for (int j = 0; j < check.Length; j++)
                        {
                            if (Char.ToLowerInvariant(check[j]) != Char.ToLowerInvariant(ps[j]))
                            {
                                bConvert = false;
                                break;
                            }
                        }
                        if (bConvert)
                        {
                            break;
                        }
                    }
                    if (!bConvert)
                    {
                        break;
                    }
                    KPOTP otp = OTPDAO.GetOTP(pe);
                    if (!otp.Valid)
                    {
                        continue;
                    }
                    i++;
                    pe.CreateBackup(otpdb);
                    pe.Strings.Set(Config.OTPFIELD, otp.OTPAuthString);
                }
                finally { MemUtil.ZeroArray(ps); }
            }
            return(i);
        }
예제 #9
0
        private void OnOTPQRCode(object sender, EventArgs e)
        {
            if (m_host.MainWindow.GetSelectedEntriesCount() != 1)
            {
                return;
            }
            KPOTP otp = OTPDAO.GetOTP(m_host.MainWindow.GetSelectedEntry(true));

            if (!otp.Valid)
            {
                return;
            }
            try
            {
                byte[]             bOTP = otp.OTPAuthString.ReadUtf8();
                QRCoder.QRCodeData qrd  = QRCoder.QRCodeGenerator.GenerateQrCode(bOTP, QRCoder.QRCodeGenerator.ECCLevel.Q);
                MemUtil.ZeroByteArray(bOTP);
                QRCoder.QRCode qrc = new QRCoder.QRCode(qrd);
                Bitmap         bmp = qrc.GetGraphic(8);
                QRForm         f   = new QRForm();
                f.FormBorderStyle = FormBorderStyle.FixedDialog;
                f.StartPosition   = FormStartPosition.CenterParent;
                f.Text            = PluginTranslate.PluginName;
                f.MinimizeBox     = false;
                f.MaximizeBox     = false;
                PictureBox pb = new PictureBox();
                pb.Size      = new Size(bmp.Width, bmp.Height);
                pb.Location  = new Point(0, 0);
                f.ClientSize = pb.Size;
                pb.Image     = bmp;
                f.Controls.Add(pb);
                if (!string.IsNullOrEmpty(otp.Issuer) && (otp.Issuer != PluginTranslate.PluginName))
                {
                    Label lIssuer = new Label();
                    lIssuer.Width    = f.ClientSize.Width;
                    lIssuer.Text     = otp.Issuer;
                    lIssuer.Location = new Point(0, f.ClientSize.Height + 10);
                    f.Controls.Add(lIssuer);
                    f.Height += lIssuer.Height + 10;
                }
                if (!string.IsNullOrEmpty(otp.Label))
                {
                    Label lLabel = new Label();
                    lLabel.Width    = f.ClientSize.Width;
                    lLabel.Text     = otp.Label;
                    lLabel.Location = new Point(0, f.ClientSize.Height + 10);
                    f.Controls.Add(lLabel);
                    f.Height += lLabel.Height + 10;
                }
                f.Height += 5;
                Timer tClose = new Timer();
                tClose.Interval = 30000;
                tClose.Tick    += (o, e1) =>
                {
                    tClose.Stop();
                    tClose.Dispose();
                    if (f != null)
                    {
                        f.Close();
                    }
                };
                f.Shown += (o, e2) =>
                {
                    KeePass.UI.GlobalWindowManager.AddWindow(f, f);
                    tClose.Start();
                };
                f.FormClosed += (o, e1) => { if (f != null)
                                             {
                                                 KeePass.UI.GlobalWindowManager.RemoveWindow(f);
                                             }
                };
                f.ShowDialog(KeePass.UI.GlobalWindowManager.TopWindow);
                pb.Image.Dispose();
                f.Dispose();
                qrc.Dispose();
                qrd.Dispose();
            }
            catch { }
        }
예제 #10
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);
        }
예제 #11
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);
        }
예제 #12
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);
        }
예제 #13
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);
        }
예제 #14
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, ...)
        }
예제 #15
0
        private void OnOTPQRCode(object sender, EventArgs e)
        {
            if (m_host.MainWindow.GetSelectedEntriesCount() != 1)
            {
                return;
            }
            KPOTP otp = OTPDAO.GetOTP(m_host.MainWindow.GetSelectedEntry(true));

            if (!otp.Valid)
            {
                return;
            }
            try
            {
                ZXing.BarcodeWriter zBW = new ZXing.BarcodeWriter();
                zBW.Options.Height = 320;
                zBW.Options.Width  = 320;
                zBW.Format         = ZXing.BarcodeFormat.QR_CODE;
                Bitmap bmp = zBW.Write(otp.OTPAuthString.ReadString());
                QRForm f   = new QRForm();
                f.FormBorderStyle = FormBorderStyle.FixedDialog;
                f.StartPosition   = FormStartPosition.CenterParent;
                f.Text            = PluginTranslate.PluginName;
                f.MinimizeBox     = false;
                f.MaximizeBox     = false;
                PictureBox pb = new PictureBox();
                pb.Location   = new Point(0, 0);
                pb.Image      = new Bitmap(bmp, bmp.Size);            //Assigning bmp directly did not work in my Ubuntu VM...
                pb.ClientSize = pb.Image.Size;
                f.ClientSize  = pb.Size;
                f.Controls.Add(pb);
                if (!string.IsNullOrEmpty(otp.Issuer) && (otp.Issuer != PluginTranslate.PluginName))
                {
                    Label lIssuer = new Label();
                    lIssuer.Width    = f.ClientSize.Width;
                    lIssuer.Text     = otp.Issuer;
                    lIssuer.Location = new Point(0, f.ClientSize.Height + 10);
                    f.Controls.Add(lIssuer);
                    f.Height += lIssuer.Height + 10;
                }
                if (!string.IsNullOrEmpty(otp.Label))
                {
                    Label lLabel = new Label();
                    lLabel.Width    = f.ClientSize.Width;
                    lLabel.Text     = otp.Label;
                    lLabel.Location = new Point(0, f.ClientSize.Height + 10);
                    f.Controls.Add(lLabel);
                    f.Height += lLabel.Height + 10;
                }
                f.Height += 5;
                Timer tClose = new Timer();
                tClose.Interval = 30000;
                tClose.Tick    += (o, e1) =>
                {
                    tClose.Stop();
                    tClose.Dispose();
                    if (f != null)
                    {
                        f.Close();
                    }
                };
                f.Shown += (o, e2) =>
                {
                    KeePass.UI.GlobalWindowManager.AddWindow(f, f);
                    tClose.Start();
                };
                f.FormClosed += (o, e1) => { if (f != null)
                                             {
                                                 KeePass.UI.GlobalWindowManager.RemoveWindow(f);
                                             }
                };
                f.ShowDialog(KeePass.UI.GlobalWindowManager.TopWindow);
                pb.Image.Dispose();
                f.Dispose();
                bmp.Dispose();
            }
            catch { };
        }
예제 #16
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);
        }
예제 #17
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);
        }