Пример #1
0
        /// <summary>
        /// Prompt.
        /// </summary>
        public override Dictionary <string, PSObject> Prompt(string caption, string message, Collection <FieldDescription> descriptions)
        {
            // forward the call to the client host
            Dictionary <string, PSObject> results = _serverMethodExecutor.ExecuteMethod <Dictionary <string, PSObject> >(
                RemoteHostMethodId.Prompt, new object[] { caption, message, descriptions });

            // attempt to do the requested type casts on the server (it is okay to fail the cast and return the original object)
            foreach (FieldDescription description in descriptions)
            {
                Type requestedType = InternalHostUserInterface.GetFieldType(description);
                if (requestedType != null)
                {
                    PSObject valueFromClient;
                    if (results.TryGetValue(description.Name, out valueFromClient))
                    {
                        object conversionResult;
                        if (LanguagePrimitives.TryConvertTo(valueFromClient, requestedType, CultureInfo.InvariantCulture, out conversionResult))
                        {
                            if (conversionResult != null)
                            {
                                results[description.Name] = PSObject.AsPSObject(conversionResult);
                            }
                            else
                            {
                                results[description.Name] = null;
                            }
                        }
                    }
                }
            }

            return(results);
        }
Пример #2
0
        /// <summary>
        /// This message performs various security checks on the
        /// remote host call message. If there is a need to modify
        /// the message or discard it for security reasons then
        /// such modifications will be made here
        /// </summary>
        /// <param name="computerName">computer name to use in
        /// warning messages</param>
        /// <returns>A collection of remote host calls which will
        /// have to be executed before this host call can be
        /// executed.</returns>
        internal Collection <RemoteHostCall> PerformSecurityChecksOnHostMessage(string computerName)
        {
            Dbg.Assert(!String.IsNullOrEmpty(computerName),
                       "Computer Name must be passed for use in warning messages");
            _computerName = computerName;
            Collection <RemoteHostCall> prerequisiteCalls = new Collection <RemoteHostCall>();

            // check if the incoming message is a PromptForCredential message
            // if so, do the following:
            //       (a) prepend "Windows PowerShell Credential Request" in the title
            //       (b) prepend "Message from Server XXXXX" to the text message
            if (MethodId == RemoteHostMethodId.PromptForCredential1 ||
                MethodId == RemoteHostMethodId.PromptForCredential2)
            {
                // modify the caption which is _parameters[0]
                string modifiedCaption = ModifyCaption((string)Parameters[0]);

                // modify the message which is _parameters[1]
                string modifiedMessage = ModifyMessage((string)Parameters[1], computerName);

                Parameters[0] = modifiedCaption;
                Parameters[1] = modifiedMessage;
            }

            // Check if the incoming message is a Prompt message
            // if so, then do the following:
            //        (a) check if any of the field descriptions
            //            correspond to PSCredential
            //        (b) if field descriptions correspond to
            //            PSCredential modify the caption and
            //            message as in the previous case above
            else if (MethodId == RemoteHostMethodId.Prompt)
            {
                // check if any of the field descriptions is for type
                // PSCredential
                if (Parameters.Length == 3)
                {
                    Collection <FieldDescription> fieldDescs =
                        (Collection <FieldDescription>)Parameters[2];

                    bool havePSCredential = false;

                    foreach (FieldDescription fieldDesc in fieldDescs)
                    {
                        fieldDesc.IsFromRemoteHost = true;

                        Type fieldType = InternalHostUserInterface.GetFieldType(fieldDesc);
                        if (fieldType != null)
                        {
                            if (fieldType == typeof(PSCredential))
                            {
                                havePSCredential = true;
                                fieldDesc.ModifiedByRemotingProtocol = true;
                            }
                            else if (fieldType == typeof(System.Security.SecureString))
                            {
                                prerequisiteCalls.Add(ConstructWarningMessageForSecureString(
                                                          computerName, RemotingErrorIdStrings.RemoteHostPromptSecureStringPrompt));
                            }
                        }
                    }

                    if (havePSCredential)
                    {
                        // modify the caption which is parameter[0]
                        string modifiedCaption = ModifyCaption((string)Parameters[0]);

                        // modify the message which is parameter[1]
                        string modifiedMessage = ModifyMessage((string)Parameters[1], computerName);

                        Parameters[0] = modifiedCaption;
                        Parameters[1] = modifiedMessage;
                    }
                }
            }

            // Check if the incoming message is a readline as secure string
            // if so do the following:
            //      (a) Specify a warning message that the server is
            //          attempting to read something securely on the client
            else if (MethodId == RemoteHostMethodId.ReadLineAsSecureString)
            {
                prerequisiteCalls.Add(ConstructWarningMessageForSecureString(
                                          computerName, RemotingErrorIdStrings.RemoteHostReadLineAsSecureStringPrompt));
            }

            // check if the incoming call is GetBufferContents
            // if so do the following:
            //      (a) Specify a warning message that the server is
            //          attempting to read the screen buffer contents
            //          on screen and it has been blocked
            //      (b) Modify the message so that call is not executed
            else if (MethodId == RemoteHostMethodId.GetBufferContents)
            {
                prerequisiteCalls.Add(ConstructWarningMessageForGetBufferContents(computerName));
            }

            return(prerequisiteCalls);
        }
        Prompt(string caption, string message, Collection <FieldDescription> descriptions)
        {
            // Need to implement EchoOnPrompt
            HandleThrowOnReadAndPrompt();

            if (descriptions == null)
            {
                throw PSTraceSource.NewArgumentNullException("descriptions");
            }

            if (descriptions.Count < 1)
            {
                throw PSTraceSource.NewArgumentException("descriptions",
                                                         ConsoleHostUserInterfaceStrings.PromptEmptyDescriptionsErrorTemplate, "descriptions");
            }

            // we lock here so that multiple threads won't interleave the various reads and writes here.

            lock (_instanceLock)
            {
                Dictionary <string, PSObject> results = new Dictionary <string, PSObject>();

                bool cancelInput = false;

                if (!string.IsNullOrEmpty(caption))
                {
                    // Should be a skin lookup

                    WriteLineToConsole();
                    WriteLineToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption));
                }

                if (!string.IsNullOrEmpty(message))
                {
                    WriteLineToConsole(WrapToCurrentWindowWidth(message));
                }

                if (AtLeastOneHelpMessageIsPresent(descriptions))
                {
                    WriteLineToConsole(WrapToCurrentWindowWidth(ConsoleHostUserInterfaceStrings.PromptHelp));
                }

                int descIndex = -1;

                foreach (FieldDescription desc in descriptions)
                {
                    descIndex++;
                    if (desc == null)
                    {
                        throw PSTraceSource.NewArgumentException("descriptions",
                                                                 ConsoleHostUserInterfaceStrings.NullErrorTemplate,
                                                                 string.Format(CultureInfo.InvariantCulture, "descriptions[{0}]", descIndex));
                    }

                    PSObject inputPSObject = null;
                    string   fieldPrompt   = null;
                    fieldPrompt = desc.Name;

                    bool fieldEchoOnPrompt = true;

                    // FieldDescription.ParameterAssemblyFullName never returns null. But this is
                    // defense in depth.
                    if (string.IsNullOrEmpty(desc.ParameterAssemblyFullName))
                    {
                        string paramName =
                            string.Format(CultureInfo.InvariantCulture, "descriptions[{0}].AssemblyFullName", descIndex);
                        throw PSTraceSource.NewArgumentException(paramName, ConsoleHostUserInterfaceStrings.NullOrEmptyErrorTemplate, paramName);
                    }

                    Type fieldType = InternalHostUserInterface.GetFieldType(desc);
                    if (fieldType == null)
                    {
                        if (InternalHostUserInterface.IsSecuritySensitiveType(desc.ParameterTypeName))
                        {
                            string errMsg =
                                StringUtil.Format(ConsoleHostUserInterfaceStrings.PromptTypeLoadErrorTemplate,
                                                  desc.Name, desc.ParameterTypeFullName);
                            PromptingException e = new PromptingException(errMsg,
                                                                          null, "BadTypeName", ErrorCategory.InvalidType);
                            throw e;
                        }

                        fieldType = typeof(string);
                    }

                    if (fieldType.GetInterface(typeof(IList).FullName) != null)
                    {
                        // field is a type implementing IList
                        ArrayList inputList = new ArrayList(); // stores all converted user input before
                        // assigned to an array

                        // if the field is an array, the element type can be found; else, use Object
                        Type elementType = typeof(object);
                        if (fieldType.IsArray)
                        {
                            elementType = fieldType.GetElementType();
                            int rank = fieldType.GetArrayRank();
                            // This check may be redundant because it doesn't seem possible to create
                            // an array of zero dimension.
                            if (rank <= 0)
                            {
                                string            msg            = StringUtil.Format(ConsoleHostUserInterfaceStrings.RankZeroArrayErrorTemplate, desc.Name);
                                ArgumentException innerException = PSTraceSource.NewArgumentException(
                                    string.Format(CultureInfo.InvariantCulture,
                                                  "descriptions[{0}].AssemblyFullName", descIndex));
                                PromptingException e = new PromptingException(msg, innerException, "ZeroRankArray", ErrorCategory.InvalidOperation);
                                throw e;
                            }
                        }

                        StringBuilder fieldPromptList = new StringBuilder(fieldPrompt);
                        // fieldPromptList = fieldPrompt + "[i] :"
                        fieldPromptList.Append("[");

                        while (true)
                        {
                            fieldPromptList.Append(
                                string.Format(CultureInfo.InvariantCulture, "{0}]: ", inputList.Count));
                            bool   inputListEnd = false;
                            object convertedObj = null;
                            string inputString  = PromptForSingleItem(elementType, fieldPromptList.ToString(), fieldPrompt, caption, message,
                                                                      desc, fieldEchoOnPrompt, true, out inputListEnd, out cancelInput, out convertedObj);

                            if (cancelInput || inputListEnd)
                            {
                                break;
                            }
                            else if (!cancelInput)
                            {
                                inputList.Add(convertedObj);
                                // Remove the indices from the prompt
                                fieldPromptList.Length = fieldPrompt.Length + 1;
                            }
                        }
                        // if cancelInput, should throw OperationCancelException?
                        if (!cancelInput)
                        {
                            object tryConvertResult = null;
                            if (LanguagePrimitives.TryConvertTo(inputList, fieldType, out tryConvertResult))
                            {
                                inputPSObject = PSObject.AsPSObject(tryConvertResult);
                            }
                            else
                            {
                                inputPSObject = PSObject.AsPSObject(inputList);
                            }
                        }
                    }
                    else
                    {
                        string printFieldPrompt = StringUtil.Format(ConsoleHostUserInterfaceStrings.PromptFieldPromptInputSeparatorTemplate,
                                                                    fieldPrompt);
                        // field is not a list
                        object convertedObj = null;
                        bool   dummy        = false;

                        PromptForSingleItem(fieldType, printFieldPrompt, fieldPrompt, caption, message, desc,
                                            fieldEchoOnPrompt, false, out dummy, out cancelInput, out convertedObj);
                        if (!cancelInput)
                        {
                            inputPSObject = PSObject.AsPSObject(convertedObj);
                        }
                    }

                    if (cancelInput)
                    {
                        s_tracer.WriteLine("Prompt canceled");
                        WriteLineToConsole();
                        results.Clear();
                        break;
                    }

                    results.Add(desc.Name, PSObject.AsPSObject(inputPSObject));
                }

                return(results);
            }
        }