Skip to content

Conversation

@markekraus
Copy link
Contributor

@markekraus markekraus commented Oct 1, 2017

closes #4899

This adds a -CertificateValidationScript parameter to Invoke-RestMethod and Invoke-WebRequest which allows the user to supply a custom validation script as a PowerShell ScriptBlock to validate Server Certificates for HTTPS connections.

The ScriptBlock also has 4 automatic variables created which allows the user to use either $args, Param(), or the automatic variables to inspect the HttpRequestMessage being sent to the server, X509Certificate2 certificate returned by the server, the X509Chain certificate chain of the server certificate, and the SslPolicyErrors. The ScriptBlock is converted to a Closure and is wrapped in a Func delegate which is used as the HttpClientHandler.ServerCertificateCustomValidationCallback. The ScriptBlock has access to the calling scope and any ScriptBlock exceptions are treated as a certificate failure.

Documentation Needed

This new parameter will need to be documented and an example added. The documentation will need to note that the $using: scope is not supported and will result in a certificate failure. it will also need to note that if the site redirects, the same validation script will apply for all hops. Finally, it will also need to state that -SkipCertificateCheck will override anything supplied in -CertificateValidationScript.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add that it is ignored when -SkipCertificateCheck is present?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case, perhaps the two parameters should be in mutually exclusive parameter sets?

Copy link
Contributor Author

@markekraus markekraus Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkeithhill We don't want these to be full mutually exclusive via parameter set. we want to support this usage:

