# -*- coding: binary -*-

module Msf::Exploit::Remote::HTTP::NagiosXi::Install
  include Msf::Exploit::Remote::HTTP::NagiosXi::URIs
  include Msf::Exploit::Remote::HTTP::NagiosXi::Login
  # Attempts to complete the Nagios XI web installation
  #
  # @param pass [String] Password
  # @return [nil, Array] nil if the installation seems successful, otherwise Array containing an error code and an error message
  def install_nagios_xi(pass)
    print_status('Attempting to finish the Nagios XI installation on the target using the provided password. The username will be `nagiosadmin`.')

    # Visit the install page to obtain the cookies and nsp token required for installing the app
     res_install_page = send_request_cgi({
      'method' => 'GET',
      'uri' => nagios_xi_install_url
    })

    unless res_install_page
      return [1, 'Connection failed']
    end

    unless res_install_page.code == 200 && res_install_page.body.include?('Nagios XI') && res_install_page.body.include?('install')
      return [2, 'Received unexpected reply while trying to access the Nagios XI Installer.']
    end

    install_cookies = res_install_page.get_cookies

    if install_cookies.blank?
      return [2, 'Unable to obtain the cookies required to install Nagios XI']
    end

    install_nsp = get_nsp(res_install_page)

    if install_nsp.blank?
      return [2, 'Unable to obtain the nsp token required to install Nagios XI']
    end

    # Install the app, using the provided password (the username cannot be set here, it is `nagiosadmin` by default)
    res_start_install = send_request_cgi({
      'method' => 'POST',
      'uri' => nagios_xi_install_url,
      'cookie' => install_cookies,
      'vars_post' => {
        'install' => 1,
        'nsp' => install_nsp,
        'url' => "#{full_uri(target_uri.path)}",
        'admin_name' => 'Nagios Administrator',
        'admin_email' => 'root@localhost',
        'admin_password' => password,
        'timezone' => 'UTC'
      }
    })

    unless res_start_install
      return [1, 'Connection failed']
    end

    unless res_start_install.code == 200 && res_start_install.body.include?('>Nagios XI<') && res_start_install.body.include?('login') # you may now login
      return [2, 'Received unexpected reply while trying to install Nagios XI on the target.']
    end

    # If installation succeeded, we don't need to return anything here.
    # It is better to start a new session to authenticate now, otherwise the session may timeout
    return
  end

  # Signs the Nagios XI license agreement
  #
  # @param cookies [String] cookies required to visit the license agreement page
  # @param nsp [String] nsp token required to visit the license agreement page
  # @return [nil, Array] nil if signing the license agreement succeeds, otherwise Array containing an error code and an error message
  def sign_license_agreement(cookies, nsp)
    if cookies.blank?
      return [2, 'Cannot sign the license agreement. The provided cookies are empty or nil.']
    end

    if nsp.blank?
      return [2, 'Cannot sign the license agreement. The provided `nsp_str` value is empty or nil.']
    end

    print_status('Attempting to sign the Nagios XI license agreement...')

    res_sign_license = send_request_cgi({
      'method' => 'POST',
      'uri' => nagios_xi_login_url,
      'cookie' => cookies,
      'vars_get' => { 'showlicense' => ''},
      'vars_post' => {
        'page' => nagios_xi_login_url,
        'pageopt' => 'agreelicense',
        'nsp' => nsp,
        'agree_license' => 'on'
      }
    })

    unless res_sign_license
      return [1, 'Connection failed']
    end

    unless res_sign_license.code == 302 && res_sign_license.headers['Location'].end_with?('index.php')
      return [2, 'Received unexpected reply while trying to accept the Nagios XI license agreement.']
    end

    # If signing the license agreement succeeded, we don't need to return anything here
    # It is better to start a new session to authenticate now, otherwise the session may timeout
    return
  end

end
