# -*- coding: binary -*-

require 'net/ssh'

# Include this mixin if you want just the SSH datastore options
# (e.g., when using Metasploit::Framework::LoginScanner::SSH)
module Msf::Exploit::Remote::SSH
module Options

  def initialize(info = {})
    # HACK: Suppress already initialized constant warning
    verbose, $VERBOSE = $VERBOSE, nil

    super

    register_options([Msf::Opt::RHOST, Msf::Opt::RPORT(22)])

    register_advanced_options([
      # See Msf::Ui::Console::Driver#on_variable_set
      Msf::OptString.new(
        'SSH_IDENT',
        [
          true,
          'SSH client identification string',
          'SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3' # Ubuntu 18.04 LTS
        ]
      ),
      # Ugh, why weren't these advanced options CamelCase?
      Msf::OptInt.new(
        'SSH_TIMEOUT',
        [
          false,
          'Maximum SSH negotiation/authentication time in seconds',
          10
        ]
      ),
      Msf::OptBool.new(
        'SSH_DEBUG',
        [
          false,
          'Enable output of SSH protocol debugging information',
          false
        ]
      )
    ])

    # HACK: Bypass dynamic constant assignment error
    ::Net::SSH::Transport::ServerVersion.const_set(
      :PROTO_VERSION,
      datastore['SSH_IDENT']
    )
  ensure
    # Restore warning
    $VERBOSE = verbose
  end

  def rhost
    datastore['RHOST']
  end

  def rport
    datastore['RPORT']
  end

  def peer
    "#{rhost}:#{rport}"
  end

end
end
