Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow SecurityProtocol to be specified for a repo #21

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ psrepository { 'my-internal-repo':
}
```

If the PowerShell repository enforces a specific security protocol, e.g. TLS 1.2, then this can be specified using the securityprotocols parameter, see [SecurityProtocolType Enum](https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype) for a list of allowed values.

```puppet
psrepository { 'my-internal-repo':
ensure => present,
source_location => 'http://myrepo.corp.com/api/nuget/powershell',
installation_policy => 'trusted',
provider => 'windowspowershell',
securityprotocols => [ 'Tls12' ]
}
```

Manifests can then refer to that repository using the `package` resource.

```puppet
Expand Down Expand Up @@ -235,6 +247,10 @@ The url to the repository that you would like to register. Must be a valid HTTP

Manages the installation policy used for the PSRepository. Valid values are `trusted` or `untrusted`

#### `securityprotocols`

An optional array of security protocols to use when accessing the repository. Values specified will be used to set the [ServicePointManager.SecurityProtocol](https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.securityprotocol) property, if this parameter is not specified then the system default protocol will be used.

### Providers
#### `windowspowershell`

Expand Down
41 changes: 38 additions & 3 deletions lib/puppet/provider/package/powershellcore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ def update
self.class.invoke_ps_command update_command
end

# Takes an array of security protocol types, e.g. [Tls,Tls11],
# see https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype
# and produces a PowerShell command that can be used to set
# the ServicePointManager.SecurityProtocol Property,
# see https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.securityprotocol
# If securityprotocols are specified for a repository, then the
# ServicePointManager.SecurityProtocol Property needs to be set
# before any request to the repository.
# @param protocols [Array]
# @return PowerShell command
def join_protocols(protocols)
return unless protocols

command = "[Net.ServicePointManager]::SecurityProtocol = 0"
protocols.each do |val|
command << " -bor [Net.SecurityProtocolType]::#{val}"
end
command
end

# Gets the value of the securityprotocols argument from the
# specified psrepository resource and converts them into a
# PowerShell command to set the ServicePointManager.SecurityProtocol Property.
def securityprotocols(repository)
psrepo = resource.catalog.resource(:psrepository,repository)
proto = psrepo.parameters[:securityprotocols] unless psrepo.nil?
join_protocols(proto.value) unless proto.nil?
end

# Turns a array of install_options into flags to be passed to a command.
# The options can be passed as a string or hash. Note that passing a hash
# should only be used in case "-foo bar" must be passed,
Expand Down Expand Up @@ -85,7 +114,8 @@ def self.instances_command
end

def install_command
command = "Install-Module #{@resource[:name]} -Scope AllUsers -Force"
command = "#{securityprotocols(@resource[:source])};"
command << "Install-Module #{@resource[:name]} -Scope AllUsers -Force"
command << " -RequiredVersion #{@resource[:ensure]}" unless [:present, :latest].include? @resource[:ensure]
command << " -Repository #{@resource[:source]}" if @resource[:source]
command << " #{install_options(@resource[:install_options])}" if @resource[:install_options]
Expand All @@ -97,11 +127,16 @@ def uninstall_command
end

def latest_command
"$mod = Find-Module #{@resource[:name]}; $mod.Version.ToString()"
command = "#{securityprotocols(@resource[:source])};"
command << "$mod = Find-Module #{@resource[:name]}"
command << " -Repository #{@resource[:source]}" if @resource[:source]
command << "; $mod.Version.ToString()"
command
end

def update_command
command = "Install-Module #{@resource[:name]} -Scope AllUsers -Force"
command = "#{securityprotocols(@resource[:source])};"
command << "Install-Module #{@resource[:name]} -Scope AllUsers -Force"
command << " -Repository #{@resource[:source]}" if @resource[:source]
command << " #{install_options(@resource[:install_options])}" if @resource[:install_options]
command
Expand Down
21 changes: 21 additions & 0 deletions lib/puppet/provider/psrepository/powershellcore.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,34 @@ def self.instances_command
COMMAND
end

# Takes an array of security protocol types, e.g. [Tls,Tls11],
# see https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype
# and produces a PowerShell command that can be used to set
# the ServicePointManager.SecurityProtocol Property,
# see https://docs.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.securityprotocol
# If securityprotocols are specified for a repository, then the
# ServicePointManager.SecurityProtocol Property needs to be set
# before any request to the repository.
# @param protocols [Array]
# @return PowerShell command
def join_protocols(protocols)
return unless protocols

command = "[Net.ServicePointManager]::SecurityProtocol = 0"
protocols.each do |val|
command << " -bor [Net.SecurityProtocolType]::#{val}"
end
command
end

def create_command
<<-COMMAND
$params = @{
Name = '#{@resource[:name]}'
SourceLocation = '#{@resource[:source_location]}'
InstallationPolicy = '#{@resource[:installation_policy]}'
}
#{join_protocols(@resource[:securityprotocols])}
Register-PSRepository @params
COMMAND
end
Expand Down
12 changes: 12 additions & 0 deletions lib/puppet/type/psrepository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,16 @@
defaultto :untrusted
newvalues(:trusted, :untrusted)
end

newparam(:securityprotocols, :array_matching => :all) do
desc "An array of security protocols which should be used when accessing the PS repository.
See: https://docs.microsoft.com/en-us/dotnet/api/system.net.securityprotocoltype?view=netframework-4.7.2.
e.g. securityprotocols => [Tls,Tls11,TLS12]
If this is not specified the system default TLS settings will be used."

# Make sure we convert to an array.
munge do |value|
[value].flatten
end
end
end