cookbooks/firewall/libraries/helpers_windows.rb
module FirewallCookbook
module Helpers
module Windows
include FirewallCookbook::Helpers
include Chef::Mixin::ShellOut
def fixup_cidr(str)
newstr = str.clone
newstr.gsub!('0.0.0.0/0', 'any') if newstr.include?('0.0.0.0/0')
newstr.gsub!('/0', '') if newstr.include?('/0')
newstr
end
def windows_rules_filename
"#{ENV['HOME']}/windows-chef.rules"
end
def active?
@active ||= begin
cmd = shell_out!('netsh advfirewall show currentprofile')
cmd.stdout =~ /^State\sON/
end
end
def enable!
shell_out!('netsh advfirewall set currentprofile state on')
end
def disable!
shell_out!('netsh advfirewall set currentprofile state off')
end
def reset!
shell_out!('netsh advfirewall reset')
end
def add_rule!(params)
shell_out!("netsh advfirewall #{params}")
end
def delete_all_rules!
shell_out!('netsh advfirewall firewall delete rule name=all')
end
def to_type(new_resource)
cmd = new_resource.command
type = if cmd == :reject || cmd == :deny
:block
else
:allow
end
type
end
def build_rule(new_resource)
type = to_type(new_resource)
parameters = {}
parameters['description'] = "\"#{new_resource.description}\""
parameters['dir'] = new_resource.direction
new_resource.program && parameters['program'] = new_resource.program
new_resource.service && parameters['service'] = new_resource.service
parameters['protocol'] = new_resource.protocol
if new_resource.direction.to_sym == :out
parameters['localip'] = new_resource.source ? fixup_cidr(new_resource.source) : 'any'
parameters['localport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any'
parameters['interfacetype'] = new_resource.interface ? new_resource.interface : 'any'
parameters['remoteip'] = new_resource.destination ? fixup_cidr(new_resource.destination) : 'any'
parameters['remoteport'] = new_resource.dest_port ? port_to_s(new_resource.dest_port) : 'any'
else
parameters['localip'] = new_resource.destination ? new_resource.destination : 'any'
parameters['localport'] = dport_calc(new_resource) ? port_to_s(dport_calc(new_resource)) : 'any'
parameters['interfacetype'] = new_resource.dest_interface ? new_resource.dest_interface : 'any'
parameters['remoteip'] = new_resource.source ? fixup_cidr(new_resource.source) : 'any'
parameters['remoteport'] = new_resource.source_port ? port_to_s(new_resource.source_port) : 'any'
end
parameters['action'] = type.to_s
partial_command = parameters.map { |k, v| "#{k}=#{v}" }.join(' ')
"firewall add rule name=\"#{new_resource.name}\" #{partial_command}"
end
def rule_exists?(name)
@exists ||= begin
cmd = shell_out!("netsh advfirewall firewall show rule name=\"#{name}\"", returns: [0, 1])
cmd.stdout !~ /^No rules match the specified criteria/
end
end
def show_all_rules!
cmd = shell_out!('netsh advfirewall firewall show rule name=all')
cmd.stdout.each_line do |line|
Chef::Log.warn(line)
end
end
def rule_up_to_date?(name, type)
@up_to_date ||= begin
desired_parameters = rule_parameters(type)
current_parameters = {}
cmd = shell_out!("netsh advfirewall firewall show rule name=\"#{name}\" verbose")
cmd.stdout.each_line do |line|
current_parameters['description'] = "\"#{Regexp.last_match(1).chomp}\"" if line =~ /^Description:\s+(.*)$/
current_parameters['dir'] = Regexp.last_match(1).chomp if line =~ /^Direction:\s+(.*)$/
current_parameters['program'] = Regexp.last_match(1).chomp if line =~ /^Program:\s+(.*)$/
current_parameters['service'] = Regexp.last_match(1).chomp if line =~ /^Service:\s+(.*)$/
current_parameters['protocol'] = Regexp.last_match(1).chomp if line =~ /^Protocol:\s+(.*)$/
current_parameters['localip'] = Regexp.last_match(1).chomp if line =~ /^LocalIP:\s+(.*)$/
current_parameters['localport'] = Regexp.last_match(1).chomp if line =~ /^LocalPort:\s+(.*)$/
current_parameters['interfacetype'] = Regexp.last_match(1).chomp if line =~ /^InterfaceTypes:\s+(.*)$/
current_parameters['remoteip'] = Regexp.last_match(1).chomp if line =~ /^RemoteIP:\s+(.*)$/
current_parameters['remoteport'] = Regexp.last_match(1).chomp if line =~ /^RemotePort:\s+(.*)$/
current_parameters['action'] = Regexp.last_match(1).chomp if line =~ /^Action:\s+(.*)$/
end
up_to_date = true
desired_parameters.each do |k, v|
up_to_date = false if current_parameters[k] !~ /^["]?#{v}["]?$/i
end
up_to_date
end
end
end
end
end