Class: Inspec::Resources::LsofPorts
- Defined in:
- lib/inspec/resources/port.rb
Overview
extracts udp and tcp ports from the lsof command
Instance Attribute Summary collapse
-
#lsof ⇒ Object
readonly
Returns the value of attribute lsof.
Attributes inherited from PortsInfo
Instance Method Summary collapse
- #info ⇒ Object
-
#initialize(inspec, lsofpath = nil) ⇒ LsofPorts
constructor
A new instance of LsofPorts.
-
#lsof_parser(lsof_cmd) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/AbcSize.
Constructor Details
#initialize(inspec, lsofpath = nil) ⇒ LsofPorts
Returns a new instance of LsofPorts.
167 168 169 170 |
# File 'lib/inspec/resources/port.rb', line 167 def initialize(inspec, lsofpath = nil) @lsof = lsofpath || "lsof" super(inspec) end |
Instance Attribute Details
#lsof ⇒ Object (readonly)
Returns the value of attribute lsof.
165 166 167 |
# File 'lib/inspec/resources/port.rb', line 165 def lsof @lsof end |
Instance Method Details
#info ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/inspec/resources/port.rb', line 172 def info ports = [] # check that lsof is available, otherwise fail raise "Please ensure `lsof` is available on the machine." unless inspec.command(@lsof.to_s).exist? # -F p=pid, c=command, P=protocol name, t=type, n=internet addresses # see 'OUTPUT FOR OTHER PROGRAMS' in LSOF(8) lsof_cmd = inspec.command("#{@lsof} -nP -i -FpctPn") return nil if lsof_cmd.exit_status.to_i != 0 # map to desired return struct lsof_parser(lsof_cmd).each do |process, port_ids| pid, cmd = process.split(":") port_ids.each do |port_str| # should not break on ipv6 addresses ipv, proto, port, host = port_str.split(":", 4) ports.push({ "port" => port.to_i, "address" => host, "protocol" => ipv == "ipv6" ? proto + "6" : proto, "process" => cmd, "pid" => pid.to_i }) end end ports end |
#lsof_parser(lsof_cmd) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/AbcSize
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/inspec/resources/port.rb', line 202 def lsof_parser(lsof_cmd) procs = {} # build this with formatted output (-F) from lsof # procs = { # '123:sshd' => [ # 'ipv4:tcp:22:127.0.0.1', # 'ipv6:tcp:22:::1', # 'ipv4:tcp:*', # 'ipv6:tcp:*', # ], # '456:ntpd' => [ # 'ipv4:udp:123:*', # 'ipv6:udp:123:*', # ] # } proc_id = port_id = nil lsof_cmd.stdout.each_line do |line| line.chomp! key = line.slice!(0) case key when "p" proc_id = line port_id = nil when "c" proc_id += ":" + line when "t" port_id = line.downcase when "P" port_id += ":" + line.downcase when "n" src, dst = line.split("->") # skip active comm streams next if dst host, port = /^(\S+):(\d+|\*)$/.match(src)[1, 2] # skip channels from port 0 - what does this mean? next if port == "*" # create new array stub if !exist? procs[proc_id] = [] unless procs.key?(proc_id) # change address '*' to zero host = port_id =~ /^ipv6:/ ? "[::]" : "0.0.0.0" if host == "*" # entrust URI to scrub the host and port begin uri = URI("addr://#{host}:#{port}") uri.host && uri.port rescue => e warn "could not parse URI 'addr://#{host}:#{port}' - #{e}" next end # e.g. 'ipv4:tcp:22:127.0.0.1' # strip ipv6 squares for inspec port_id += ":" + port + ":" + host.gsub(/^\[|\]$/, "") # lsof will give us another port unless it's done procs[proc_id] << port_id end end procs end |