ronin-rb/ronin-recon

View on GitHub
lib/ronin/recon/value/parser.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true
#
# ronin-recon - A micro-framework and tool for performing reconnaissance.
#
# Copyright (c) 2023-2024 Hal Brodigan (postmodern.mod3@gmail.com)
#
# ronin-recon 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-recon 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-recon.  If not, see <https://www.gnu.org/licenses/>.
#

require_relative '../values/host'
require_relative '../values/domain'
require_relative '../values/wildcard'
require_relative '../values/ip'
require_relative '../values/ip_range'
require_relative '../values/website'
require_relative '../exceptions'

require 'ronin/support/network/ip'
require 'ronin/support/network/ip_range'
require 'ronin/support/text/patterns/network'
require 'ronin/support/network/public_suffix'

require 'ipaddr'
require 'uri'

module Ronin
  module Recon
    #
    # Base class for all {Values} classes.
    #
    class Value

      #
      # Module that parses strings into {Values::IP}, {Values::IPRange},
      # {Values::Domain}, {Values::Host}, or {Values::Website}.
      #
      module Parser
        # Regular expression to match IPv4 and IPv6 addresses.
        IP_REGEX = Support::Network::IP::REGEX

        # Regular expression to match IPv4 and IPv6 CIDR ranges.
        IP_RANGE_REGEX = Support::Network::IPRange::REGEX

        # Regular expression to match sub-domain host-names.
        HOSTNAME_REGEX = /\A(?:[a-zA-Z0-9_-]{1,63}\.)+#{Support::Text::Patterns::DOMAIN}\z/

        # Regular expression to match domain host-names.
        DOMAIN_REGEX = /\A#{Support::Text::Patterns::DOMAIN}\z/

        # Regular expression to match wildcard host-names.
        WILDCARD_REGEX = /\A\*(?:\.[a-z0-9_-]+)+\z/

        # Regular expression to match https:// and http:// website base URLs.
        WEBSITE_REGEX = %r{\Ahttp(?:s)?://[a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*(?::\d+)?/?\z}

        #
        # Parses a value string.
        #
        # @param [String] string
        #   The string to parse.
        #
        # @return [Values::IP, Values::IPRange, Values::Host, Values::Domain, Values::Wildcard, Values::Website]
        #   The parsed value.
        #
        # @raise [UnknownValue]
        #   Could not identify what value the string represents.
        #
        def self.parse(string)
          case string
          when IP_REGEX       then Values::IP.new(string)
          when IP_RANGE_REGEX then Values::IPRange.new(string)
          when WEBSITE_REGEX  then Values::Website.parse(string)
          when WILDCARD_REGEX then Values::Wildcard.new(string)
          when HOSTNAME_REGEX then Values::Host.new(string)
          when DOMAIN_REGEX   then Values::Domain.new(string)
          else
            raise(UnknownValue,"unrecognized recon value: #{string.inspect}")
          end
        end
      end

      #
      # Parses a value string.
      #
      # @param [String] string
      #   The string to parse.
      #
      # @return [Values::IP, Values::IPRange, Values::Host, Values::Domain, Values::Wildcard, Values::Website]
      #   The parsed value.
      #
      # @raise [UnknownValue]
      #   Could not identify what value the string represents.
      #
      # @see Parser.parse
      #
      def self.parse(string)
        Parser.parse(string)
      end

    end
  end
end