# # Cookbook:: selinux # Resource:: port # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # unified_mode true property :port, [Integer, String], name_property: true, regex: /^\d+$/, description: 'Port to modify' property :protocol, String, equal_to: %w(tcp udp), required: %i(manage add modify), description: 'Protocol to modify' property :secontext, String, required: %i(manage add modify), description: 'SELinux context to assign to the port' action_class do include SELinux::Cookbook::StateHelpers def current_port_context # use awk to see if the given port is within a reported port range shell_out!( <<~CMD seinfo --portcon=#{new_resource.port} | grep 'portcon #{new_resource.protocol}' | \ awk -F: '$(NF-1) !~ /reserved_port_t$/ && $(NF-3) !~ /[0-9]*-[0-9]*/ {print $(NF-1)}' CMD ).stdout.split end end action :manage do run_action(:add) run_action(:modify) end action :addormodify do Chef::Log.warn('The :addormodify action for selinux_port is deprecated and will be removed in a future release. Use the :manage action instead.') run_action(:manage) end # Create if doesn't exist, do not touch if port is already registered (even under different type) action :add do if selinux_disabled? Chef::Log.warn("Unable to add SELinux port #{new_resource.name} as SELinux is disabled") return end if current_port_context.empty? converge_by "Adding context #{new_resource.secontext} to port #{new_resource.port}/#{new_resource.protocol}" do shell_out!("semanage port -a -t '#{new_resource.secontext}' -p #{new_resource.protocol} #{new_resource.port}") end end end # Only modify port if it exists & doesn't have the correct context already action :modify do if selinux_disabled? Chef::Log.warn("Unable to modify SELinux port #{new_resource.name} as SELinux is disabled") return end if !current_port_context.empty? && !current_port_context.include?(new_resource.secontext) converge_by "Modifying context #{new_resource.secontext} to port #{new_resource.port}/#{new_resource.protocol}" do shell_out!("semanage port -m -t '#{new_resource.secontext}' -p #{new_resource.protocol} #{new_resource.port}") end end end # Delete if exists action :delete do if selinux_disabled? Chef::Log.warn("Unable to delete SELinux port #{new_resource.name} as SELinux is disabled") return end unless current_port_context.empty? converge_by "Deleting context from port #{new_resource.port}/#{new_resource.protocol}" do shell_out!("semanage port -d -p #{new_resource.protocol} #{new_resource.port}") end end end