private static string ReplacePickPwPlaceholder(string str, string strPlaceholder, uint uCharCount, SprContext ctx, uint uRecursionLevel) { if(str.IndexOf(strPlaceholder, StrUtil.CaseIgnoreCmp) < 0) return str; ProtectedString ps = ctx.Entry.Strings.Get(PwDefs.PasswordField); if(ps != null) { string strPassword = ps.ReadString(); string strPick = SprEngine.CompileInternal(strPassword, ctx.WithoutContentTransformations(), uRecursionLevel + 1); if(!string.IsNullOrEmpty(strPick)) { ProtectedString psPick = new ProtectedString(false, strPick); string strPicked = (CharPickerForm.ShowAndRestore(psPick, true, true, uCharCount, null) ?? string.Empty); str = StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, SprEngine.TransformContent(strPicked, ctx)); } } return StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, string.Empty); }
// Legacy, for backward compatibility only; see PickChars private static string ReplacePickPw(string strText, SprContext ctx, uint uRecursionLevel) { if(ctx.Entry == null) { Debug.Assert(false); return strText; } string str = strText; while(true) { const string strStart = @"{PICKPASSWORDCHARS"; int iStart = str.IndexOf(strStart, StrUtil.CaseIgnoreCmp); if(iStart < 0) break; int iEnd = str.IndexOf('}', iStart); if(iEnd < 0) break; string strPlaceholder = str.Substring(iStart, iEnd - iStart + 1); string strParam = str.Substring(iStart + strStart.Length, iEnd - (iStart + strStart.Length)); string[] vParams = strParam.Split(new char[] { ':' }); uint uCharCount = 0; if(vParams.Length >= 2) uint.TryParse(vParams[1], out uCharCount); str = ReplacePickPwPlaceholder(str, strPlaceholder, uCharCount, ctx, uRecursionLevel); } return str; }
public static string Compile(string strText, bool bIsAutoTypeSequence, PwEntry pwEntry, PwDatabase pwDatabase, bool bEscapeForAutoType, bool bEscapeQuotesForCommandLine) { SprContext ctx = new SprContext(pwEntry, pwDatabase, SprCompileFlags.All, bEscapeForAutoType, bEscapeQuotesForCommandLine); return Compile(strText, ctx); }
public static string Compile(string strText, SprContext ctx) { if(strText == null) { Debug.Assert(false); return string.Empty; } if(strText.Length == 0) return string.Empty; SprEngine.InitializeStatic(); if(ctx == null) ctx = new SprContext(); ctx.RefsCache.Clear(); string str = SprEngine.CompileInternal(strText, ctx, 0); // if(bEscapeForAutoType && !bIsAutoTypeSequence) // str = SprEncoding.MakeAutoTypeSequence(str); return str; }
public static string Compile(string strText, SprContext ctx) { if (strText == null) { Debug.Assert(false); return(string.Empty); } if (strText.Length == 0) { return(string.Empty); } if (ctx == null) { ctx = new SprContext(); } ctx.RefCache.Clear(); string str = SprEngine.CompileInternal(strText, ctx, 0); // if(bEscapeForAutoType && !bIsAutoTypeSequence) // str = SprEncoding.MakeAutoTypeSequence(str); return(str); }
/// <summary> /// Hash all settings of <paramref name="ctx" /> that may /// affect the encoded value of a field reference. /// </summary> private static uint HashContext(SprContext ctx) { if (ctx == null) { Debug.Assert(false); return(0); } uint u = 0; if (ctx.ForcePlainTextPasswords) { u |= 1; } if (ctx.EncodeQuotesForCommandLine) { u |= 2; } if (ctx.EncodeAsAutoTypeSequence) { u |= 4; } return(u); }
private static string FillEntryStringsSpecial(string str, SprContext ctx, uint uRecursionLevel) { if ((str.IndexOf(UrlSpecialRmvScm, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialScm, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialHost, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialPort, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialPath, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialQuery, SprEngine.ScMethod) >= 0)) { string strUrl = SprEngine.FillIfExists(@"{URL}", @"{URL}", ctx.Entry.Strings.GetSafe(PwDefs.UrlField), ctx, uRecursionLevel); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialRmvScm, UrlUtil.RemoveScheme(strUrl)); try { Uri uri = new Uri(strUrl); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialScm, uri.Scheme); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialHost, uri.Host); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialPort, uri.Port.ToString()); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialPath, uri.AbsolutePath); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialQuery, uri.Query); } catch (Exception) { } // Invalid URI } return(str); }
private static string Fill(string strData, string strPlaceholder, ProtectedString psReplacement, SprContext ctx, uint?ouRecursionLevel) { if (strData == null) { Debug.Assert(false); return(string.Empty); } if (string.IsNullOrEmpty(strPlaceholder)) { Debug.Assert(false); return(strData); } if (psReplacement == null) { Debug.Assert(false); psReplacement = ProtectedString.Empty; } if (strData.IndexOf(strPlaceholder, SprEngine.ScMethod) < 0) { return(strData); } return(Fill(strData, strPlaceholder, psReplacement.ReadString(), ctx, ouRecursionLevel)); }
public static string TransformContent(string strContent, SprContext ctx) { if (strContent == null) { Debug.Assert(false); return(string.Empty); } string str = strContent; if (ctx != null) { if (ctx.EncodeForCommandLine) { str = SprEncoding.EncodeForCommandLine(str); } if (ctx.EncodeAsAutoTypeSequence) { str = SprEncoding.EncodeAsAutoTypeSequence(str); } } return(str); }
private static string FillGroupPlh(string strData, string strPlhPrefix, PwGroup pg, SprContext ctx, uint uRecursionLevel) { Debug.Assert(strPlhPrefix.StartsWith("{")); Debug.Assert(!strPlhPrefix.EndsWith("_")); Debug.Assert(!strPlhPrefix.EndsWith("}")); string str = strData; str = SprEngine.FillIfExists(str, strPlhPrefix + @"}", new ProtectedString(false, pg.Name), ctx, uRecursionLevel); ProtectedString psGroupPath = new ProtectedString(false, pg.GetFullPath()); str = SprEngine.FillIfExists(str, strPlhPrefix + @"_PATH}", psGroupPath, ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, strPlhPrefix + @"PATH}", psGroupPath, ctx, uRecursionLevel); // Obsolete; for backward compatibility str = SprEngine.FillIfExists(str, strPlhPrefix + @"_NOTES}", new ProtectedString(false, pg.Notes), ctx, uRecursionLevel); return(str); }
private static string ReplacePickPwPlaceholder(string str, string strPlaceholder, uint uCharCount, SprContext ctx, uint uRecursionLevel) { if (str.IndexOf(strPlaceholder, StrUtil.CaseIgnoreCmp) < 0) { return(str); } ProtectedString ps = ctx.Entry.Strings.Get(PwDefs.PasswordField); if (ps != null) { string strPassword = ps.ReadString(); string strPick = SprEngine.CompileInternal(strPassword, ctx.WithoutContentTransformations(), uRecursionLevel + 1); if (!string.IsNullOrEmpty(strPick)) { ProtectedString psPick = new ProtectedString(false, strPick); string strPicked = (CharPickerForm.ShowAndRestore(psPick, true, true, uCharCount, null) ?? string.Empty); str = StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, SprEngine.TransformContent(strPicked, ctx)); } } return(StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, string.Empty)); }
private static string FillIfExists(string strData, string strPlaceholder, ProtectedString psParsable, SprContext ctx, uint uRecursionLevel) { // // The UrlRemoveSchemeOnce property of ctx must be cleared // // before this method returns and before any recursive call // bool bRemoveScheme = false; // if(ctx != null) // { // bRemoveScheme = ctx.UrlRemoveSchemeOnce; // ctx.UrlRemoveSchemeOnce = false; // } if(strData == null) { Debug.Assert(false); return string.Empty; } if(strPlaceholder == null) { Debug.Assert(false); return strData; } if(strPlaceholder.Length == 0) { Debug.Assert(false); return strData; } if(psParsable == null) { Debug.Assert(false); return strData; } if(strData.IndexOf(strPlaceholder, SprEngine.ScMethod) >= 0) { string strReplacement = SprEngine.CompileInternal( psParsable.ReadString(), ctx.WithoutContentTransformations(), uRecursionLevel + 1); // if(bRemoveScheme) // strReplacement = UrlUtil.RemoveScheme(strReplacement); return SprEngine.FillPlaceholder(strData, strPlaceholder, strReplacement, ctx); } return strData; }
void UpdateKeyInfo() { if (hasSshKeyCheckBox.Checked) { switch (keyLocationPanel.KeyLocation.SelectedType) { case EntrySettings.LocationType.Attachment: case EntrySettings.LocationType.File: try { pwEntryForm.UpdateEntryStrings(true, false); var context = new SprContext(pwEntryForm.EntryRef, pwEntryForm.EntryRef.GetDatabase (), SprCompileFlags.Deref); using (var key = CurrentSettings. GetSshKey(pwEntryForm.EntryStrings, pwEntryForm.EntryBinaries, context)) { commentTextBox.Text = key.Comment; fingerprintTextBox.Text = key.GetMD5Fingerprint().ToHexString(); publicKeyTextBox.Text = key.GetAuthorizedKeyString(); copyPublicKeybutton.Enabled = true; } } catch (Exception) { string file = "attachment"; if (keyLocationPanel.KeyLocation.SelectedType == EntrySettings.LocationType.File) { try { file = Path.GetFullPath(CurrentSettings.Location.FileName); } catch (Exception) { file = "file"; } } commentTextBox.Text = string.Format("<Error loading key from {0}>", file); fingerprintTextBox.Text = string.Empty; publicKeyTextBox.Text = string.Empty; copyPublicKeybutton.Enabled = false; } break; default: commentTextBox.Text = "No key selected"; fingerprintTextBox.Text = string.Empty; publicKeyTextBox.Text = string.Empty; copyPublicKeybutton.Enabled = false; break; } } else { commentTextBox.Text = string.Empty; fingerprintTextBox.Text = string.Empty; publicKeyTextBox.Text = string.Empty; } }
private static string ReplaceHmacOtpPlaceholder(string strText, SprContext ctx) { PwEntry pe = ctx.Entry; PwDatabase pd = ctx.Database; if((pe == null) || (pd == null)) return strText; string str = strText; const string strHmacOtpPlh = @"{HMACOTP}"; if(str.IndexOf(strHmacOtpPlh, StrUtil.CaseIgnoreCmp) >= 0) { const string strKeyFieldUtf8 = "HmacOtp-Secret"; const string strKeyFieldHex = "HmacOtp-Secret-Hex"; const string strKeyFieldBase32 = "HmacOtp-Secret-Base32"; const string strKeyFieldBase64 = "HmacOtp-Secret-Base64"; const string strCounterField = "HmacOtp-Counter"; byte[] pbSecret = null; try { string strKey = pe.Strings.ReadSafe(strKeyFieldUtf8); if(strKey.Length > 0) pbSecret = StrUtil.Utf8.GetBytes(strKey); if(pbSecret == null) { strKey = pe.Strings.ReadSafe(strKeyFieldHex); if(strKey.Length > 0) pbSecret = MemUtil.HexStringToByteArray(strKey); } if(pbSecret == null) { strKey = pe.Strings.ReadSafe(strKeyFieldBase32); if(strKey.Length > 0) pbSecret = MemUtil.ParseBase32(strKey); } if(pbSecret == null) { strKey = pe.Strings.ReadSafe(strKeyFieldBase64); if(strKey.Length > 0) pbSecret = Convert.FromBase64String(strKey); } } catch(Exception) { Debug.Assert(false); } if(pbSecret == null) pbSecret = new byte[0]; string strCounter = pe.Strings.ReadSafe(strCounterField); ulong uCounter; ulong.TryParse(strCounter, out uCounter); string strValue = HmacOtp.Generate(pbSecret, uCounter, 6, false, -1); pe.Strings.Set(strCounterField, new ProtectedString(false, (uCounter + 1).ToString())); pd.Modified = true; str = StrUtil.ReplaceCaseInsensitive(str, strHmacOtpPlh, strValue); } return str; }
public static string FillPlaceholders(string strText, SprContext ctx, uint uRecursionLevel) { if((ctx == null) || (ctx.Entry == null)) return strText; string str = strText; if((ctx.Flags & SprCompileFlags.NewPassword) != SprCompileFlags.None) str = ReplaceNewPasswordPlaceholder(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.HmacOtp) != SprCompileFlags.None) str = ReplaceHmacOtpPlaceholder(str, ctx); return str; }
private static bool HighlightRegularPlh(SprPart pPart, List <SprStyle> lStyles, Stack <SprPart> sToDo, SprContext ctx) { string str = pPart.Text; int iStart = str.IndexOf('{'); if (iStart < 0) { return(false); } if ((iStart + 2) >= str.Length) { SetStyle(lStyles, pPart, iStart, str.Length - iStart, SprStyleError); } else { int iOpen = str.IndexOf('{', iStart + 2); int iClose = str.IndexOf('}', iStart + 2); bool bAT = ((ctx != null) && ctx.EncodeAsAutoTypeSequence); if (iClose < 0) { SetStyle(lStyles, pPart, iStart, str.Length - iStart, SprStyleError); } else if ((iOpen >= 0) && (iOpen < iClose)) { sToDo.Push(pPart.GetPart(iOpen)); SetStyle(lStyles, pPart, iStart, iOpen - iStart, SprStyleError); } else if (bAT && ((str[iStart + 1] == '{') || (str[iStart + 1] == '}')) && (iClose != (iStart + 2))) { sToDo.Push(pPart.GetPart(iClose + 1)); SetStyle(lStyles, pPart, iStart, iClose - iStart + 1, SprStyleError); } else { sToDo.Push(pPart.GetPart(iClose + 1)); int iErrLvl = 0; string strPlh = str.Substring(iStart + 1, iClose - iStart - 1); if (strPlh.Length == 0) { Debug.Assert(false); iErrLvl = 2; } else if (char.IsWhiteSpace(strPlh[0])) { iErrLvl = 2; } else if (strPlh.StartsWith("S:", StrUtil.CaseIgnoreCmp) && (ctx != null) && (ctx.Entry != null)) { string strField = strPlh.Substring(2); List <string> lFields = PwDefs.GetStandardFields(); lFields.AddRange(ctx.Entry.Strings.GetKeys()); bool bFound = false; foreach (string strAvail in lFields) { if (strField.Equals(strAvail, StrUtil.CaseIgnoreCmp)) { bFound = true; break; } } if (!bFound) { iErrLvl = 1; } } SprStyle s = SprStyleOK; if (iErrLvl == 1) { s = SprStyleWarning; } else if (iErrLvl > 1) { s = SprStyleError; } SetStyle(lStyles, pPart, iStart, iClose - iStart + 1, s); } } if (iStart > 0) { sToDo.Push(pPart.GetPart(0, iStart)); } return(true); }
internal static string DerefFn(string str, PwEntry pe) { if(!MightDeref(str)) return str; SprContext ctx = new SprContext(pe, Program.MainForm.DocumentManager.SafeFindContainerOf(pe), SprCompileFlags.Deref); // ctx.ForcePlainTextPasswords = false; return Compile(str, ctx); }
internal string[] GetUserPass(PwEntryDatabase entryDatabase) { // follow references SprContext ctx = new SprContext(entryDatabase.entry, entryDatabase.database, SprCompileFlags.All, false, false); string user = SprEngine.Compile( entryDatabase.entry.Strings.ReadSafe(PwDefs.UserNameField), ctx); string pass = SprEngine.Compile( entryDatabase.entry.Strings.ReadSafe(PwDefs.PasswordField), ctx); var f = (MethodInvoker)delegate { // apparently, SprEngine.Compile might modify the database host.MainWindow.UpdateUI(false, null, false, null, false, null, false); }; if (host.MainWindow.InvokeRequired) host.MainWindow.Invoke(f); else f.Invoke(); return new string[] { user, pass }; }
internal static SprContext GetEntryListSprContext(PwEntry pe, PwDatabase pd) { SprContext ctx = new SprContext(pe, pd, SprCompileFlags.Deref); ctx.ForcePlainTextPasswords = false; return ctx; }
public static ISshKey GetSshKey(this EntrySettings settings, ProtectedStringDictionary strings, ProtectedBinaryDictionary binaries, SprContext sprContext) { if (!settings.AllowUseOfSshKey) { return null; } KeyFormatter.GetPassphraseCallback getPassphraseCallback = delegate(string comment) { var securePassphrase = new SecureString(); var passphrase = SprEngine.Compile(strings.ReadSafe( PwDefs.PasswordField), sprContext); foreach (var c in passphrase) { securePassphrase.AppendChar(c); } return securePassphrase; }; Func<Stream> getPrivateKeyStream; Func<Stream> getPublicKeyStream = null; switch (settings.Location.SelectedType) { case EntrySettings.LocationType.Attachment: if (string.IsNullOrWhiteSpace(settings.Location.AttachmentName)) { throw new NoAttachmentException(); } var privateKeyData = binaries.Get(settings.Location.AttachmentName); var publicKeyData = binaries.Get(settings.Location.AttachmentName + ".pub"); getPrivateKeyStream = () => new MemoryStream(privateKeyData.ReadData()); if (publicKeyData != null) getPublicKeyStream = () => new MemoryStream(publicKeyData.ReadData()); return GetSshKey(getPrivateKeyStream, getPublicKeyStream, settings.Location.AttachmentName, getPassphraseCallback); case EntrySettings.LocationType.File: getPrivateKeyStream = () => File.OpenRead(settings.Location.FileName); var publicKeyFile = settings.Location.FileName + ".pub"; if (File.Exists(publicKeyFile)) getPublicKeyStream = () => File.OpenRead(publicKeyFile); return GetSshKey(getPrivateKeyStream, getPublicKeyStream, settings.Location.AttachmentName, getPassphraseCallback); default: return null; } }
public static ISshKey GetSshKey(this PwEntry entry) { var settings = entry.GetKeeAgentSettings(); var context = new SprContext(entry, entry.GetDatabase(), SprCompileFlags.Deref); return settings.GetSshKey(entry.Strings, entry.Binaries, context); }
private static string RunCommands(string strText, SprContext ctx, uint uRecursionLevel) { string str = strText; int iStart; List <string> lParams; while (ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{CMD:", out iStart, out lParams, true)) { if (lParams.Count == 0) { continue; } string strCmd = lParams[0]; if (string.IsNullOrEmpty(strCmd)) { continue; } Process p = null; try { StringComparison sc = StrUtil.CaseIgnoreCmp; string strOpt = ((lParams.Count >= 2) ? lParams[1] : string.Empty); Dictionary <string, string> d = SplitParams(strOpt); ProcessStartInfo psi = new ProcessStartInfo(); string strApp, strArgs; StrUtil.SplitCommandLine(strCmd, out strApp, out strArgs); strApp = WinUtil.CompileUrl((strApp ?? string.Empty), ((ctx != null) ? ctx.Entry : null), true, null); if (string.IsNullOrEmpty(strApp)) { continue; } psi.FileName = strApp; if (!string.IsNullOrEmpty(strArgs)) { psi.Arguments = strArgs; } string strMethod = GetParam(d, "m", "s"); bool bShellExec = !strMethod.Equals("c", sc); psi.UseShellExecute = bShellExec; string strO = GetParam(d, "o", (bShellExec ? "0" : "1")); bool bStdOut = strO.Equals("1", sc); if (bStdOut) { psi.RedirectStandardOutput = true; } string strWS = GetParam(d, "ws", "n"); if (strWS.Equals("h", sc)) { psi.CreateNoWindow = true; psi.WindowStyle = ProcessWindowStyle.Hidden; } else if (strWS.Equals("min", sc)) { psi.WindowStyle = ProcessWindowStyle.Minimized; } else if (strWS.Equals("max", sc)) { psi.WindowStyle = ProcessWindowStyle.Maximized; } else { Debug.Assert(psi.WindowStyle == ProcessWindowStyle.Normal); } string strVerb = GetParam(d, "v", null); if (!string.IsNullOrEmpty(strVerb)) { psi.Verb = strVerb; } bool bWait = GetParam(d, "w", "1").Equals("1", sc); p = Process.Start(psi); if (p == null) { Debug.Assert(false); continue; } if (bStdOut) { string strOut = p.StandardOutput.ReadToEnd(); strOut = TransformContent(strOut, ctx); str = str.Insert(iStart, strOut); } if (bWait) { p.WaitForExit(); } } catch (Exception ex) { string strMsg = strCmd + MessageService.NewParagraph + ex.Message; MessageService.ShowWarning(strMsg); } finally { try { if (p != null) { p.Dispose(); } } catch (Exception) { Debug.Assert(false); } } } return(str); }
private static string FillRefPlaceholders(string strSeq, SprContext ctx, uint uRecursionLevel) { if(ctx.Database == null) return strSeq; string str = strSeq; int nOffset = 0; for(int iLoop = 0; iLoop < 20; ++iLoop) { str = SprEngine.FillRefsUsingCache(str, ctx); int nStart = str.IndexOf(StrRefStart, nOffset, SprEngine.ScMethod); if(nStart < 0) break; int nEnd = str.IndexOf(StrRefEnd, nStart + 1, SprEngine.ScMethod); if(nEnd <= nStart) break; string strFullRef = str.Substring(nStart, nEnd - nStart + 1); char chScan, chWanted; PwEntry peFound = FindRefTarget(strFullRef, ctx, out chScan, out chWanted); if(peFound != null) { string strInsData; if(chWanted == 'T') strInsData = peFound.Strings.ReadSafe(PwDefs.TitleField); else if(chWanted == 'U') strInsData = peFound.Strings.ReadSafe(PwDefs.UserNameField); else if(chWanted == 'A') strInsData = peFound.Strings.ReadSafe(PwDefs.UrlField); else if(chWanted == 'P') strInsData = peFound.Strings.ReadSafe(PwDefs.PasswordField); else if(chWanted == 'N') strInsData = peFound.Strings.ReadSafe(PwDefs.NotesField); else if(chWanted == 'I') strInsData = peFound.Uuid.ToHexString(); else { nOffset = nStart + 1; continue; } if((chWanted == 'P') && !ctx.ForcePlainTextPasswords && Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password)) strInsData = PwDefs.HiddenPassword; SprContext sprSub = ctx.WithoutContentTransformations(); sprSub.Entry = peFound; string strInnerContent = SprEngine.CompileInternal(strInsData, sprSub, uRecursionLevel + 1); strInnerContent = SprEngine.TransformContent(strInnerContent, ctx); // str = str.Substring(0, nStart) + strInnerContent + str.Substring(nEnd + 1); SprEngine.AddRefToCache(strFullRef, strInnerContent, ctx); str = SprEngine.FillRefsUsingCache(str, ctx); } else { nOffset = nStart + 1; continue; } } return str; }
public static void OpenUrl(string strUrlToOpen, PwEntry peDataSource, bool bAllowOverride, string strBaseRaw) { // If URL is null, return, do not throw exception. Debug.Assert(strUrlToOpen != null); if(strUrlToOpen == null) return; string strPrevWorkDir = WinUtil.GetWorkingDirectory(); string strThisExe = WinUtil.GetExecutable(); string strExeDir = UrlUtil.GetFileDirectory(strThisExe, false, true); WinUtil.SetWorkingDirectory(strExeDir); string strUrlFlt = strUrlToOpen; strUrlFlt = strUrlFlt.TrimStart(new char[]{ ' ', '\t', '\r', '\n' }); PwDatabase pwDatabase = null; try { pwDatabase = Program.MainForm.DocumentManager.SafeFindContainerOf( peDataSource); } catch(Exception) { Debug.Assert(false); } bool bCmdQuotes = WinUtil.IsCommandLineUrl(strUrlFlt); SprContext ctx = new SprContext(peDataSource, pwDatabase, SprCompileFlags.All, false, bCmdQuotes); ctx.Base = strBaseRaw; ctx.BaseIsEncoded = false; string strUrl = SprEngine.Compile(strUrlFlt, ctx); string strOvr = Program.Config.Integration.UrlSchemeOverrides.GetOverrideForUrl( strUrl); if(!bAllowOverride) strOvr = null; if(strOvr != null) { bool bCmdQuotesOvr = WinUtil.IsCommandLineUrl(strOvr); SprContext ctxOvr = new SprContext(peDataSource, pwDatabase, SprCompileFlags.All, false, bCmdQuotesOvr); ctxOvr.Base = strUrl; ctxOvr.BaseIsEncoded = bCmdQuotes; strUrl = SprEngine.Compile(strOvr, ctxOvr); } if(WinUtil.IsCommandLineUrl(strUrl)) { string strApp, strArgs; StrUtil.SplitCommandLine(WinUtil.GetCommandLineFromUrl(strUrl), out strApp, out strArgs); try { if((strArgs != null) && (strArgs.Length > 0)) Process.Start(strApp, strArgs); else Process.Start(strApp); } catch(Win32Exception) { StartWithoutShellExecute(strApp, strArgs); } catch(Exception exCmd) { string strInf = KPRes.FileOrUrl + ": " + strApp; if((strArgs != null) && (strArgs.Length > 0)) strInf += MessageService.NewParagraph + KPRes.Arguments + ": " + strArgs; MessageService.ShowWarning(strInf, exCmd); } } else // Standard URL { try { Process.Start(strUrl); } catch(Exception exUrl) { MessageService.ShowWarning(strUrl, exUrl); } } // Restore previous working directory WinUtil.SetWorkingDirectory(strPrevWorkDir); // SprEngine.Compile might have modified the database Program.MainForm.UpdateUI(false, null, false, null, false, null, false); }
private static string FillRefsUsingCache(string strText, SprContext ctx) { string str = strText; foreach(KeyValuePair<string, string> kvp in ctx.RefsCache) { // str = str.Replace(kvp.Key, kvp.Value); str = StrUtil.ReplaceCaseInsensitive(str, kvp.Key, kvp.Value); } return str; }
private static string FillEntryStringsSpecial(string str, SprContext ctx, uint uRecursionLevel) { if((str.IndexOf(UrlSpecialRmvScm, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialScm, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialHost, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialPort, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialPath, SprEngine.ScMethod) >= 0) || (str.IndexOf(UrlSpecialQuery, SprEngine.ScMethod) >= 0)) { string strUrl = SprEngine.FillIfExists(@"{URL}", @"{URL}", ctx.Entry.Strings.GetSafe(PwDefs.UrlField), ctx, uRecursionLevel); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialRmvScm, UrlUtil.RemoveScheme(strUrl)); try { Uri uri = new Uri(strUrl); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialScm, uri.Scheme); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialHost, uri.Host); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialPort, uri.Port.ToString()); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialPath, uri.AbsolutePath); str = StrUtil.ReplaceCaseInsensitive(str, UrlSpecialQuery, uri.Query); } catch(Exception) { } // Invalid URI } return str; }
private static string PerformTextTransforms(string strText, SprContext ctx, uint uRecursionLevel) { string str = strText; int iStart; List<string> lParams; while(ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{T-REPLACE-RX:", out iStart, out lParams, true)) { if(lParams.Count < 2) continue; if(lParams.Count == 2) lParams.Add(string.Empty); try { string strNew = Regex.Replace(lParams[0], lParams[1], lParams[2]); strNew = TransformContent(strNew, ctx); str = str.Insert(iStart, strNew); } catch(Exception) { } } while(ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{T-CONV:", out iStart, out lParams, true)) { if(lParams.Count < 2) continue; try { string strNew = lParams[0]; string strCmd = lParams[1].ToLower(); if((strCmd == "u") || (strCmd == "upper")) strNew = strNew.ToUpper(); else if((strCmd == "l") || (strCmd == "lower")) strNew = strNew.ToLower(); else if(strCmd == "base64") { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strNew); strNew = Convert.ToBase64String(pbUtf8); } else if(strCmd == "hex") { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strNew); strNew = MemUtil.ByteArrayToHexString(pbUtf8); } else if(strCmd == "uri") strNew = Uri.EscapeDataString(strNew); else if(strCmd == "uri-dec") strNew = Uri.UnescapeDataString(strNew); strNew = TransformContent(strNew, ctx); str = str.Insert(iStart, strNew); } catch(Exception) { Debug.Assert(false); } } return str; }
private static string PerformTextTransforms(string strText, SprContext ctx, uint uRecursionLevel) { string str = strText; int iStart; List <string> lParams; // {T-CONV:/Text/Raw/} should be the first transformation while (ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{T-CONV:", out iStart, out lParams, true)) { if (lParams.Count < 2) { continue; } try { string strNew = lParams[0]; string strCmd = lParams[1].ToLower(); if ((strCmd == "u") || (strCmd == "upper")) { strNew = strNew.ToUpper(); } else if ((strCmd == "l") || (strCmd == "lower")) { strNew = strNew.ToLower(); } else if (strCmd == "base64") { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strNew); strNew = Convert.ToBase64String(pbUtf8); } else if (strCmd == "hex") { byte[] pbUtf8 = StrUtil.Utf8.GetBytes(strNew); strNew = MemUtil.ByteArrayToHexString(pbUtf8); } else if (strCmd == "uri") { strNew = Uri.EscapeDataString(strNew); } else if (strCmd == "uri-dec") { strNew = Uri.UnescapeDataString(strNew); } // "raw": no modification if (strCmd != "raw") { strNew = TransformContent(strNew, ctx); } str = str.Insert(iStart, strNew); } catch (Exception) { Debug.Assert(false); } } while (ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{T-REPLACE-RX:", out iStart, out lParams, true)) { if (lParams.Count < 2) { continue; } if (lParams.Count == 2) { lParams.Add(string.Empty); } try { string strNew = Regex.Replace(lParams[0], lParams[1], lParams[2]); strNew = TransformContent(strNew, ctx); str = str.Insert(iStart, strNew); } catch (Exception) { } } return(str); }
public static string FillPlaceholders(string strText, SprContext ctx) { return FillPlaceholders(strText, ctx, 0); }
private static string CompileInternal(string strText, SprContext ctx, uint uRecursionLevel) { if (strText == null) { Debug.Assert(false); return(string.Empty); } if (ctx == null) { Debug.Assert(false); ctx = new SprContext(); } if (uRecursionLevel >= SprEngine.MaxRecursionDepth) { Debug.Assert(false); // Most likely a recursive reference return(string.Empty); // Do not return strText (endless loop) } string str = strText; MainForm mf = Program.MainForm; bool bExt = ((ctx.Flags & (SprCompileFlags.ExtActive | SprCompileFlags.ExtNonActive)) != SprCompileFlags.None); if (bExt && (SprEngine.FilterCompilePre != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompilePre(null, args); str = args.Text; } if ((ctx.Flags & SprCompileFlags.Comments) != SprCompileFlags.None) { str = RemoveComments(str); } // The following realizes {T-CONV:/Text/Raw/}, which should be // one of the first transformations (except comments) if ((ctx.Flags & SprCompileFlags.TextTransforms) != SprCompileFlags.None) { str = PerformTextTransforms(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.Run) != SprCompileFlags.None) { str = RunCommands(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.DataActive) != SprCompileFlags.None) { str = PerformClipboardCopy(str, ctx, uRecursionLevel); } if (((ctx.Flags & SprCompileFlags.DataNonActive) != SprCompileFlags.None) && (str.IndexOf(@"{CLIPBOARD}", SprEngine.ScMethod) >= 0)) { string strCb = null; try { strCb = ClipboardUtil.GetText(); } catch (Exception) { Debug.Assert(false); } str = Fill(str, @"{CLIPBOARD}", strCb ?? string.Empty, ctx, null); } if ((ctx.Flags & SprCompileFlags.AppPaths) != SprCompileFlags.None) { str = AppLocator.FillPlaceholders(str, ctx); } if (ctx.Entry != null) { if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) { str = ReplacePickPw(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.EntryStrings) != SprCompileFlags.None) { str = FillEntryStrings(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.EntryStringsSpecial) != SprCompileFlags.None) { str = FillEntryStringsSpecial(str, ctx, uRecursionLevel); } if (((ctx.Flags & SprCompileFlags.EntryProperties) != SprCompileFlags.None) && (str.IndexOf(@"{UUID}", SprEngine.ScMethod) >= 0)) { str = Fill(str, @"{UUID}", ctx.Entry.Uuid.ToHexString(), ctx, null); } if (((ctx.Flags & SprCompileFlags.PasswordEnc) != SprCompileFlags.None) && (str.IndexOf(@"{PASSWORD_ENC}", SprEngine.ScMethod) >= 0)) { string strPwCmp = SprEngine.CompileInternal(@"{PASSWORD}", ctx.WithoutContentTransformations(), uRecursionLevel + 1); str = Fill(str, @"{PASSWORD_ENC}", StrUtil.EncryptString( strPwCmp), ctx, null); } PwGroup pg = ctx.Entry.ParentGroup; if (((ctx.Flags & SprCompileFlags.Group) != SprCompileFlags.None) && (pg != null)) { str = FillGroupPlh(str, @"{GROUP", pg, ctx, uRecursionLevel); } } if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { if (mf != null) { PwGroup pgSel = mf.GetSelectedGroup(); if (pgSel != null) { str = FillGroupPlh(str, @"{GROUP_SEL", pgSel, ctx, uRecursionLevel); } } str = Fill(str, @"{APPDIR}", UrlUtil.GetFileDirectory( WinUtil.GetExecutable(), false, false), ctx, uRecursionLevel); str = Fill(str, @"{ENV_DIRSEP}", Path.DirectorySeparatorChar.ToString(), ctx, null); string strPF86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); if (string.IsNullOrEmpty(strPF86)) { strPF86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); } if (strPF86 != null) { str = Fill(str, @"{ENV_PROGRAMFILES_X86}", strPF86, ctx, uRecursionLevel); } else { Debug.Assert(false); } if (ctx.Database != null) { string strPath = ctx.Database.IOConnectionInfo.Path; string strDir = UrlUtil.GetFileDirectory(strPath, false, false); string strName = UrlUtil.GetFileName(strPath); // For backward compatibility only str = Fill(str, @"{DOCDIR}", strDir, ctx, uRecursionLevel); str = Fill(str, @"{DB_PATH}", strPath, ctx, uRecursionLevel); str = Fill(str, @"{DB_DIR}", strDir, ctx, uRecursionLevel); str = Fill(str, @"{DB_NAME}", strName, ctx, uRecursionLevel); str = Fill(str, @"{DB_BASENAME}", UrlUtil.StripExtension( strName), ctx, uRecursionLevel); str = Fill(str, @"{DB_EXT}", UrlUtil.GetExtension( strPath), ctx, uRecursionLevel); } } if ((ctx.Flags & SprCompileFlags.AutoType) != SprCompileFlags.None) { // Use Bksp instead of Del (in order to avoid Ctrl+Alt+Del); // https://sourceforge.net/p/keepass/discussion/329220/thread/4f1aa6b8/ str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEARFIELD}", @"{HOME}+({END}){BKSP}{DELAY 50}"); } if (((ctx.Flags & SprCompileFlags.DateTime) != SprCompileFlags.None) && (str.IndexOf(@"{DT_", SprEngine.ScMethod) >= 0)) { DateTime dtNow = DateTime.UtcNow; str = Fill(str, @"{DT_UTC_YEAR}", dtNow.Year.ToString("D4"), ctx, null); str = Fill(str, @"{DT_UTC_MONTH}", dtNow.Month.ToString("D2"), ctx, null); str = Fill(str, @"{DT_UTC_DAY}", dtNow.Day.ToString("D2"), ctx, null); str = Fill(str, @"{DT_UTC_HOUR}", dtNow.Hour.ToString("D2"), ctx, null); str = Fill(str, @"{DT_UTC_MINUTE}", dtNow.Minute.ToString("D2"), ctx, null); str = Fill(str, @"{DT_UTC_SECOND}", dtNow.Second.ToString("D2"), ctx, null); str = Fill(str, @"{DT_UTC_SIMPLE}", dtNow.ToString("yyyyMMddHHmmss"), ctx, null); dtNow = dtNow.ToLocalTime(); str = Fill(str, @"{DT_YEAR}", dtNow.Year.ToString("D4"), ctx, null); str = Fill(str, @"{DT_MONTH}", dtNow.Month.ToString("D2"), ctx, null); str = Fill(str, @"{DT_DAY}", dtNow.Day.ToString("D2"), ctx, null); str = Fill(str, @"{DT_HOUR}", dtNow.Hour.ToString("D2"), ctx, null); str = Fill(str, @"{DT_MINUTE}", dtNow.Minute.ToString("D2"), ctx, null); str = Fill(str, @"{DT_SECOND}", dtNow.Second.ToString("D2"), ctx, null); str = Fill(str, @"{DT_SIMPLE}", dtNow.ToString("yyyyMMddHHmmss"), ctx, null); } if ((ctx.Flags & SprCompileFlags.References) != SprCompileFlags.None) { str = SprEngine.FillRefPlaceholders(str, ctx, uRecursionLevel); } if (((ctx.Flags & SprCompileFlags.EnvVars) != SprCompileFlags.None) && (str.IndexOf('%') >= 0)) { foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) { string strKey = (de.Key as string); if (string.IsNullOrEmpty(strKey)) { Debug.Assert(false); continue; } string strValue = (de.Value as string); if (strValue == null) { Debug.Assert(false); strValue = string.Empty; } str = Fill(str, @"%" + strKey + @"%", strValue, ctx, uRecursionLevel); } } if ((ctx.Flags & SprCompileFlags.Env) != SprCompileFlags.None) { str = FillUriSpecial(str, ctx, @"{BASE", (ctx.Base ?? string.Empty), ctx.BaseIsEncoded, uRecursionLevel); } str = EntryUtil.FillPlaceholders(str, ctx, uRecursionLevel); if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) { str = ReplacePickChars(str, ctx, uRecursionLevel); } if (bExt && (SprEngine.FilterCompile != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompile(null, args); str = args.Text; } if (ctx.EncodeAsAutoTypeSequence) { str = StrUtil.NormalizeNewLines(str, false); str = str.Replace("\n", @"{ENTER}"); } return(str); }
private static string GeneratePassword(string strProfile, SprContext ctx) { PwProfile prf = Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile; if(!string.IsNullOrEmpty(strProfile)) { if(strProfile == @"~") prf = PwProfile.DeriveFromPassword(ctx.Entry.Strings.GetSafe( PwDefs.PasswordField)); else { List<PwProfile> lPrf = PwGeneratorUtil.GetAllProfiles(false); foreach(PwProfile p in lPrf) { if(strProfile.Equals(p.Name, StrUtil.CaseIgnoreCmp)) { prf = p; break; } } } } ProtectedString ps; PwgError e = PwGenerator.Generate(out ps, prf, null, Program.PwGeneratorPool); if((e != PwgError.Success) || (ps == null)) return string.Empty; string strGen = ps.ReadString(); strGen = SprEngine.TransformContent(strGen, ctx); return strGen; }
private static string RunCommands(string strText, SprContext ctx, uint uRecursionLevel) { string str = strText; int iStart; List <string> lParams; while (ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, @"{CMD:", out iStart, out lParams, false)) { if (lParams.Count == 0) { continue; } string strBaseRaw = null; if ((ctx != null) && (ctx.Base != null)) { if (ctx.BaseIsEncoded) { strBaseRaw = UntransformContent(ctx.Base, ctx); } else { strBaseRaw = ctx.Base; } } string strCmd = WinUtil.CompileUrl((lParams[0] ?? string.Empty), ((ctx != null) ? ctx.Entry : null), true, strBaseRaw, true); if (WinUtil.IsCommandLineUrl(strCmd)) { strCmd = WinUtil.GetCommandLineFromUrl(strCmd); } if (string.IsNullOrEmpty(strCmd)) { continue; } Process p = null; try { StringComparison sc = StrUtil.CaseIgnoreCmp; string strOpt = ((lParams.Count >= 2) ? lParams[1] : string.Empty); Dictionary <string, string> d = SplitParams(strOpt); ProcessStartInfo psi = new ProcessStartInfo(); string strApp, strArgs; StrUtil.SplitCommandLine(strCmd, out strApp, out strArgs); if (string.IsNullOrEmpty(strApp)) { continue; } psi.FileName = strApp; if (!string.IsNullOrEmpty(strArgs)) { psi.Arguments = strArgs; } string strMethod = GetParam(d, "m", "s"); bool bShellExec = !strMethod.Equals("c", sc); psi.UseShellExecute = bShellExec; string strO = GetParam(d, "o", (bShellExec ? "0" : "1")); bool bStdOut = strO.Equals("1", sc); if (bStdOut) { psi.RedirectStandardOutput = true; } string strWS = GetParam(d, "ws", "n"); if (strWS.Equals("h", sc)) { psi.CreateNoWindow = true; psi.WindowStyle = ProcessWindowStyle.Hidden; } else if (strWS.Equals("min", sc)) { psi.WindowStyle = ProcessWindowStyle.Minimized; } else if (strWS.Equals("max", sc)) { psi.WindowStyle = ProcessWindowStyle.Maximized; } else { Debug.Assert(psi.WindowStyle == ProcessWindowStyle.Normal); } string strVerb = GetParam(d, "v", null); if (!string.IsNullOrEmpty(strVerb)) { psi.Verb = strVerb; } bool bWait = GetParam(d, "w", "1").Equals("1", sc); p = NativeLib.StartProcessEx(psi); if (p == null) { Debug.Assert(false); continue; } if (bStdOut) { string strOut = (p.StandardOutput.ReadToEnd() ?? string.Empty); // Remove trailing new-line characters, like $(...); // https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html // https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html#Command-Substitution strOut = strOut.TrimEnd('\r', '\n'); strOut = TransformContent(strOut, ctx); str = str.Insert(iStart, strOut); } if (bWait) { p.WaitForExit(); } } catch (Exception ex) { string strMsg = strCmd + MessageService.NewParagraph + ex.Message; MessageService.ShowWarning(strMsg); } finally { try { if (p != null) { p.Dispose(); } } catch (Exception) { Debug.Assert(false); } } } return(str); }
private static string ReplaceNewPasswordPlaceholder(string strText, SprContext ctx, uint uRecursionLevel) { PwEntry pe = ctx.Entry; PwDatabase pd = ctx.Database; if((pe == null) || (pd == null)) return strText; string str = strText; const string strNewPwStart = @"{NEWPASSWORD"; if(str.IndexOf(strNewPwStart, StrUtil.CaseIgnoreCmp) < 0) return str; string strGen = null; int iStart; List<string> lParams; while(SprEngine.ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel, strNewPwStart + ":", out iStart, out lParams, true)) { if(strGen == null) strGen = GeneratePassword((((lParams != null) && (lParams.Count > 0)) ? lParams[0] : string.Empty), ctx); str = str.Insert(iStart, strGen); } const string strNewPwPlh = strNewPwStart + @"}"; if(str.IndexOf(strNewPwPlh, StrUtil.CaseIgnoreCmp) >= 0) { if(strGen == null) strGen = GeneratePassword(null, ctx); str = StrUtil.ReplaceCaseInsensitive(str, strNewPwPlh, strGen); } if(strGen != null) { pe.CreateBackup(pd); ProtectedString psGen = new ProtectedString( pd.MemoryProtection.ProtectPassword, strGen); pe.Strings.Set(PwDefs.PasswordField, psGen); pe.Touch(true, false); pd.Modified = true; } else { Debug.Assert(false); } return str; }
public static string TransformContent(string strContent, SprContext ctx) { if(strContent == null) { Debug.Assert(false); return string.Empty; } string str = strContent; if(ctx != null) { if(ctx.EncodeQuotesForCommandLine) str = SprEncoding.MakeCommandQuotes(str); if(ctx.EncodeAsAutoTypeSequence) str = SprEncoding.MakeAutoTypeSequence(str); } return str; }
private static string CompileInternal(string strText, SprContext ctx, uint uRecursionLevel) { if(strText == null) { Debug.Assert(false); return string.Empty; } if(ctx == null) { Debug.Assert(false); ctx = new SprContext(); } if(uRecursionLevel >= SprEngine.MaxRecursionDepth) { Debug.Assert(false); // Most likely a recursive reference return string.Empty; // Do not return strText (endless loop) } string str = strText; bool bExt = ((ctx.Flags & (SprCompileFlags.ExtActive | SprCompileFlags.ExtNonActive)) != SprCompileFlags.None); if(bExt && (SprEngine.FilterCompilePre != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompilePre(null, args); str = args.Text; } if((ctx.Flags & SprCompileFlags.Comments) != SprCompileFlags.None) str = RemoveComments(str); if((ctx.Flags & SprCompileFlags.TextTransforms) != SprCompileFlags.None) str = PerformTextTransforms(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.AppPaths) != SprCompileFlags.None) str = AppLocator.FillPlaceholders(str, ctx); if(ctx.Entry != null) { if((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) str = ReplacePickPw(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.EntryStrings) != SprCompileFlags.None) str = FillEntryStrings(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.EntryStringsSpecial) != SprCompileFlags.None) { // ctx.UrlRemoveSchemeOnce = true; // str = SprEngine.FillIfExists(str, @"{URL:RMVSCM}", // ctx.Entry.Strings.GetSafe(PwDefs.UrlField), ctx, uRecursionLevel); // Debug.Assert(!ctx.UrlRemoveSchemeOnce); str = FillEntryStringsSpecial(str, ctx, uRecursionLevel); } if(((ctx.Flags & SprCompileFlags.PasswordEnc) != SprCompileFlags.None) && (str.IndexOf(@"{PASSWORD_ENC}", SprEngine.ScMethod) >= 0)) { string strPwCmp = SprEngine.FillIfExists(@"{PASSWORD}", @"{PASSWORD}", ctx.Entry.Strings.GetSafe(PwDefs.PasswordField), ctx.WithoutContentTransformations(), uRecursionLevel); str = SprEngine.FillPlaceholder(str, @"{PASSWORD_ENC}", StrUtil.EncryptString(strPwCmp), ctx); } if(((ctx.Flags & SprCompileFlags.Group) != SprCompileFlags.None) && (ctx.Entry.ParentGroup != null)) { str = SprEngine.FillIfExists(str, @"{GROUP}", new ProtectedString( false, ctx.Entry.ParentGroup.Name), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{GROUPPATH}", new ProtectedString( false, ctx.Entry.ParentGroup.GetFullPath()), ctx, uRecursionLevel); } } if((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) str = SprEngine.FillIfExists(str, @"{APPDIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(m_strAppExePath, false, false)), ctx, uRecursionLevel); if(ctx.Database != null) { if((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { // For backward compatibility only str = SprEngine.FillIfExists(str, @"{DOCDIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path, false, false)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_PATH}", new ProtectedString( false, ctx.Database.IOConnectionInfo.Path), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_DIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path, false, false)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_NAME}", new ProtectedString( false, UrlUtil.GetFileName(ctx.Database.IOConnectionInfo.Path)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_BASENAME}", new ProtectedString( false, UrlUtil.StripExtension(UrlUtil.GetFileName( ctx.Database.IOConnectionInfo.Path))), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_EXT}", new ProtectedString( false, UrlUtil.GetExtension(ctx.Database.IOConnectionInfo.Path)), ctx, uRecursionLevel); } } if((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { str = SprEngine.FillIfExists(str, @"{ENV_DIRSEP}", new ProtectedString( false, Path.DirectorySeparatorChar.ToString()), ctx, uRecursionLevel); string strPF86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); if(string.IsNullOrEmpty(strPF86)) strPF86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); if(strPF86 != null) str = SprEngine.FillIfExists(str, @"{ENV_PROGRAMFILES_X86}", new ProtectedString(false, strPF86), ctx, uRecursionLevel); else { Debug.Assert(false); } } if((ctx.Flags & SprCompileFlags.AutoType) != SprCompileFlags.None) { // Use Bksp instead of Del (in order to avoid Ctrl+Alt+Del); // https://sourceforge.net/p/keepass/discussion/329220/thread/4f1aa6b8/ str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEARFIELD}", @"{HOME}+({END}){BKSP}{DELAY 50}"); } if((ctx.Flags & SprCompileFlags.DateTime) != SprCompileFlags.None) { DateTime dtNow = DateTime.Now; // Local time str = SprEngine.FillIfExists(str, @"{DT_YEAR}", new ProtectedString( false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_MONTH}", new ProtectedString( false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_DAY}", new ProtectedString( false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_HOUR}", new ProtectedString( false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_MINUTE}", new ProtectedString( false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_SECOND}", new ProtectedString( false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_SIMPLE}", new ProtectedString( false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel); dtNow = dtNow.ToUniversalTime(); str = SprEngine.FillIfExists(str, @"{DT_UTC_YEAR}", new ProtectedString( false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_MONTH}", new ProtectedString( false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_DAY}", new ProtectedString( false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_HOUR}", new ProtectedString( false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_MINUTE}", new ProtectedString( false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_SECOND}", new ProtectedString( false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_SIMPLE}", new ProtectedString( false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel); } if((ctx.Flags & SprCompileFlags.References) != SprCompileFlags.None) str = SprEngine.FillRefPlaceholders(str, ctx, uRecursionLevel); if(((ctx.Flags & SprCompileFlags.EnvVars) != SprCompileFlags.None) && (str.IndexOf('%') >= 0)) { // Replace environment variables foreach(DictionaryEntry de in Environment.GetEnvironmentVariables()) { string strKey = (de.Key as string); string strValue = (de.Value as string); if((strKey != null) && (strValue != null)) str = SprEngine.FillIfExists(str, @"%" + strKey + @"%", new ProtectedString(false, strValue), ctx, uRecursionLevel); else { Debug.Assert(false); } } } if((ctx.Flags & SprCompileFlags.Env) != SprCompileFlags.None) str = FillUriSpecial(str, ctx, @"{BASE", (ctx.Base ?? string.Empty), ctx.BaseIsEncoded, uRecursionLevel); str = EntryUtil.FillPlaceholders(str, ctx, uRecursionLevel); if((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) str = ReplacePickChars(str, ctx, uRecursionLevel); if(bExt && (SprEngine.FilterCompile != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompile(null, args); str = args.Text; } if(ctx.EncodeAsAutoTypeSequence) { str = StrUtil.NormalizeNewLines(str, false); str = str.Replace("\n", @"{ENTER}"); } return str; }
private static string FillEntryStringsSpecial(string str, SprContext ctx, uint uRecursionLevel) { return FillUriSpecial(str, ctx, @"{URL", ctx.Entry.Strings.ReadSafe( PwDefs.UrlField), false, uRecursionLevel); }
private static string FillPlaceholder(string strData, string strPlaceholder, string strReplaceWith, SprContext ctx) { if(strData == null) { Debug.Assert(false); return string.Empty; } if(strPlaceholder == null) { Debug.Assert(false); return strData; } if(strPlaceholder.Length == 0) { Debug.Assert(false); return strData; } if(strReplaceWith == null) { Debug.Assert(false); return strData; } return StrUtil.ReplaceCaseInsensitive(strData, strPlaceholder, SprEngine.TransformContent(strReplaceWith, ctx)); }
private static string ReplacePickChars(string strText, SprContext ctx, uint uRecursionLevel) { if (ctx.Entry == null) { return(strText); // No assert } string str = strText; Dictionary <string, string> dPicked = new Dictionary <string, string>(); while (true) { const string strStart = @"{PICKCHARS"; int iStart = str.IndexOf(strStart, StrUtil.CaseIgnoreCmp); if (iStart < 0) { break; } int iEnd = str.IndexOf('}', iStart); if (iEnd < 0) { break; } string strPlaceholder = str.Substring(iStart, iEnd - iStart + 1); string strParam = str.Substring(iStart + strStart.Length, iEnd - (iStart + strStart.Length)); string strRep = string.Empty; bool bEncode = true; if (strParam.Length == 0) { strRep = ShowCharPickDlg(ctx.Entry.Strings.ReadSafe( PwDefs.PasswordField), 0, null, ctx, uRecursionLevel); } else if (strParam.StartsWith(":")) { string strParams = strParam.Substring(1); string[] vParams = strParams.Split(new char[] { ':' }, StringSplitOptions.None); string strField = string.Empty; if (vParams.Length >= 1) { strField = (vParams[0] ?? string.Empty).Trim(); } if (strField.Length == 0) { strField = PwDefs.PasswordField; } string strOptions = string.Empty; if (vParams.Length >= 2) { strOptions = (vParams[1] ?? string.Empty); } Dictionary <string, string> dOptions = new Dictionary <string, string>(); string[] vOptions = strOptions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string strOption in vOptions) { string[] vKvp = strOption.Split(new char[] { '=' }, StringSplitOptions.None); if (vKvp.Length != 2) { continue; } dOptions[vKvp[0].Trim().ToLower()] = vKvp[1].Trim(); } string strID = string.Empty; if (dOptions.ContainsKey("id")) { strID = dOptions["id"].ToLower(); } uint uCharCount = 0; if (dOptions.ContainsKey("c")) { uint.TryParse(dOptions["c"], out uCharCount); } if (dOptions.ContainsKey("count")) { uint.TryParse(dOptions["count"], out uCharCount); } bool?bInitHide = null; if (dOptions.ContainsKey("hide")) { bInitHide = StrUtil.StringToBool(dOptions["hide"]); } string strContent = ctx.Entry.Strings.ReadSafe(strField); if (strContent.Length == 0) { } // Leave strRep empty else if ((strID.Length > 0) && dPicked.ContainsKey(strID)) { strRep = dPicked[strID]; } else { strRep = ShowCharPickDlg(strContent, uCharCount, bInitHide, ctx, uRecursionLevel); } if (strID.Length > 0) { dPicked[strID] = strRep; } if (dOptions.ContainsKey("conv")) { int iOffset = 0; if (dOptions.ContainsKey("conv-offset")) { int.TryParse(dOptions["conv-offset"], out iOffset); } string strConvFmt = string.Empty; if (dOptions.ContainsKey("conv-fmt")) { strConvFmt = dOptions["conv-fmt"]; } string strConv = dOptions["conv"]; if (strConv.Equals("d", StrUtil.CaseIgnoreCmp)) { strRep = ConvertToDownArrows(strRep, iOffset, strConvFmt); bEncode = false; } } } str = StrUtil.ReplaceCaseInsensitive(str, strPlaceholder, bEncode ? SprEngine.TransformContent(strRep, ctx) : strRep); } return(str); }
private static string FillEntryStrings(string str, SprContext ctx, uint uRecursionLevel) { List<string> vKeys = ctx.Entry.Strings.GetKeys(); // Ensure that all standard field names are in the list // (this is required in order to replace the standard placeholders // even if the corresponding standard field isn't present in // the entry) List<string> vStdNames = PwDefs.GetStandardFields(); foreach(string strStdField in vStdNames) { if(!vKeys.Contains(strStdField)) vKeys.Add(strStdField); } // Do not directly enumerate the strings in ctx.Entry.Strings, // because strings might change during the Spr compilation foreach(string strField in vKeys) { string strKey = (PwDefs.IsStandardField(strField) ? (@"{" + strField + @"}") : (@"{" + PwDefs.AutoTypeStringPrefix + strField + @"}")); if(!ctx.ForcePlainTextPasswords && strKey.Equals(@"{" + PwDefs.PasswordField + @"}", StrUtil.CaseIgnoreCmp) && Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password)) { str = SprEngine.FillIfExists(str, strKey, new ProtectedString( false, PwDefs.HiddenPassword), ctx, uRecursionLevel); continue; } // Use GetSafe because the field doesn't necessarily exist // (might be a standard field that has been added above) str = SprEngine.FillIfExists(str, strKey, ctx.Entry.Strings.GetSafe( strField), ctx, uRecursionLevel); } return str; }
private static string FillEntryStringsSpecial(string str, SprContext ctx, uint uRecursionLevel) { return(FillUriSpecial(str, ctx, @"{URL", ctx.Entry.Strings.ReadSafe( PwDefs.UrlField), false, uRecursionLevel)); }
private static string FillUriSpecial(string strText, SprContext ctx, string strPlhInit, string strData, bool bDataIsEncoded, uint uRecursionLevel) { Debug.Assert(strPlhInit.StartsWith(@"{") && !strPlhInit.EndsWith(@"}")); Debug.Assert(strData != null); string[] vPlhs = new string[] { strPlhInit + @"}", strPlhInit + @":RMVSCM}", strPlhInit + @":SCM}", strPlhInit + @":HOST}", strPlhInit + @":PORT}", strPlhInit + @":PATH}", strPlhInit + @":QUERY}", strPlhInit + @":USERINFO}", strPlhInit + @":USERNAME}", strPlhInit + @":PASSWORD}" }; string str = strText; string strDataCmp = null; Uri uri = null; for(int i = 0; i < vPlhs.Length; ++i) { string strPlh = vPlhs[i]; if(str.IndexOf(strPlh, SprEngine.ScMethod) < 0) continue; if(strDataCmp == null) { SprContext ctxData = (bDataIsEncoded ? ctx.WithoutContentTransformations() : ctx); strDataCmp = SprEngine.CompileInternal(strData, ctxData, uRecursionLevel + 1); } string strRep = null; if(i == 0) strRep = strDataCmp; else if(i == 1) strRep = UrlUtil.RemoveScheme(strDataCmp); else { try { if(uri == null) uri = new Uri(strDataCmp); int t; switch(i) { case 2: strRep = uri.Scheme; break; case 3: strRep = uri.Host; break; case 4: strRep = uri.Port.ToString( NumberFormatInfo.InvariantInfo); break; case 5: strRep = uri.AbsolutePath; break; case 6: strRep = uri.Query; break; case 7: strRep = uri.UserInfo; break; case 8: strRep = uri.UserInfo; t = strRep.IndexOf(':'); if(t >= 0) strRep = strRep.Substring(0, t); break; case 9: strRep = uri.UserInfo; t = strRep.IndexOf(':'); if(t < 0) strRep = string.Empty; else strRep = strRep.Substring(t + 1); break; default: Debug.Assert(false); break; } } catch(Exception) { } // Invalid URI } if(strRep == null) strRep = string.Empty; // No assert str = StrUtil.ReplaceCaseInsensitive(str, strPlh, strRep); } return str; }
private static string CompileInternal(string strText, SprContext ctx, uint uRecursionLevel) { if (strText == null) { Debug.Assert(false); return(string.Empty); } if (ctx == null) { Debug.Assert(false); ctx = new SprContext(); } if (uRecursionLevel >= SprEngine.MaxRecursionDepth) { Debug.Assert(false); // Most likely a recursive reference return(string.Empty); // Do not return strText (endless loop) } string str = strText; bool bExt = ((ctx.Flags & (SprCompileFlags.ExtActive | SprCompileFlags.ExtNonActive)) != SprCompileFlags.None); if (bExt && (SprEngine.FilterCompilePre != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompilePre(null, args); str = args.Text; } if ((ctx.Flags & SprCompileFlags.Comments) != SprCompileFlags.None) { str = RemoveComments(str); } if ((ctx.Flags & SprCompileFlags.TextTransforms) != SprCompileFlags.None) { str = PerformTextTransforms(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.AppPaths) != SprCompileFlags.None) { str = AppLocator.FillPlaceholders(str, ctx); } if (ctx.Entry != null) { if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) { str = ReplacePickPw(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.EntryStrings) != SprCompileFlags.None) { str = FillEntryStrings(str, ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.EntryStringsSpecial) != SprCompileFlags.None) { // ctx.UrlRemoveSchemeOnce = true; // str = SprEngine.FillIfExists(str, @"{URL:RMVSCM}", // ctx.Entry.Strings.GetSafe(PwDefs.UrlField), ctx, uRecursionLevel); // Debug.Assert(!ctx.UrlRemoveSchemeOnce); str = FillEntryStringsSpecial(str, ctx, uRecursionLevel); } if (((ctx.Flags & SprCompileFlags.PasswordEnc) != SprCompileFlags.None) && (str.IndexOf(@"{PASSWORD_ENC}", SprEngine.ScMethod) >= 0)) { string strPwCmp = SprEngine.FillIfExists(@"{PASSWORD}", @"{PASSWORD}", ctx.Entry.Strings.GetSafe(PwDefs.PasswordField), ctx.WithoutContentTransformations(), uRecursionLevel); str = SprEngine.FillPlaceholder(str, @"{PASSWORD_ENC}", StrUtil.EncryptString(strPwCmp), ctx); } if (((ctx.Flags & SprCompileFlags.Group) != SprCompileFlags.None) && (ctx.Entry.ParentGroup != null)) { str = SprEngine.FillIfExists(str, @"{GROUP}", new ProtectedString( false, ctx.Entry.ParentGroup.Name), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{GROUPPATH}", new ProtectedString( false, ctx.Entry.ParentGroup.GetFullPath()), ctx, uRecursionLevel); } } if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { str = SprEngine.FillIfExists(str, @"{APPDIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(m_strAppExePath, false, false)), ctx, uRecursionLevel); } if (ctx.Database != null) { if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { // For backward compatibility only str = SprEngine.FillIfExists(str, @"{DOCDIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path, false, false)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_PATH}", new ProtectedString( false, ctx.Database.IOConnectionInfo.Path), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_DIR}", new ProtectedString( false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path, false, false)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_NAME}", new ProtectedString( false, UrlUtil.GetFileName(ctx.Database.IOConnectionInfo.Path)), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_BASENAME}", new ProtectedString( false, UrlUtil.StripExtension(UrlUtil.GetFileName( ctx.Database.IOConnectionInfo.Path))), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DB_EXT}", new ProtectedString( false, UrlUtil.GetExtension(ctx.Database.IOConnectionInfo.Path)), ctx, uRecursionLevel); } } if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None) { str = SprEngine.FillIfExists(str, @"{ENV_DIRSEP}", new ProtectedString( false, Path.DirectorySeparatorChar.ToString()), ctx, uRecursionLevel); string strPF86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); if (string.IsNullOrEmpty(strPF86)) { strPF86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); } if (strPF86 != null) { str = SprEngine.FillIfExists(str, @"{ENV_PROGRAMFILES_X86}", new ProtectedString(false, strPF86), ctx, uRecursionLevel); } else { Debug.Assert(false); } } if ((ctx.Flags & SprCompileFlags.AutoType) != SprCompileFlags.None) { // Use Bksp instead of Del (in order to avoid Ctrl+Alt+Del); // https://sourceforge.net/p/keepass/discussion/329220/thread/4f1aa6b8/ str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEARFIELD}", @"{HOME}+({END}){BKSP}{DELAY 50}"); } if ((ctx.Flags & SprCompileFlags.DateTime) != SprCompileFlags.None) { DateTime dtNow = DateTime.Now; // Local time str = SprEngine.FillIfExists(str, @"{DT_YEAR}", new ProtectedString( false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_MONTH}", new ProtectedString( false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_DAY}", new ProtectedString( false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_HOUR}", new ProtectedString( false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_MINUTE}", new ProtectedString( false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_SECOND}", new ProtectedString( false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_SIMPLE}", new ProtectedString( false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel); dtNow = dtNow.ToUniversalTime(); str = SprEngine.FillIfExists(str, @"{DT_UTC_YEAR}", new ProtectedString( false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_MONTH}", new ProtectedString( false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_DAY}", new ProtectedString( false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_HOUR}", new ProtectedString( false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_MINUTE}", new ProtectedString( false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_SECOND}", new ProtectedString( false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel); str = SprEngine.FillIfExists(str, @"{DT_UTC_SIMPLE}", new ProtectedString( false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel); } if ((ctx.Flags & SprCompileFlags.References) != SprCompileFlags.None) { str = SprEngine.FillRefPlaceholders(str, ctx, uRecursionLevel); } if (((ctx.Flags & SprCompileFlags.EnvVars) != SprCompileFlags.None) && (str.IndexOf('%') >= 0)) { // Replace environment variables foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) { string strKey = (de.Key as string); string strValue = (de.Value as string); if ((strKey != null) && (strValue != null)) { str = SprEngine.FillIfExists(str, @"%" + strKey + @"%", new ProtectedString(false, strValue), ctx, uRecursionLevel); } else { Debug.Assert(false); } } } if ((ctx.Flags & SprCompileFlags.Env) != SprCompileFlags.None) { str = FillUriSpecial(str, ctx, @"{BASE", (ctx.Base ?? string.Empty), ctx.BaseIsEncoded, uRecursionLevel); } str = EntryUtil.FillPlaceholders(str, ctx, uRecursionLevel); if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None) { str = ReplacePickChars(str, ctx, uRecursionLevel); } if (bExt && (SprEngine.FilterCompile != null)) { SprEventArgs args = new SprEventArgs(str, ctx.Clone()); SprEngine.FilterCompile(null, args); str = args.Text; } if (ctx.EncodeAsAutoTypeSequence) { str = StrUtil.NormalizeNewLines(str, false); str = str.Replace("\n", @"{ENTER}"); } return(str); }
public static PwEntry FindRefTarget(string strFullRef, SprContext ctx, out char chScan, out char chWanted) { chScan = char.MinValue; chWanted = char.MinValue; if(strFullRef == null) { Debug.Assert(false); return null; } if(!strFullRef.StartsWith(StrRefStart, SprEngine.ScMethod) || !strFullRef.EndsWith(StrRefEnd, SprEngine.ScMethod)) return null; if((ctx == null) || (ctx.Database == null)) { Debug.Assert(false); return null; } string strRef = strFullRef.Substring(StrRefStart.Length, strFullRef.Length - StrRefStart.Length - StrRefEnd.Length); if(strRef.Length <= 4) return null; if(strRef[1] != '@') return null; if(strRef[3] != ':') return null; chScan = char.ToUpper(strRef[2]); chWanted = char.ToUpper(strRef[0]); SearchParameters sp = SearchParameters.None; sp.SearchString = strRef.Substring(4); sp.RespectEntrySearchingDisabled = false; if(chScan == 'T') sp.SearchInTitles = true; else if(chScan == 'U') sp.SearchInUserNames = true; else if(chScan == 'A') sp.SearchInUrls = true; else if(chScan == 'P') sp.SearchInPasswords = true; else if(chScan == 'N') sp.SearchInNotes = true; else if(chScan == 'I') sp.SearchInUuids = true; else if(chScan == 'O') sp.SearchInOther = true; else return null; PwObjectList<PwEntry> lFound = new PwObjectList<PwEntry>(); ctx.Database.RootGroup.SearchEntries(sp, lFound); return ((lFound.UCount > 0) ? lFound.GetAt(0) : null); }
private static string FillRefPlaceholders(string strSeq, SprContext ctx, uint uRecursionLevel) { if (ctx.Database == null) { return(strSeq); } string str = strSeq; int nOffset = 0; for (int iLoop = 0; iLoop < 20; ++iLoop) { str = ctx.RefCache.Fill(str, ctx); int nStart = str.IndexOf(StrRefStart, nOffset, SprEngine.ScMethod); if (nStart < 0) { break; } int nEnd = str.IndexOf(StrRefEnd, nStart + 1, SprEngine.ScMethod); if (nEnd <= nStart) { break; } string strFullRef = str.Substring(nStart, nEnd - nStart + 1); char chScan, chWanted; PwEntry peFound = FindRefTarget(strFullRef, ctx, out chScan, out chWanted); if (peFound != null) { string strInsData; if (chWanted == 'T') { strInsData = peFound.Strings.ReadSafe(PwDefs.TitleField); } else if (chWanted == 'U') { strInsData = peFound.Strings.ReadSafe(PwDefs.UserNameField); } else if (chWanted == 'A') { strInsData = peFound.Strings.ReadSafe(PwDefs.UrlField); } else if (chWanted == 'P') { strInsData = peFound.Strings.ReadSafe(PwDefs.PasswordField); } else if (chWanted == 'N') { strInsData = peFound.Strings.ReadSafe(PwDefs.NotesField); } else if (chWanted == 'I') { strInsData = peFound.Uuid.ToHexString(); } else { nOffset = nStart + 1; continue; } if ((chWanted == 'P') && !ctx.ForcePlainTextPasswords && Program.Config.MainWindow.IsColumnHidden(AceColumnType.Password)) { strInsData = PwDefs.HiddenPassword; } SprContext sprSub = ctx.WithoutContentTransformations(); sprSub.Entry = peFound; string strInnerContent = SprEngine.CompileInternal(strInsData, sprSub, uRecursionLevel + 1); strInnerContent = SprEngine.TransformContent(strInnerContent, ctx); // str = str.Substring(0, nStart) + strInnerContent + str.Substring(nEnd + 1); ctx.RefCache.Add(strFullRef, strInnerContent, ctx); str = ctx.RefCache.Fill(str, ctx); } else { nOffset = nStart + 1; continue; } } return(str); }
private static void AddRefToCache(string strRef, string strValue, SprContext ctx) { if(strRef == null) { Debug.Assert(false); return; } if(strValue == null) { Debug.Assert(false); return; } if(ctx == null) { Debug.Assert(false); return; } // Only add if not exists, do not overwrite if(!ctx.RefsCache.ContainsKey(strRef)) ctx.RefsCache.Add(strRef, strValue); }
public static PwEntry FindRefTarget(string strFullRef, SprContext ctx, out char chScan, out char chWanted) { chScan = char.MinValue; chWanted = char.MinValue; if (strFullRef == null) { Debug.Assert(false); return(null); } if (!strFullRef.StartsWith(StrRefStart, SprEngine.ScMethod) || !strFullRef.EndsWith(StrRefEnd, SprEngine.ScMethod)) { return(null); } if ((ctx == null) || (ctx.Database == null)) { Debug.Assert(false); return(null); } string strRef = strFullRef.Substring(StrRefStart.Length, strFullRef.Length - StrRefStart.Length - StrRefEnd.Length); if (strRef.Length <= 4) { return(null); } if (strRef[1] != '@') { return(null); } if (strRef[3] != ':') { return(null); } chScan = char.ToUpper(strRef[2]); chWanted = char.ToUpper(strRef[0]); SearchParameters sp = SearchParameters.None; sp.SearchString = strRef.Substring(4); sp.RespectEntrySearchingDisabled = false; if (chScan == 'T') { sp.SearchInTitles = true; } else if (chScan == 'U') { sp.SearchInUserNames = true; } else if (chScan == 'A') { sp.SearchInUrls = true; } else if (chScan == 'P') { sp.SearchInPasswords = true; } else if (chScan == 'N') { sp.SearchInNotes = true; } else if (chScan == 'I') { sp.SearchInUuids = true; } else if (chScan == 'O') { sp.SearchInOther = true; } else { return(null); } PwObjectList <PwEntry> lFound = new PwObjectList <PwEntry>(); ctx.Database.RootGroup.SearchEntries(sp, lFound); return((lFound.UCount > 0) ? lFound.GetAt(0) : null); }
/// <summary> /// Parse and remove a placeholder of the form /// <c>{PLH:/Param1/Param2/.../}</c>. /// </summary> internal static bool ParseAndRemovePlhWithParams(ref string str, SprContext ctx, uint uRecursionLevel, string strPlhStart, out int iStart, out List<string> lParams, bool bSprCmpParams) { Debug.Assert(strPlhStart.StartsWith(@"{") && !strPlhStart.EndsWith(@"}")); iStart = str.IndexOf(strPlhStart, StrUtil.CaseIgnoreCmp); if(iStart < 0) { lParams = null; return false; } lParams = new List<string>(); try { int p = iStart + strPlhStart.Length; if(p >= str.Length) throw new FormatException(); char chSep = str[p]; while(true) { if((p + 1) >= str.Length) throw new FormatException(); if(str[p + 1] == '}') break; int q = str.IndexOf(chSep, p + 1); if(q < 0) throw new FormatException(); lParams.Add(str.Substring(p + 1, q - p - 1)); p = q; } Debug.Assert(str[p + 1] == '}'); str = str.Remove(iStart, (p + 1) - iStart + 1); } catch(Exception) { str = str.Substring(0, iStart); } if(bSprCmpParams && (ctx != null)) { SprContext ctxSub = ctx.WithoutContentTransformations(); for(int i = 0; i < lParams.Count; ++i) lParams[i] = CompileInternal(lParams[i], ctxSub, uRecursionLevel); } return true; }
/// <summary> /// Parse and remove a placeholder of the form /// <c>{PLH:/Param1/Param2/.../}</c>. /// </summary> internal static bool ParseAndRemovePlhWithParams(ref string str, SprContext ctx, uint uRecursionLevel, string strPlhStart, out int iStart, out List <string> lParams, bool bSprCmpParams) { Debug.Assert(strPlhStart.StartsWith(@"{") && !strPlhStart.EndsWith(@"}")); iStart = str.IndexOf(strPlhStart, SprEngine.ScMethod); if (iStart < 0) { lParams = null; return(false); } lParams = new List <string>(); try { int p = iStart + strPlhStart.Length; if (p >= str.Length) { throw new FormatException(); } char chSep = str[p]; while (true) { if ((p + 1) >= str.Length) { throw new FormatException(); } if (str[p + 1] == '}') { break; } int q = str.IndexOf(chSep, p + 1); if (q < 0) { throw new FormatException(); } lParams.Add(str.Substring(p + 1, q - p - 1)); p = q; } Debug.Assert(str[p + 1] == '}'); str = str.Remove(iStart, (p + 1) - iStart + 1); } catch (Exception) { str = str.Substring(0, iStart); } if (bSprCmpParams && (ctx != null)) { SprContext ctxSub = ctx.WithoutContentTransformations(); for (int i = 0; i < lParams.Count; ++i) { lParams[i] = CompileInternal(lParams[i], ctxSub, uRecursionLevel); } } return(true); }
private static string FillUriSpecial(string strText, SprContext ctx, string strPlhInit, string strData, bool bDataIsEncoded, uint uRecursionLevel) { Debug.Assert(strPlhInit.StartsWith(@"{") && !strPlhInit.EndsWith(@"}")); Debug.Assert(strData != null); string[] vPlhs = new string[] { strPlhInit + @"}", strPlhInit + @":RMVSCM}", strPlhInit + @":SCM}", strPlhInit + @":HOST}", strPlhInit + @":PORT}", strPlhInit + @":PATH}", strPlhInit + @":QUERY}", strPlhInit + @":USERINFO}", strPlhInit + @":USERNAME}", strPlhInit + @":PASSWORD}" }; string str = strText; string strDataCmp = null; Uri uri = null; for (int i = 0; i < vPlhs.Length; ++i) { string strPlh = vPlhs[i]; if (str.IndexOf(strPlh, SprEngine.ScMethod) < 0) { continue; } if (strDataCmp == null) { SprContext ctxData = (bDataIsEncoded ? ctx.WithoutContentTransformations() : ctx); strDataCmp = SprEngine.CompileInternal(strData, ctxData, uRecursionLevel + 1); } string strRep = null; if (i == 0) { strRep = strDataCmp; } // UrlUtil supports prefixes like cmd:// else if (i == 1) { strRep = UrlUtil.RemoveScheme(strDataCmp); } else if (i == 2) { strRep = UrlUtil.GetScheme(strDataCmp); } else { try { if (uri == null) { uri = new Uri(strDataCmp); } int t; switch (i) { // case 2: strRep = uri.Scheme; break; // No cmd:// support case 3: strRep = uri.Host; break; case 4: strRep = uri.Port.ToString( NumberFormatInfo.InvariantInfo); break; case 5: strRep = uri.AbsolutePath; break; case 6: strRep = uri.Query; break; case 7: strRep = uri.UserInfo; break; case 8: strRep = uri.UserInfo; t = strRep.IndexOf(':'); if (t >= 0) { strRep = strRep.Substring(0, t); } break; case 9: strRep = uri.UserInfo; t = strRep.IndexOf(':'); if (t < 0) { strRep = string.Empty; } else { strRep = strRep.Substring(t + 1); } break; default: Debug.Assert(false); break; } } catch (Exception) { } // Invalid URI } if (strRep == null) { strRep = string.Empty; // No assert } str = StrUtil.ReplaceCaseInsensitive(str, strPlh, strRep); } return(str); }
public static void Highlight(RichTextBox rtb, SprContext ctx) { try { HighlightPriv(rtb, ctx); } catch (Exception) { Debug.Assert(false); } }