From 32b72c1aa7b4d665d85a2c9bcda350da8a056412 Mon Sep 17 00:00:00 2001 From: Nilesh Ghodekar Date: Thu, 23 Jul 2020 14:23:39 +0100 Subject: [PATCH] Regression Bug fix: RunPowerShellScript activity fails to parse PowerShell user password as the ParseIfExpression check leads to an exception if the password is not a WAL expression. --- src/Scripts/EncryptData.ps1 | 13 +++--- src/VersionInfo.cs | 4 +- .../Common/ExpressionEvaluator.cs | 44 +++++++++++++++++-- .../Common/ExpressionFunction.cs | 3 +- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/Scripts/EncryptData.ps1 b/src/Scripts/EncryptData.ps1 index f2cfb0c..b59e4c9 100644 --- a/src/Scripts/EncryptData.ps1 +++ b/src/Scripts/EncryptData.ps1 @@ -8,9 +8,10 @@ NOTE: Edit the Version and PublicKeyToken of the WAL AssemblyName to match the one that you have deployed in GAC. Also edit the $encryptionCertThumbprint of cert to be used for certificate based encryption. - Finding Assembly verion and PublicKeyToken - gacutil.exe -l | findstr WorkflowActivityLibrary - Creatinig a self signed certificate for MIMWAL (You can use a legacy CSP such as Microsoft Strong Cryptographic Provider as shown in the example below) + To find Assembly verion and PublicKeyToken + .\gacutil.exe -l | findstr WorkflowActivityLibrary + To create a self-signed certificate for MIMWAL, you must use a legacy CSP (as .NET 3.5 only supports legacy CSPs). + You can use a legacy CSP such as Microsoft Strong Cryptographic Provider as shown in the example below: $cert = New-SelfSignedCertificate -DnsName "MIMWAL Encryption (Do Not Delete)" -CertStoreLocation "cert:\LocalMachine\My" -Provider "Microsoft Strong Cryptographic Provider" -NotAfter (Get-Date).AddYears(20) $cert.Thumbprint As of version v2.18.1110.0, only FIMService account needs read access to the private key of the MIMWAL certificate created above. @@ -18,9 +19,9 @@ $Error.Clear() -$walAssemblyVersion = "2.20.0523.0" -$walAssemblyPublicKeyToken = "31bf3856ad364e35" -$encryptionCertThumbprint = "9C697919FB2FB2D6324ADE42D5F8CB49E8778C08" # cert to be used for encryption (from the cert:\localmachine\my\ store). +$walAssemblyVersion = "2.20.0723.0" # edit appropriately +$walAssemblyPublicKeyToken = "31bf3856ad364e35" # edit appropriately +$encryptionCertThumbprint = "9C697919FB2FB2D6324ADE42D5F8CB49E8778C08" # cert to be used for encryption (from the cert:\localmachine\my\ store). Edit appropriately Add-Type -AssemblyName "System.Security" # use the full name for WAL assembly to eliminate need to assembly redirects for dependent assemblies. diff --git a/src/VersionInfo.cs b/src/VersionInfo.cs index 08db16d..1fa222a 100644 --- a/src/VersionInfo.cs +++ b/src/VersionInfo.cs @@ -22,7 +22,7 @@ internal static class VersionInfo /// Build Number (MMDD) /// Revision (if any on the same day) /// - internal const string Version = "2.20.0523.0"; + internal const string Version = "2.20.0723.0"; /// /// File Version information for the assembly consists of the following four values: @@ -31,6 +31,6 @@ internal static class VersionInfo /// Build Number (MMDD) /// Revision (if any on the same day) /// - internal const string FileVersion = "2.20.0523.0"; + internal const string FileVersion = "2.20.0723.0"; } } \ No newline at end of file diff --git a/src/WorkflowActivityLibrary/Common/ExpressionEvaluator.cs b/src/WorkflowActivityLibrary/Common/ExpressionEvaluator.cs index 2295e06..0a35f6c 100644 --- a/src/WorkflowActivityLibrary/Common/ExpressionEvaluator.cs +++ b/src/WorkflowActivityLibrary/Common/ExpressionEvaluator.cs @@ -109,9 +109,18 @@ public static ParameterType DetermineParameterType(string parameter, bool suppre // Function: contains ( and ends with ) // Lookup: starts with [// and ends with ] // Variable: starts with $ and does not contain invalid characters - if (IdentifyExpressionComponents(parameter).Count > 1) + ArrayList components = IdentifyExpressionComponents(parameter, suppressValidationError); + if (components.Count > 1) { parameterType = ParameterType.Expression; + foreach (string component in components) + { + if (DetermineParameterType(component, suppressValidationError) == ParameterType.Unknown) + { + parameterType = ParameterType.Unknown; + break; + } + } } else if (long.TryParse(parameter, out parseInteger)) { @@ -449,8 +458,9 @@ public void PublishVariable(string variable, object value, UpdateMode mode) /// Identifies the expression components. /// /// The expression. + /// Indicates whether to suppress the validation error or not. /// The ArrayList of expression components. - private static ArrayList IdentifyExpressionComponents(string expression) + private static ArrayList IdentifyExpressionComponents(string expression, bool suppressValidationError) { Logger.Instance.WriteMethodEntry(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponents, "Expression: '{0}'.", expression); @@ -484,12 +494,28 @@ private static ArrayList IdentifyExpressionComponents(string expression) // parentheses characters do not match, throw an exception if (openString) { - throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponentsQuotesValidationError, new InvalidExpressionException(Messages.ExpressionEvaluator_ExpressionQuotesValidationError, expression)); + if (suppressValidationError) + { + Logger.Instance.WriteVerbose(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponentsQuotesValidationError, Messages.ExpressionEvaluator_ExpressionQuotesValidationError, expression); + return components; + } + else + { + throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponentsQuotesValidationError, new InvalidExpressionException(Messages.ExpressionEvaluator_ExpressionQuotesValidationError, expression)); + } } if (openFunctions != 0) { - throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponentsParenthesisValidationError, new InvalidExpressionException(Messages.ExpressionEvaluator_ExpressionParenthesisValidationError, expression)); + if (suppressValidationError) + { + Logger.Instance.WriteVerbose(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponentsParenthesisValidationError, Messages.ExpressionEvaluator_ExpressionParenthesisValidationError, expression); + return components; + } + else + { + throw Logger.Instance.ReportError(EventIdentifier.ExpressionEvaluatorIdentifyExpressionComponentsParenthesisValidationError, new InvalidExpressionException(Messages.ExpressionEvaluator_ExpressionParenthesisValidationError, expression)); + } } // The function expression could contain + characters which are wrapped in quotations @@ -546,6 +572,16 @@ private static ArrayList IdentifyExpressionComponents(string expression) } } + /// + /// Identifies the expression components. + /// + /// The expression. + /// The ArrayList of expression components. + private static ArrayList IdentifyExpressionComponents(string expression) + { + return IdentifyExpressionComponents(expression, false); + } + /// /// Escapes the string. /// A string is escaped by removing the quotation marks at its start and finish and diff --git a/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs b/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs index 86c7d3a..c688f44 100644 --- a/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs +++ b/src/WorkflowActivityLibrary/Common/ExpressionFunction.cs @@ -2500,7 +2500,7 @@ private object DateTimeToFileTimeUtc() } /// - /// This function is used to convert a date to the local time or specifed time zone. + /// This function is used to convert a date to the local time or specified time zone. /// Function Syntax: DateTimeUtcToLocalTime(date:DateTime [, TimeZoneId]) /// /// The value of the specified UTC date expressed in the local time or specified time zone. @@ -2848,7 +2848,6 @@ private int IndexByValue() index += 1; } } - } Logger.Instance.WriteVerbose(EventIdentifier.ExpressionFunctionIndexByValue, "IndexByValue('{0}', '{1}') returned '{2}'.", this.parameters[0], this.parameters[1], result);