130 lines
4.9 KiB
Ruby
130 lines
4.9 KiB
Ruby
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
|
|
if cmd == :reject || cmd == :deny
|
|
:block
|
|
else
|
|
:allow
|
|
end
|
|
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 || '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 || 'any'
|
|
parameters['localport'] = dport_calc(new_resource) ? port_to_s(dport_calc(new_resource)) : 'any'
|
|
parameters['interfacetype'] = 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
|