ronin-rb/ronin-nmap

View on GitHub
lib/ronin/nmap/converter.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true
#
# ronin-nmap - A Ruby library for automating nmap and importing nmap scans.
#
# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
#
# ronin-nmap is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-nmap is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ronin-nmap.  If not, see <https://www.gnu.org/licenses/>.
#

require_relative 'converters'

require 'nmap/xml'

module Ronin
  module Nmap
    #
    # Handles converting nmap XML into other formats.
    #
    # Supports the following formats:
    #
    # * JSON
    # * CSV
    #
    # @api public
    #
    module Converter
      # Mapping of file extension names to formats.
      #
      # @api private
      FILE_FORMATS = {
        '.json' => :json,
        '.csv'  => :csv
      }

      #
      # Converts an nmap XML scan file into another format.
      #
      # @param [String] src
      #   The input XML file path.
      #
      # @param [String] dest
      #   The output file path.
      #
      # @api public
      #
      def self.convert_file(src,dest, format: infer_format_for(dest))
        xml       = ::Nmap::XML.open(src)
        converter = Converters[format]

        File.open(dest,'w') do |output|
          converter.convert(xml,output)
        end
      end

      #
      # Converts parsed nmap XML into the desired format.
      #
      # @param [::Nmap::XML] xml
      #   The nmap XML to convert.
      #
      # @param [IO, nil] output
      #   Optional output to write the converted output to.
      #
      # @param [:json, :csv] format
      #   The desired convert to convert the parsed nmap XML to.
      #
      # @return [String]
      #   The converted nmap XML.
      #
      # @api public
      #
      def self.convert(xml,output=nil, format: )
        if output
          Converters[format].convert(xml,output)
        else
          output = StringIO.new
          convert(xml,output, format: format)
          output.string
        end
      end

      #
      # Infers the output format from the output file's extension.
      #
      # @param [String] path
      #   The output file name.
      #
      # @return [:json, :csv]
      #   The conversion format.
      #
      # @raise [ArgumentError]
      #   The format could not be inferred from the path's file extension.
      #
      # @api private
      #
      def self.infer_format_for(path)
        FILE_FORMATS.fetch(File.extname(path)) do
          raise(ArgumentError,"cannot infer output format from path: #{path.inspect}")
        end
      end
    end
  end
end