/// <summary>
        /// Converts value of args parameter in to an encoded string
        /// </summary>
        private static string ConvertArgsValueToEncodedString(object value)
        {
            ArrayList list = ConvertArgsValueToArrayList(value);

            //Serialize the list
            StringWriter stringWriter = new StringWriter(System.Globalization.CultureInfo.InvariantCulture);
            //When (if) switching to XmlTextWriter.Create remember the OmitXmlDeclaration difference
            XmlWriter  xmlWriter  = XmlWriter.Create(stringWriter);
            Serializer serializer = new Serializer(xmlWriter);

            serializer.Serialize(list);
            serializer.Done();
            xmlWriter.Flush();
            string result = stringWriter.ToString();

            //convert result to encoded string
            return(StringToBase64Converter.StringToBase64String(result));
        }
예제 #2
0
        /// <summary>
        /// This method is to get the unique key for a UsingExpressionAst. The key is a base64
        /// encoded string based on the text of the UsingExpressionAst.
        ///
        /// This method is used when handling a script block that contains $using for Invoke-Command.
        ///
        /// When run Invoke-Command targeting a machine that runs PSv3 or above, we pass a dictionary
        /// to the remote end that contains the key of each UsingExpressionAst and its value. This method
        /// is used to generate the key.
        /// </summary>
        /// <param name="usingAst">A using expression</param>
        /// <returns>Base64 encoded string as the key of the UsingExpressionAst</returns>
        internal static string GetUsingExpressionKey(Language.UsingExpressionAst usingAst)
        {
            Diagnostics.Assert(usingAst != null, "Caller makes sure the parameter is not null");

            // We cannot call ToLowerInvariant unconditionally, because usingAst might
            // contain IndexExpressionAst in its SubExpression, such as
            //   $using:bar["AAAA"]
            // and the index "AAAA" might not get us the same value as "aaaa".
            //
            // But we do want a unique key to represent the same UsingExpressionAst's as much
            // as possible, so as to avoid sending redundant key-value's to remote machine.
            // As a workaround, we call ToLowerInvariant when the SubExpression of usingAst
            // is a VariableExpressionAst, because:
            //   (1) Variable name is case insensitive;
            //   (2) People use $using to refer to a variable most of the time.
            string usingAstText = usingAst.ToString();

            if (usingAst.SubExpression is Language.VariableExpressionAst)
            {
                usingAstText = usingAstText.ToLowerInvariant();
            }
            return(StringToBase64Converter.StringToBase64String(usingAstText));
        }