$script = { <# some validation script #> }
$PSDefaultParameterValues['Invoke-RestMethod:CertificateValidationScript'] = $script

# All calls will use the validation script
Invoke-RestMethod https://unknonwnurl.com/

# But the user may want to override their normal validation for a certain Url
Invoke-RestMethod https://devsite.com/ -SkipCertificateCheck

Also, the Web Cmdlets have traditionally had a single parameter set and there are other parameters that are "exclusive" (i.e. -InFile and -Body). Introducing a parameter set here would be awkward.

@iSazonov I can update the summary, but other parameters with this kind of behavior do not call it out in their summaries. I believe these summaries are only visible when coding in C#, correct? Since these are PSCmdlet derived, you don't even see these summaries from within the same assembly. In which case, this is visible only when working in classes that derive from WebRequestPSCmdlet.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Web Cmdlets have traditionally had a single parameter set I agree to follow the pattern.

My thought was that we should add the comment somewhere. The place is best. It's good for documenting code. Also we generate XML help files - I guess it can be used for creation of HTLM documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not mistaken, the help files are generated from the PowerShell/PowerShell-Docs markdown? I can certainly say that I have never seen gets or sets the Body property (the summary for -Body) in anything. I certainly don't see any of the parameter summaries in any of the help xmls. The only place this shows up is the Microsoft.PowerShell.Commands.Utility.xml file and that has the same unhelpful summaries as the other parameters.

I will update it. I just think it wont be actually that helpful to anyone.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's two types of help, there's the updatable help that exists in PowerShell-Docs and there's api reference docs that get generated from the assemblies. Any public api should be documented in code as the documentation is generated from that xml.

Copy link
Contributor Author

@markekraus markekraus Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT Is this the documentation you are referring to? https://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.webrequestpscmdlet(v=vs.85).aspx If not, what exactly? I ask because the other summaries are very unhelpful and if these are being documented somewhere they could use some serious attention. I have never seen these summaries outside of the XML file and the source code.

edit: I found it https://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.webrequestpscmdlet_members(v=vs.85).aspx

Copy link
Collaborator

@iSazonov iSazonov Oct 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already added in our coding guigance that we welcome good comments everywhere. I hope in time we'll see a well-documented code 😄

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe put x509Certificate2on first position because the callback is for it?
Another thought is to pass a PSObject as $PSItem with the properties (x509Certificate2, httpRequestMessage, ...).

Copy link
Contributor Author

@markekraus markekraus Oct 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All 4 are equally important for validating the certificate.

$Script = {
    Return (
        $HttpRequestMessage.RequestUri.AbsoluteUri -eq 'https://www.google.com/' -and
        $X509Certificate2.Subject -eq 'CN=www.google.com, O=Google Inc, L=Mountain View, S=California, C=US' -and
        $X509Chain.ChainElements[2].Certificate.Thumbprint -eq 'DE28F4A4FFE5B92FA3C503D1A349A7F9962A8212' -and
        $SslPolicyErrors -eq 'None'
    )
}

I wanted to mirror the ,NET callback as much as possible to prevent confusion.

To be clear, $args[1], $X509Certificate2, and Param( [Parameter(Position=1)]$certificate <#...#> ) are all possible to the user.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe if we say about a script block we shouldn't concerned about .Net templates. Script writes don't see underlying implementations and usualy expect implicit $PSItem or explicit Param.
Also the variables actually is automatic variables and we should add its in list of automatic variables. This seems unjustified.
I suggest we wait for @lzybkr opinion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's automatic to the ScriptBlock only. These do not show up in the calling scope. I don't see the problem? Please elaborate "we should add its in list of automatic variables". Do Script Block have their own list of automatic variables?

And, we should be concerned about the underlying .NET. It would be confusing to maintainers if the Func delegate has one argument order but the script block has another. The user gets the convenience of the automatic variables or Param() if they don't like that $args[0] is the HttpMessageRequest . As I said, all 4 arguments are equally important. Some users may have rules which never even test the certificate (URL based acceptance).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why set the variables and pass them as args?

Also, why set $ErrorActionPreference? That might not be desirable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why set the variables and pass them as args?

I wanted to support parameter binding by type i.e.

param(
    [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert,
# ...

I was trying to be flexible.

Also, why set $ErrorActionPreference? That might not be desirable.

The [planned] documented behavior is that that errors and exceptions result in certificate failures. I ran into some strange scenarios where if errors weren't terminating it would hang the thread. but, this was before I switched to a closure and before I was using LanguagePrimitives.IsTrue(). I'm not sure if it s still needed, I can check though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm definitely not in favor of both variables and parameters. Either way you need good documentation, but I prefer parameters.

And please do verify that setting $ErrorActionPreference is not needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the draft documentation:
MicrosoftDocs/PowerShell-Docs@staging...markekraus:CertificatevalidationScriptDraft

I'm not sure I agree that parameters are preferable. Personally, I'm OK with either. But, I think most people would rather have auto-variables than have to declare param() or try to remember which $args is which. in the end, this is a documentation heavy dependent feature no matter which way it is implemented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll let the @PowerShell/powershell-committee chime in on this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automatic variables removed per @PowerShell/powershell-committee decision. $ErrorActionPreference also appears to be no longer needed.

@markekraus
Copy link
Contributor Author

@lzybkr @SteveL-MSFT Is there something more I need to do for this PR?

@iSazonov
Copy link
Collaborator

iSazonov commented Oct 6, 2017

LGTM but we need review from MSFT experts.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd sleep better if this was in a finally - then I don't need to worry about a change to let some exceptions through.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no longer applicable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is worrisome. From reading just this code, I have no clue if currentRunspace will be blocked while the delegate is running.

For example, if we're streaming objects and in the middle of a call to WriteObject in the cmdlet's thread, that could yield to a random PowerShell event handler, which will be a race condition with whatever this delegate might do.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how to make this work in a different runspace and supporting access to the current scope. To me, personally, that is not an issue as I can live with this not having scope access. But in the discussion the issue was brought up that users might find that confusing. or difficult to work with.

Can you mock up something that would cause this race condition so I can test it? I did some basic tests with this running in a pipeline and as part of a process block, but I was never able to cause a hang. or unexpected behavior. I thought maybe since we are forcing the call to run synchronously it might nor be an issue:

HttpResponseMessage response = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, _cancelToken.Token).GetAwaiter().GetResult();

But, honestly, I'm not anywhere near an expert on this area. I just know that if I don't specify a run space here I get the exception about a missing runspace.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, before running your code, run something like:

$t = [System.Timers.Timer]::new(10)
$t.AutoReset = $true
Register-ObjectEvent -InputObject $t -EventName Elapsed -Action { Write-Host 'event' }
$t.Enabled = $true

If this doesn't cause problems, try something less trivial in the action - call functions, maybe a recursive function calculating fibonacci or something.

In your certificate validation script, also do something similarly non-trivial, e.g. compute a different fibonacci number.

I'm thinking some state will be corrupted, e.g. the current scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using that event and a simple block caused it to hang the thread. So definitely some corruption. ☹️ I'm looking at some other options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

10ms might be too fast, maybe try a little slower, say 100ms. The goal was to hit a race as quickly as possible and get something other than a hang, though I suppose a hang is one possible outcome of a race.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lzybkr actually... I think that test may kill any callback, not just the one in this issue.

I reduced the code to this

Func<HttpRequestMessage,X509Certificate2,X509Chain,SslPolicyErrors,bool> validationCallBackWrapper = 
    delegate(HttpRequestMessage httpRequestMessage, X509Certificate2 x509Certificate2, X509Chain x509Chain, SslPolicyErrors sslPolicyErrors)
    {
        Boolean result = false;
        try
        {
            result = LanguagePrimitives.IsTrue(
                CertificateValidationScript.InvokeReturnAsIs(
                    httpRequestMessage, 
                    x509Certificate2, 
                    x509Chain, 
                    sslPolicyErrors
                )
            );
        }
        catch // Treat all exceptions as Certificate failures.
        {
            result = false;
        }
        return result;
    };

handler.ServerCertificateCustomValidationCallback = validationCallBackWrapper;

No more closure, no more setting the default runspace, no more auto variables or erroraction. Just wrapping the InvokeReturnAsIs() in the delegate and this hangs:

$t = [System.Timers.Timer]::new(10)
$t.AutoReset = $true
Register-ObjectEvent -InputObject $t -EventName Elapsed -Action { write-host =  'event' }
$t.Enabled = $true
$script = { return $true }
Invoke-RestMethod -uri https://httpbin.org/get -CertificateValidationScript $Script

if I reduce it back to

Func<HttpRequestMessage,X509Certificate2,X509Chain,SslPolicyErrors,bool> validationCallBackWrapper =
    LanguagePrimitives.ConvertTo<Func<HttpRequestMessage,X509Certificate2,X509Chain,SslPolicyErrors,bool>>(CertificateValidationScript);
handler.ServerCertificateCustomValidationCallback = validationCallBackWrapper;

I get this:

Invoke-RestMethod : There is no Runspace available to run scripts in this thread. You can provide one in the
DefaultRunspace property of the System.Management.Automation.Runspaces.Runspace type. The script block you attempted
to invoke was:  return $true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

100ms didn't make a difference. ☹️ Still hangs on all the scenarios.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code has been changed and the setting/unsetting of the runspace is no longer a part of it. However, the callback still results in a thread hang when using the event trigger(s) provided by @lzybkr. I'm not sure where to go on that issue.

@lzybkr lzybkr added the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Oct 10, 2017
@SteveL-MSFT
Copy link
Member

@PowerShell/powershell-committee reviewed the topic of params or automatic variables passed to the script block delegate. There was concerns about new automatic variables scoped only to this usage but would needed to be documented in the about_automaticvariables topic which may create some confusion. In addition, params seems to be a general pattern already in use across PowerShell, so the request is to use params for the script block (and update the doc draft accordingly).

There were other concerns we didn't have time to discuss such as which runspace the delegate ran in. For now, continue that discussion in this PR.

@SteveL-MSFT SteveL-MSFT added Committee-Reviewed PS-Committee has reviewed this and made a decision and removed Review - Committee The PR/Issue needs a review from the PowerShell Committee labels Oct 12, 2017
@markekraus
Copy link
Contributor Author

markekraus commented Oct 12, 2017

Well that's baffling. It's not a surprise that the certificate validation doesn't work on macOS. I ran into similar issues enabling -Certificate because macOS (and some linux distors) use a different implementation than openssl that CoreFX doesn't support but, how did these tests manage to pass on macOS in previous commits?

It should have failed before.

@alx9r
Copy link

alx9r commented Oct 20, 2017

There was concerns about new automatic variables scoped only to this usage but would needed to be documented in the about_automaticvariables topic which may create some confusion.

@SteveL-MSFT Was the prospect of providing the callback parameters to the scriptblock by way of properties on $_ contemplated? That feels like the most PowerShell-ey style to me. There is precedent for non-pipeline use of $_ instead of param() in ValidateScript().

I've been favoring $_ over param() for scriptblock predicates like ServerCertificateCustomValidationCallback mainly because the param() block ends up being repeated, often overshadows the predicate in character count, and usually doesn't provide much useful information to a reader.

Here's a mock-up of param() vs $_ for illustration:

{
    param($Message,$Cert,$Chain,$PolicyErrors)
    Assert-CertificateCompliance -Policy Strict -Message $Message -Cert $Cert -Chain $Chain -PolicyErrors $PolicyErrors
}

{$_ | Assert-CertificateCompliance -Policy Strict}

For me the point of this PR is to be able to impose per-URL certificate requirements. So I'll end up with policy data structures looking something like this:

@{
    Uri = 'https://github.com'
    CertificateValidator = {
        $_ | Assert-CertificateCompliance -Policy Strict
        $_ | Assert-Certificate Server -Thumbprint d79f076110b39293e349ac89845b0380c19e2f8b
    }
}

@{
    Uri = 'https://www.powershellgallery.com'
    CertificateValidator = {
        $_ | Assert-CertificateCompliance -Policy Strict
        $_ | Assert-Certificate Intermediate -Thumbprint ‎98af62baa639b0827f887c75a77f4afd4eff2685
    }
}

The validation scriptblock gets repeated for each uri so noise from param() adds up.

@SteveL-MSFT
Copy link
Member

@alx9r no, using members of $_ wasn't something that was considered and is an interesting approach. Would like some others to chime in on this proposal. cc @lzybkr @JamesWTruher @HemantMahawar

@markekraus
Copy link
Contributor Author

@SteveL-MSFT I had an early draft that did it that way. I had dropped it in favor of the automatic variables before submitting the PR.

@SteveL-MSFT
Copy link
Member

@markekraus sorry, must have missed it. Getting myself involved in too many discussions on here to keep track of them (something I'm learning not to do!)

@markekraus
Copy link
Contributor Author

@SteveL-MSFT I don't think the draft ever made it's way to my public repo so I don't think you missed anything, actually. My point was more that I'm on board with the idea of a $_ with members if that lends any weight in the decision making.

@markekraus markekraus force-pushed the CertificateValidationScript branch 2 times, most recently from f196c5f to 888b2b3 Compare October 28, 2017 13:28
@markekraus
Copy link
Contributor Author

After much trial and error I determined that the only safe way to do this where any kind of event triggers were in place was run the ScriptBlock in a completely new session state and runspace. Variables could easily be imported, but I did tests where the event triggers updated a variable at that same time as callback and that resulted in a hang. Importing functions and modules leaves them in a disconnected state from the user's context (module scoped variables are lost).

I have incorporated the $_. I'm open for suggestions on renaming the members. Right now they are Request, Certificate, CertificateChain, and SslErrors. This current implementation does not support param(). I'm assuming we want to go with one or the other and not both.

I have tested the current code with the event triggers @lzybkr provided and it works. no hangs.

The down side is that the ScriptBlock is now devoid of the calling scope. I was originally under the impression it would need to be done this way and I think that so long as it is documented it should be acceptable. Any of the other means of making the scope available results in either unpredictable behavior or hangs. I think no scope is better than some broken scope.

@alx9r
Copy link

alx9r commented Oct 28, 2017

...I did tests where the event triggers updated a variable at that same time as callback and that resulted in a hang.

I'm curious what these tests looked like. It doesn't seem like Register-ObjectEvent naturally accepts PSVariables in its parameters. It also doesn't seem like the Register-ObjectEvent -Action scriptblock has access the call site's variables. In the tests that hung how did the event handler get a reference to the same variable as the callback?

I have incorporated the $_. I'm open for suggestions on renaming the members. Right now they are Request, Certificate, CertificateChain, and SslErrors.

I see that the current documentation for HttpClientHandler.ServerCertificateCustomValidationCallback doesn't name its parameters. For that matter, there is very little documentation about the semantics of that callback altogether. dotnet/corefx#24774 might improve that documentation and that might lead to parameter names. If ServerCertificateCustomValidationCallback does end up with documented parameter names, it seems like the properties on $_ should have identical names. The closest documented callback interface seems to be full .net's System.Net.Security.RemoteCertificateValidationCallback. I propose adopting the corresponding names from that callback interface in the meantime.

The down side is that the ScriptBlock is now devoid of the calling scope. I was originally under the impression it would need to be done this way and I think that so long as it is documented it should be acceptable. Any of the other means of making the scope available results in either unpredictable behavior or hangs. I think no scope is better than some broken scope.

Is there a reason that the scope rules wouldn't be the same as for other scriptblocks using remote variables? Invoke-Command -Session -ScriptBlock, for example, provides access to local variables in the remote session by way of the $using: expression.

FWIW, I think this would be a pretty awkward interface without having some way of making user objects available in the callback scriptblock. A natural use would be as follows:

@{
    u='https://github.com/some/important/file'
    thumbprint = 'd79f076110b39293e349ac89845b0380c19e2f8b'
},
@{
    u='https://powershellgallery.com/some/other/important/file'
    thumbprint = '98af62baa639b0827f887c75a77f4afd4eff2685'
} |
    % { 
        $thumbprint = $_.thumbprint
        # ... do some prep things
        Invoke-WebRequest $_.u -CertificateValidationScript {
            # ... a bunch of tests that are identical for every certificate
            $_.Certificate.Thumbprint -eq $using:thumbprint
        }
        # ... do some cleanup things
    }

Without $using:, arguments, or some other means of passing data, it will be tough to separate the concern of which thumbprints are acceptable for which url from the concern of checking for certificate revokation, for example.

@markekraus
Copy link
Contributor Author

markekraus commented Oct 28, 2017

I'm curious what these tests looked like.

I just used the same variable in @lzybkr's example and used it

$t = [System.Timers.Timer]::new(10)
$t.AutoReset = $true
Register-ObjectEvent -InputObject $t -EventName Elapsed -Action { Write-Host 'event' }
$t.Enabled = $true
$script = {$t.Enabled = $false; $true}
irm -uri https://expired.badssl.com
#hangs

$t was being populated as a PSVarabile in the iss.

I propose adopting the corresponding names from that callback interface in the meantime.

I disagree. Unless it is documented on this API, we should use something generic that is easier for PowerShell users to use. Sender is a terrible choice when it's an HttpRequestMessage. If Sender were the documented name for this API, then I would concede that's probably better.

Is there a reason that the scope rules wouldn't be the same as for other scriptblocks using

$using in every instance I've seen is a unique implementation. If there were a generic API for adding this capability to a ScriptBlock, then $using: would be awesome to have here. but I see no point in adding yet-another-using-implimentation for validation callbacks on cmdlets that don't normally do any work with ScriptBlocks.

Without $using:, arguments, or some other means of passing data,..

Erm, not really? I mean yea, not on the ease of use level that using variables from the calling scope or $using:, but, most validation logic is fairly static, in my experience. Create module, Import it in the ScriptBlock, magic. or use CSV, Clixml, JSON files for confgis if you don't wants it hard coded in the the PS Script.

I'm not saying this is ideal. What I am saying is that I can't see a safe way to get the calling scope available in the remote scope with out severely over-complicating the implementation.

Also, these validations scripts are "per call". For 6.1 I want to look at adding session persistent options. One of them will be add your own .NET delegates for cert validation, So if you want to have some variable magic then you can. The goal in this PR is to provide the basic implementation that will work for most people on a "per call" basis. I think most will just need to ensure a static thumbprint or 2 against URLs. Complex validation scenarios are not the goal of the implementation in this PR, but are on my radar for the futre.

@alx9r
Copy link

alx9r commented Oct 28, 2017

Complex validation scenarios are not the goal of the implementation in this PR, but are on my radar for the futre.

OK. Got it. Thanks @markekraus

@SteveL-MSFT SteveL-MSFT added Review - Committee The PR/Issue needs a review from the PowerShell Committee and removed Committee-Reviewed PS-Committee has reviewed this and made a decision labels Oct 31, 2017
@markekraus markekraus force-pushed the CertificateValidationScript branch from 888b2b3 to bf8c9dc Compare November 13, 2017 20:46
@markekraus
Copy link
Contributor Author

rebased to fix merge conflict.

@lzybkr lzybkr removed their assignment Nov 13, 2017
@iSazonov
Copy link
Collaborator

iSazonov commented Nov 14, 2017

@markekraus Another merge conflict.

@iSazonov iSazonov self-assigned this Nov 14, 2017
@markekraus markekraus force-pushed the CertificateValidationScript branch from bf8c9dc to 9bece06 Compare November 14, 2017 10:06
@markekraus
Copy link
Contributor Author

rebased.

@SteveL-MSFT
Copy link
Member

@PowerShell/powershell-committee reviewed this and recommends using the param() format. Specifically, $_ provides no context on what it represents. Typically $_ means the current object and reusing it in the scriptblock changes that expectation. Using param() makes the code more readable and therefore maintainable.

@SteveL-MSFT SteveL-MSFT added Committee-Reviewed PS-Committee has reviewed this and made a decision and removed Review - Committee The PR/Issue needs a review from the PowerShell Committee labels Nov 15, 2017
@iSazonov
Copy link
Collaborator

@markekraus Please rebase with next new commit to get latest updates and pass CIs.

@markekraus
Copy link
Contributor Author

@iSazonov I still need to incorporate the changes per the committee's decision. I will hopefully have free time this week. I will rebase before I commit the changes.

@markekraus
Copy link
Contributor Author

FYI, I'm waiting on #5518 as this will need to rebased again and more drastically.

@markekraus
Copy link
Contributor Author

Due to the issues of rebasing this and that the code still needs to be updated to fit the review comitee's decision, I'm going to close this PR. I will attempt to address this feature before 6.1.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Committee-Reviewed PS-Committee has reviewed this and made a decision

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add User Supplied ServerCertificateCustomValidationCallback Support to Web Cmdlets

7 participants