# encoding: ascii
# api: powershell
# title: SSL Oblivious Web Client
# description: This function creates a web client that will ignore all SSL certificate errors. Useful for uploading (HTTP PUT, maybe POST as well) to an https web server using a self-signed cert.
# version: 0.1
# type: function
# author: Stephen Campbell
# license: CC0
# function: New-TrustAllWebClient
# x-poshcode-id: 634
# x-archived: 2014-04-07T16:50:33
# x-published: 2009-10-09T21:27:00
#
# Note: When uploading, the entire file is loaded into memory.  We’re working on a solution.
# This function comes from Stephen Campbell of Marchview Consultants Ltd and Carter Shanklin of VMware Inc.
#
function New-TrustAllWebClient {
	# Create a compilation environment
	$Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
	$Compiler=$Provider.CreateCompiler()
	$Params=New-Object System.CodeDom.Compiler.CompilerParameters
	$Params.GenerateExecutable=$False
	$Params.GenerateInMemory=$True
	$Params.IncludeDebugInformation=$False
	$Params.ReferencedAssemblies.Add("System.DLL") > $null
	$TASource=@'
	  namespace Local.ToolkitExtensions.Net.CertificatePolicy {
	    public class TrustAll : System.Net.ICertificatePolicy {
	      public TrustAll() { 
	      }
	      public bool CheckValidationResult(System.Net.ServicePoint sp,
	        System.Security.Cryptography.X509Certificates.X509Certificate cert, 
	        System.Net.WebRequest req, int problem) {
	        return true;
	      }
	    }
	  }
'@ 
	$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
	$TAAssembly=$TAResults.CompiledAssembly

	## We now create an instance of the TrustAll and attach it to the ServicePointManager
	$TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
	[System.Net.ServicePointManager]::CertificatePolicy=$TrustAll

	## The ESX Upload requires the Preauthenticate value to be true which is not the default
	## for the System.Net.WebClient class which has very simple-to-use downloadFile and uploadfile
	## methods.  We create an override class which simply sets that Preauthenticate value.
	## After creating an instance of the Local.ToolkitExtensions.Net.WebClient class, we use it just
	## like the standard WebClient class.
	$WCSource=@'
	  namespace Local.ToolkitExtensions.Net {
	    class WebClient : System.Net.WebClient {
	      protected override System.Net.WebRequest GetWebRequest(System.Uri uri) {
	        System.Net.WebRequest webRequest = base.GetWebRequest(uri);
	        webRequest.PreAuthenticate = true;
	        webRequest.Timeout = System.Threading.Timeout.Infinite;
	        return webRequest;
	      }
	    }
	  }
'@
	$WCResults=$Provider.CompileAssemblyFromSource($Params,$WCSource)
	$WCAssembly=$WCResults.CompiledAssembly

	## Now return the custom WebClient. It behaves almost like a normal WebClient.
	$WebClient=$WCAssembly.CreateInstance("Local.ToolkitExtensions.Net.WebClient")
	return $WebClient
}

# Example of using this function to upload a file over SSL.
# Notice that the object you get back from New-TrustAllWebClient is almost identical
# to what you would get from new-object system.net.webclient.
# $wc = New-TrustAllWebClient
# $credential = get-credential
# $wc.set_Credentials($credential.GetNetworkCredential())
# $URL = "https://192.168.25.129/folder/VM%201/VM%201.vmx?dcPath=ha-datacenter&dsName=datastore1"
# $wc.UploadString($URL, "PUT", "Testing")