예제 #3
0
        /// <summary>
        /// Binds the specified parameters to the native command
        /// </summary>
        /// <param name="parameters">
        /// The parameters to bind.
        /// </param>
        /// <param name="outputRedirected">
        /// true if minishell output is redirected.
        /// </param>
        /// <param name="hostName">
        /// name of the calling host.
        /// </param>
        /// <remarks>
        /// For any parameters that do not have a name, they are added to the command
        /// line arguments for the command
        /// </remarks>
        internal Collection <CommandParameterInternal> BindParameters(Collection <CommandParameterInternal> parameters, bool outputRedirected, string hostName)
        {
            MinishellParameters seen = 0;
            string inputFormat       = null;
            string outputFormat      = null;

            for (int i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];

                if (parameter.ParameterNameSpecified)
                {
                    var parameterName = parameter.ParameterName;

                    if (CommandParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.Command, CommandParameter);

                        // Value must be specified for -Command parameter.
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, CommandParameter,
                                                               typeof(ScriptBlock), null,
                                                               NativeCP.NoValueForCommandParameter,
                                                               "NoValueForCommandParameter");
                        }

                        i += 1;

                        // Value of -Command parameter must be scriptblock
                        var scriptBlockArgument = parameters[i];
                        var argumentValue       = PSObject.Base(scriptBlockArgument.ArgumentValue);
                        if (!scriptBlockArgument.ArgumentSpecified || !(argumentValue is ScriptBlock))
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, CommandParameter,
                                                               typeof(ScriptBlock), argumentValue.GetType(),
                                                               NativeCP.IncorrectValueForCommandParameter,
                                                               "IncorrectValueForCommandParameter");
                        }

                        // Replace the parameters with -EncodedCommand <base64 encoded scriptblock>
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(EncodedCommandParameter, "-" + EncodedCommandParameter, parameter.ParameterAst);
                        string encodedScript = StringToBase64Converter.StringToBase64String(argumentValue.ToString());
                        parameters[i] = CommandParameterInternal.CreateArgument(encodedScript, scriptBlockArgument.ArgumentAst);
                    }
                    else if (InputFormatParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.InputFormat, InputFormatParameter);

                        // Value for -Inputformat must be specified
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, InputFormatParameter,
                                                               typeof(string), null,
                                                               NativeCP.NoValueForInputFormatParameter,
                                                               "NoValueForInputFormatParameter");
                        }

                        // Update the argument (partial arguments are allowed)
                        i += 1;
                        var inputFormatArg = parameters[i];
                        inputFormat       = ProcessFormatParameterValue(InputFormatParameter, inputFormatArg.ArgumentValue);
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(InputFormatParameter, "-" + InputFormatParameter, parameter.ParameterAst);
                        parameters[i]     = CommandParameterInternal.CreateArgument(inputFormat, inputFormatArg.ArgumentAst);
                    }
                    else if (OutputFormatParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.OutputFormat, OutputFormatParameter);

                        // Value for -Inputformat must be specified
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, OutputFormatParameter,
                                                               typeof(string), null,
                                                               NativeCP.NoValueForOutputFormatParameter,
                                                               "NoValueForInputFormatParameter");
                        }

                        // Update the argument (partial arguments are allowed)
                        i += 1;
                        var outputFormatArg = parameters[i];
                        outputFormat      = ProcessFormatParameterValue(OutputFormatParameter, outputFormatArg.ArgumentValue);
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(OutputFormatParameter, "-" + OutputFormatParameter, parameter.ParameterAst);
                        parameters[i]     = CommandParameterInternal.CreateArgument(outputFormat, outputFormatArg.ArgumentAst);
                    }
                    else if (ArgsParameter.StartsWith(parameterName, StringComparison.OrdinalIgnoreCase))
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.Arguments, ArgsParameter);

                        // Value for -Args parameter must be specified
                        if (i + 1 >= parameters.Count)
                        {
                            throw NewParameterBindingException(null, ErrorCategory.InvalidArgument, ArgsParameter,
                                                               typeof(string), null, NativeCP.NoValuesSpecifiedForArgs,
                                                               "NoValuesSpecifiedForArgs");
                        }

                        // Get the encoded value for -args parameter
                        i += 1;
                        var argsArg     = parameters[i];
                        var encodedArgs = ConvertArgsValueToEncodedString(argsArg.ArgumentValue);
                        parameters[i - 1] = CommandParameterInternal.CreateParameter(EncodedArgsParameter, "-" + EncodedArgsParameter, parameter.ParameterAst);
                        // NOTE: do not pass the ArgumentAst; it will fail validation in BindParameters if there
                        // are multiple arguments (array) but encodedArgs is an encoded string.
                        parameters[i] = CommandParameterInternal.CreateArgument(encodedArgs);
                    }
                }
                else
                {
                    // -Command is positional parameter. Bind first scriptblock to it, others are errors.
                    var scriptBlockArgument = parameters[i];
                    var argumentValue       = PSObject.Base(scriptBlockArgument.ArgumentValue);
                    if (argumentValue is ScriptBlock)
                    {
                        HandleSeenParameter(ref seen, MinishellParameters.Command, CommandParameter);

                        // Replace the argument with -EncodedCommand <base64 encoded scriptblock>
                        string encodedScript = StringToBase64Converter.StringToBase64String(argumentValue.ToString());
                        parameters[i] = CommandParameterInternal.CreateParameterWithArgument(
                            parameter.ArgumentAst, EncodedCommandParameter, "-" + EncodedCommandParameter,
                            parameter.ArgumentAst, encodedScript,
                            spaceAfterParameter: true);
                    }
                }
            }

            // Add InputFormat and OutputFormat parameter if not specified
            if (inputFormat == null)
            {
                // For minishell default input format is xml
                parameters.Add(CommandParameterInternal.CreateParameter(InputFormatParameter, "-" + InputFormatParameter));
                parameters.Add(CommandParameterInternal.CreateArgument(XmlFormatValue));
                inputFormat = XmlFormatValue;
            }

            if (outputFormat == null)
            {
                // If output is redirected, output format should be xml
                outputFormat = outputRedirected ? XmlFormatValue : TextFormatValue;
                parameters.Add(CommandParameterInternal.CreateParameter(OutputFormatParameter, "-" + OutputFormatParameter));
                parameters.Add(CommandParameterInternal.CreateArgument(outputFormat));
            }

            // Set the output and input format class variable
            InputFormat = XmlFormatValue.StartsWith(inputFormat, StringComparison.OrdinalIgnoreCase)
                ? NativeCommandIOFormat.Xml
                : NativeCommandIOFormat.Text;
            OutputFormat = XmlFormatValue.StartsWith(outputFormat, StringComparison.OrdinalIgnoreCase)
                ? NativeCommandIOFormat.Xml
                : NativeCommandIOFormat.Text;

            // Note if a minishell is invoked from a non-console host, we need to
            // pass -nonInteractive flag. Our console host's name is "ConsoleHost".
            // Correct check would be see if current host has access to console and
            // pass noninteractive flag if doesn't.
            if (string.IsNullOrEmpty(hostName) || !hostName.Equals("ConsoleHost", StringComparison.OrdinalIgnoreCase))
            {
                NonInteractive = true;
                parameters.Insert(0, CommandParameterInternal.CreateParameter(NonInteractiveParameter, "-" + NonInteractiveParameter));
            }

            ((NativeCommandParameterBinder)DefaultParameterBinder).BindParameters(parameters);

            Diagnostics.Assert(s_emptyReturnCollection.Count == 0, "This list shouldn't be used for anything as it's shared.");

            return(s_emptyReturnCollection);
        } // BindParameters
