hpux support for basic port properties

This commit is contained in:
Anirudh Gupta 2016-05-03 14:30:59 +05:30
parent f61c9d030e
commit d839f218bf
5 changed files with 88 additions and 4 deletions

View file

@ -3,7 +3,7 @@
# author: Dominik Richter # author: Dominik Richter
require 'utils/parser' require 'utils/parser'
require 'pry'
# Usage: # Usage:
# describe port(80) do # describe port(80) do
# it { should be_listening } # it { should be_listening }
@ -47,6 +47,8 @@ module Inspec::Resources
@port_manager = FreeBsdPorts.new(inspec) @port_manager = FreeBsdPorts.new(inspec)
elsif os.solaris? elsif os.solaris?
@port_manager = SolarisPorts.new(inspec) @port_manager = SolarisPorts.new(inspec)
elsif os.hpux?
@port_manager = HpuxPorts.new(inspec)
else else
return skip_resource 'The `port` resource is not supported on your OS yet.' return skip_resource 'The `port` resource is not supported on your OS yet.'
end end
@ -292,7 +294,6 @@ module Inspec::Resources
# parse each line # parse each line
# 1 - Proto, 2 - Recv-Q, 3 - Send-Q, 4 - Local Address, 5 - Foreign Address, 6 - State, 7 - Inode, 8 - PID/Program name # 1 - Proto, 2 - Recv-Q, 3 - Send-Q, 4 - Local Address, 5 - Foreign Address, 6 - State, 7 - Inode, 8 - PID/Program name
parsed = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)?\s+(\S+)\s+(\S+)\s+(\S+)/.match(line) parsed = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)?\s+(\S+)\s+(\S+)\s+(\S+)/.match(line)
return {} if parsed.nil? || line.match(/^proto/i) return {} if parsed.nil? || line.match(/^proto/i)
# parse ip4 and ip6 addresses # parse ip4 and ip6 addresses
@ -408,7 +409,7 @@ module Inspec::Resources
# parse the content # parse the content
netstat_ports = parse_netstat(cmd.stdout) netstat_ports = parse_netstat(cmd.stdout)
# filter all ports, where we listen # filter all ports, where we `listen`
listen = netstat_ports.select { |val| listen = netstat_ports.select { |val|
!val['state'].nil? && 'listen'.casecmp(val['state']) == 0 !val['state'].nil? && 'listen'.casecmp(val['state']) == 0
} }
@ -433,4 +434,48 @@ module Inspec::Resources
ports ports
end end
end end
# extracts information from netstat for hpux
class HpuxPorts < FreeBsdPorts
def info
## Can't use 'netstat -an -f inet -f inet6' as the latter -f option overrides the former one and return only inet ports
cmd1 = inspec.command('netstat -an -f inet')
return nil if cmd1.exit_status.to_i != 0
cmd2 = inspec.command('netstat -an -f inet6')
return nil if cmd2.exit_status.to_i != 0
cmd = cmd1.stdout + cmd2.stdout
ports = []
# parse all lines
cmd.each_line do |line|
port_info = parse_netstat_line(line)
next unless %w{tcp tcp6 udp udp6}.include?(port_info[:protocol])
ports.push(port_info)
end
# select all ports, where we `listen`
ports.select { |val| val if 'listen'.casecmp(val[:state]) == 0 }
end
def parse_netstat_line(line)
# parse each line
# 1 - Proto, 2 - Recv-Q, 3 - Send-Q, 4 - Local Address, 5 - Foreign Address, 6 - (state)
parsed = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)?/.match(line)
return {} if parsed.nil? || line.match(/^proto/i) || line.match(/^active/i)
protocol = parsed[1].downcase
state = parsed[6].nil?? ' ' : parsed[6].downcase
local_addr = parsed[4]
local_addr[local_addr.rindex('.')] = ':'
# extract host and port information
host, port = parse_net_address(local_addr, protocol)
# map data
{
port: port,
address: host,
protocol: protocol,
state: state,
process: nil,
pid: nil,
}
end
end
end end

View file

@ -246,7 +246,11 @@ class MockLoader
#user info on hpux #user info on hpux
"logins -x -l root" => cmd.call('logins-x'), "logins -x -l root" => cmd.call('logins-x'),
#packages on hpux #packages on hpux
"swlist -l product | grep vim" => cmd.call('swlist-l-product') "swlist -l product | grep vim" => cmd.call('swlist-l-product'),
# ipv4 ports on hpux
'netstat -an -f inet' => cmd.call('netstat-inet'),
#ipv6 ports on hpux
'netstat -an -f inet6' => cmd.call('netstat-inet6'),
} }
@backend @backend

View file

@ -0,0 +1,10 @@
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp 0 0 *.515 *.* LISTEN
tcp 0 28 16.147.37.141.22 16.180.154.172.64145 ESTABLISHED
tcp 0 0 *.22 *.* LISTEN
tcp 0 0 *.49196 *.* LISTEN
tcp 0 0 16.147.37.141.49399 16.147.37.141.1712 ESTABLISHED
tcp 0 0 127.0.0.1.49433 *.* LISTEN
udp 0 0 127.0.0.1.49178 127.0.0.1.49178
udp 0 0 *.49153 *.*

View file

@ -0,0 +1,11 @@
Active Internet connections (IPv6, including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
tcp6 0 0 ::1.49309 *.* LISTEN
tcp6 0 0 *.21 *.* LISTEN
tcp6 0 0 ::1.49671 ::1.49400 ESTABLISHED
tcp6 0 0 *.383 *.* LISTEN
tcp6 0 0 *.22 *.* LISTEN
tcp6 0 0 ::1.49403 ::1.49400 ESTABLISHED
tcp6 0 0 ::1.62538 ::1.62537 TIME_WAIT
udp6 0 0 *.514 *.*
udp6 0 0 *.9 *.*

View file

@ -92,4 +92,18 @@ describe 'Inspec::Resources::Port' do
_(resource.listening?).must_equal true _(resource.listening?).must_equal true
_(resource.addresses).must_equal ["0.0.0.0"] _(resource.addresses).must_equal ["0.0.0.0"]
end end
it 'verify port on hpux' do
resource = MockLoader.new(:hpux).load_resource('port', 22)
_(resource.listening?).must_equal true
_(resource.protocols).must_equal %w{ tcp tcp6 }
_(resource.addresses).must_equal ["0.0.0.0", "0:0:0:0:0:0:0:0" ]
end
it 'verify not listening port on hpux' do
resource = MockLoader.new(:hpux).load_resource('port', 23)
_(resource.listening?).must_equal false
_(resource.protocols).must_equal nil
_(resource.addresses).must_equal nil
end
end end