# -*- coding: binary -*-

module Msf::Exploit::Remote::HTTP::Joomla::Version

  # Returns the Joomla version.
  #
  # @return [String] Joomla version (if found)
  # @return [NilClass] No Joomla version found.
  def joomla_version
    files = [
      'administrator/manifests/files/joomla.xml',
      'language/en-GB/en-GB.xml',
      'templates/system/css/system.css',
      'media/system/js/mootools-more.js',
      'language/en-GB/en-GB.ini',
      'htaccess.txt',
      'language/en-GB/en-GB.com_media.ini'
    ]

    files.each do |file|
      version = check_file_version(file)
      return version if version
    end

    nil
  end

  private

  # Returns the Joomla version based on a response.
  #
  # @param res [Rex::Proto::Http::Response] Response to fingerprint from.
  # @return [String] Joomla version (if found)
  # @return [NilClass] No Joomla version found.
  def fingerprint(res)
    version = nil

    case res.body
    when /<version.*\/?>[[:print:]]+<\/version\/?>/i
      version = res.get_html_document.at('version').text
    when /system\.css 20196 2011\-01\-09 02\:40\:25Z ian/,
      /MooTools\.More\=\{version\:\"1\.3\.0\.1\"/,
      /en-GB\.ini 20196 2011\-01\-09 02\:40\:25Z ian/,
      /en-GB\.ini 20990 2011\-03\-18 16\:42\:30Z infograf768/,
      /20196 2011\-01\-09 02\:40\:25Z ian/
      version = '1.6'
    when /system\.css 21322 2011\-05\-11 01\:10\:29Z dextercowley /,
      /MooTools\.More\=\{version\:\"1\.3\.2\.1\"/,
      /22183 2011\-09\-30 09\:04\:32Z infograf768/,
      /21660 2011\-06\-23 13\:25\:32Z infograf768/
      version = '1.7'
    when /Joomla! 1\.5/,
      /MooTools\=\{version\:\'1\.12\'\}/,
      /11391 2009\-01\-04 13\:35\:50Z ian/
      version = '1.5'
    when /Copyright \(C\) 2005 \- 2012 Open Source Matters/,
      /MooTools.More\=\{version\:\"1\.4\.0\.1\"/
      version = '2.5'
    when /<meta name=\"Keywords\" content=\"(.*)\">\s+<meta name/
      version = $1.split(/,/)[0]
    when /(Copyright \(C\) 2005 \- 200(6|7))/,
      /47 2005\-09\-15 02\:55\:27Z rhuk/,
      /423 2005\-10\-09 18\:23\:50Z stingrey/,
      /1005 2005\-11\-13 17\:33\:59Z stingrey/,
      /1570 2005\-12\-29 05\:53\:33Z eddieajau/,
      /2368 2006\-02\-14 17\:40\:02Z stingrey/,
      /4085 2006\-06\-21 16\:03\:54Z stingrey/,
      /4756 2006\-08\-25 16\:07\:11Z stingrey/,
      /5973 2006\-12\-11 01\:26\:33Z robs/,
      /5975 2006\-12\-11 01\:26\:33Z robs/
      version = '1.0'
    end

    version
  end

  # Returns the Joomla version based on a file path.
  #
  # @param file [String] File path to check.
  # @return [String] Joomla version (if found)
  # @return [NilClass] No Joomla version found.
  def check_file_version(file)
    version = nil

    res = send_request_cgi({
      'uri' => normalize_uri(target_uri.path, file)
    })

    if res && res.code == 200
      version = fingerprint(res)
    end

    version
  end

end
