class Inspec::Resources::AixPorts
Public Instance Methods
info()
click to toggle source
# File lib/inspec/resources/port.rb, line 270 def info ports_via_netstat || ports_via_lsof end
parse_net_address(net_addr, protocol)
click to toggle source
# File lib/inspec/resources/port.rb, line 335 def parse_net_address(net_addr, protocol) # local/foreign addresses on AIX use a '.' to separate the addresss # from the port address, _sep, port = net_addr.rpartition(".") if protocol.eql?("tcp6") || protocol.eql?("udp6") ip6addr = address # AIX uses the wildcard character for ipv6 addresses listening on # all interfaces. ip6addr = "::" if ip6addr =~ /^\*$/ # v6 addresses need to end in a double-colon when using # shorthand notation. netstat ends with a single colon. # IPAddr will fail to properly parse an address unless it # uses a double-colon for short-hand notation. ip6addr += ":" if ip6addr =~ /\w:$/ begin ip_parser = IPAddr.new(ip6addr) rescue IPAddr::InvalidAddressError # This IP is not parsable. There appears to be a bug in netstat # output that truncates link-local IP addresses: # example: udp6 0 0 fe80::42:acff:fe11::123 :::* 0 54550 3335/ntpd # actual link address: inet6 fe80::42:acff:fe11:5/64 scope link # # in this example, the "5" is truncated making the netstat output # an invalid IP address. return [nil, nil] end # Check to see if this is a IPv4 address in a tcp6/udp6 line. # If so, don't put brackets around the IP or URI won't know how # to properly handle it. # example: f000000000000000 tcp6 0 0 127.0.0.1.8005 *.* LISTEN if ip_parser.ipv4? ip_addr = URI("addr://#{ip6addr}:#{port}") host = ip_addr.host else ip_addr = URI("addr://[#{ip6addr}]:#{port}") host = ip_addr.host[1..ip_addr.host.size - 2] end else ip4addr = address # In AIX the wildcard character is used to match all interfaces ip4addr = "0.0.0.0" if ip4addr =~ /^\*$/ ip_addr = URI("addr://#{ip4addr}:#{port}") host = ip_addr.host end [host, port.to_i] end
parse_netstat_line(line)
click to toggle source
# File lib/inspec/resources/port.rb, line 300 def parse_netstat_line(line) # parse each line # 1 - Socket, 2 - Proto, 3 - Receive-Q, 4 - Send-Q, 5 - Local address, 6 - Foreign Address, 7 - State parsed = /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)?\s+(\S+)/.match(line) return {} if parsed.nil? # parse ip4 and ip6 addresses protocol = parsed[2].downcase # detect protocol if not provided protocol += "6" if parsed[5].count(":") > 1 && %w{tcp udp}.include?(protocol) protocol.chop! if %w{tcp4 upd4}.include?(protocol) # extract host and port information host, port = parse_net_address(parsed[5], protocol) return {} if host.nil? # extract PID cmd = inspec.command("rmsock #{parsed[1]} tcpcb") parsed_pid = /^The socket (\S+) is being held by proccess (\d+) \((\S+)\)/.match(cmd.stdout) return {} if parsed_pid.nil? process = parsed_pid[3] pid = parsed_pid[2] pid = pid.to_i if pid =~ /^\d+$/ { "port" => port, "address" => host, "protocol" => protocol, "process" => process, "pid" => pid, } end
ports_via_lsof()
click to toggle source
# File lib/inspec/resources/port.rb, line 274 def ports_via_lsof return nil unless inspec.command("lsof").exist? LsofPorts.new(inspec).info end
ports_via_netstat()
click to toggle source
# File lib/inspec/resources/port.rb, line 280 def ports_via_netstat return nil unless inspec.command("netstat").exist? cmd = inspec.command("netstat -Aan | grep LISTEN") return nil unless cmd.exit_status.to_i == 0 ports = [] # parse all lines cmd.stdout.each_line do |line| port_info = parse_netstat_line(line) # only push protocols we are interested in next unless %w{tcp tcp6 udp udp6}.include?(port_info["protocol"]) ports.push(port_info) end ports end