예제 #4
0
 private ArrayList ProcessMinishellParameters(
     ArrayList args,
     bool outputRedirected,
     string hostName)
 {
     using (MinishellParameterBinderController.tracer.TraceMethod())
     {
         ArrayList arrayList = new ArrayList();
         string    lhs1      = (string)null;
         string    lhs2      = (string)null;
         MinishellParameterBinderController.MinishellParameters seen = (MinishellParameterBinderController.MinishellParameters) 0;
         for (int index = 0; index < args.Count; ++index)
         {
             object obj = args[index];
             if (MinishellParameterBinderController.StartsWith("-command", obj))
             {
                 this.HandleSeenParameter(ref seen, MinishellParameterBinderController.MinishellParameters.Command, "-command");
                 arrayList.Add((object)"-encodedCommand");
                 if (index + 1 >= args.Count)
                 {
                     throw this.NewParameterBindingException((Exception)null, ErrorCategory.InvalidArgument, "-command", typeof(ScriptBlock), (Type)null, "NoValueForCommandParameter");
                 }
                 if (!(args[index + 1] is ScriptBlock scriptBlock))
                 {
                     throw this.NewParameterBindingException((Exception)null, ErrorCategory.InvalidArgument, "-command", typeof(ScriptBlock), args[index + 1].GetType(), "IncorrectValueForCommandParameter");
                 }
                 string base64String = StringToBase64Converter.StringToBase64String(scriptBlock.ToString());
                 arrayList.Add((object)base64String);
                 ++index;
             }
             else if (obj is ScriptBlock)
             {
                 this.HandleSeenParameter(ref seen, MinishellParameterBinderController.MinishellParameters.Command, "-command");
                 arrayList.Add((object)"-encodedCommand");
                 string base64String = StringToBase64Converter.StringToBase64String(obj.ToString());
                 arrayList.Add((object)base64String);
             }
             else if (MinishellParameterBinderController.StartsWith("-inputFormat", obj))
             {
                 this.HandleSeenParameter(ref seen, MinishellParameterBinderController.MinishellParameters.InputFormat, "-inputFormat");
                 arrayList.Add((object)"-inputFormat");
                 if (index + 1 >= args.Count)
                 {
                     throw this.NewParameterBindingException((Exception)null, ErrorCategory.InvalidArgument, "-inputFormat", typeof(string), (Type)null, "NoValueForInputFormatParameter");
                 }
                 lhs1 = this.ProcessFormatParameterValue("-inputFormat", args[index + 1]);
                 ++index;
                 arrayList.Add((object)lhs1);
             }
             else if (MinishellParameterBinderController.StartsWith("-outputFormat", obj))
             {
                 this.HandleSeenParameter(ref seen, MinishellParameterBinderController.MinishellParameters.OutputFormat, "-outputFormat");
                 arrayList.Add((object)"-outputFormat");
                 if (index + 1 >= args.Count)
                 {
                     throw this.NewParameterBindingException((Exception)null, ErrorCategory.InvalidArgument, "-outputFormat", typeof(string), (Type)null, "NoValueForOutputFormatParameter");
                 }
                 lhs2 = this.ProcessFormatParameterValue("-outputFormat", args[index + 1]);
                 ++index;
                 arrayList.Add((object)lhs2);
             }
             else if (MinishellParameterBinderController.StartsWith("-args", obj))
             {
                 this.HandleSeenParameter(ref seen, MinishellParameterBinderController.MinishellParameters.Arguments, "-args");
                 arrayList.Add((object)"-encodedarguments");
                 if (index + 1 >= args.Count)
                 {
                     throw this.NewParameterBindingException((Exception)null, ErrorCategory.InvalidArgument, "-args", typeof(string), (Type)null, "NoValuesSpecifiedForArgs");
                 }
                 string encodedString = MinishellParameterBinderController.ConvertArgsValueToEncodedString(args[index + 1]);
                 ++index;
                 arrayList.Add((object)encodedString);
             }
             else
             {
                 arrayList.Add(obj);
             }
         }
         if (lhs1 == null)
         {
             arrayList.Add((object)"-inputFormat");
             arrayList.Add((object)"xml");
             lhs1 = "xml";
         }
         if (lhs2 == null)
         {
             arrayList.Add((object)"-outputFormat");
             if (outputRedirected)
             {
                 arrayList.Add((object)"xml");
                 lhs2 = "xml";
             }
             else
             {
                 arrayList.Add((object)"text");
                 lhs2 = "text";
             }
         }
         this.inputFormatValue  = !MinishellParameterBinderController.StartsWith(lhs1, (object)"xml") ? NativeCommandIOFormat.Text : NativeCommandIOFormat.Xml;
         this.outputFormatValue = !MinishellParameterBinderController.StartsWith(lhs2, (object)"xml") ? NativeCommandIOFormat.Text : NativeCommandIOFormat.Xml;
         if (string.IsNullOrEmpty(hostName) || !hostName.Equals("ConsoleHost", StringComparison.OrdinalIgnoreCase))
         {
             this.nonInteractive = true;
             arrayList.Insert(0, (object)"-noninteractive");
         }
         return(arrayList);
     }
 }
        private ArrayList ProcessMinishellParameters(ArrayList args, bool outputRedirected, string hostName)
        {
            ArrayList           list = new ArrayList();
            string              str  = null;
            string              str2 = null;
            MinishellParameters seen = 0;

            for (int i = 0; i < args.Count; i++)
            {
                object obj2 = args[i];
                if (StartsWith("-command", obj2))
                {
                    this.HandleSeenParameter(ref seen, MinishellParameters.Command, "-command");
                    list.Add("-encodedCommand");
                    if ((i + 1) >= args.Count)
                    {
                        throw this.NewParameterBindingException(null, ErrorCategory.InvalidArgument, "-command", typeof(ScriptBlock), null, "NoValueForCommandParameter", new object[0]);
                    }
                    ScriptBlock block = args[i + 1] as ScriptBlock;
                    if (block == null)
                    {
                        throw this.NewParameterBindingException(null, ErrorCategory.InvalidArgument, "-command", typeof(ScriptBlock), args[i + 1].GetType(), "IncorrectValueForCommandParameter", new object[0]);
                    }
                    string str3 = StringToBase64Converter.StringToBase64String(block.ToString());
                    list.Add(str3);
                    i++;
                }
                else if (obj2 is ScriptBlock)
                {
                    this.HandleSeenParameter(ref seen, MinishellParameters.Command, "-command");
                    list.Add("-encodedCommand");
                    string str4 = StringToBase64Converter.StringToBase64String(obj2.ToString());
                    list.Add(str4);
                }
                else if (StartsWith("-inputFormat", obj2))
                {
                    this.HandleSeenParameter(ref seen, MinishellParameters.InputFormat, "-inputFormat");
                    list.Add("-inputFormat");
                    if ((i + 1) >= args.Count)
                    {
                        throw this.NewParameterBindingException(null, ErrorCategory.InvalidArgument, "-inputFormat", typeof(string), null, "NoValueForInputFormatParameter", new object[0]);
                    }
                    str = this.ProcessFormatParameterValue("-inputFormat", args[i + 1]);
                    i++;
                    list.Add(str);
                }
                else if (StartsWith("-outputFormat", obj2))
                {
                    this.HandleSeenParameter(ref seen, MinishellParameters.OutputFormat, "-outputFormat");
                    list.Add("-outputFormat");
                    if ((i + 1) >= args.Count)
                    {
                        throw this.NewParameterBindingException(null, ErrorCategory.InvalidArgument, "-outputFormat", typeof(string), null, "NoValueForOutputFormatParameter", new object[0]);
                    }
                    str2 = this.ProcessFormatParameterValue("-outputFormat", args[i + 1]);
                    i++;
                    list.Add(str2);
                }
                else if (StartsWith("-args", obj2))
                {
                    this.HandleSeenParameter(ref seen, MinishellParameters.Arguments, "-args");
                    list.Add("-encodedarguments");
                    if ((i + 1) >= args.Count)
                    {
                        throw this.NewParameterBindingException(null, ErrorCategory.InvalidArgument, "-args", typeof(string), null, "NoValuesSpecifiedForArgs", new object[0]);
                    }
                    string str5 = ConvertArgsValueToEncodedString(args[i + 1]);
                    i++;
                    list.Add(str5);
                }
                else
                {
                    list.Add(obj2);
                }
            }
            if (str == null)
            {
                list.Add("-inputFormat");
                list.Add("xml");
                str = "xml";
            }
            if (str2 == null)
            {
                list.Add("-outputFormat");
                if (outputRedirected)
                {
                    list.Add("xml");
                    str2 = "xml";
                }
                else
                {
                    list.Add("text");
                    str2 = "text";
                }
            }
            if (StartsWith(str, "xml"))
            {
                this.inputFormatValue = NativeCommandIOFormat.Xml;
            }
            else
            {
                this.inputFormatValue = NativeCommandIOFormat.Text;
            }
            if (StartsWith(str2, "xml"))
            {
                this.outputFormatValue = NativeCommandIOFormat.Xml;
            }
            else
            {
                this.outputFormatValue = NativeCommandIOFormat.Text;
            }
            if (string.IsNullOrEmpty(hostName) || !hostName.Equals("ConsoleHost", StringComparison.OrdinalIgnoreCase))
            {
                this.nonInteractive = true;
                list.Insert(0, "-noninteractive");
            }
            return(list);
        }