Add tests for optional session mixins

This commit is contained in:
Dean Welch 2024-02-23 17:12:25 +00:00
parent 244e20a3d5
commit 559ab0f10d
6 changed files with 254 additions and 0 deletions

View File

@ -47,4 +47,92 @@ RSpec.describe Msf::OptionGroup do
end
end
end
describe '#validate' do
let(:required_option_name) { 'required_name' }
let(:option_names) { ['not_required_name', required_option_name] }
let(:required_names) { [required_option_name] }
let(:options) { instance_double(Msf::OptionContainer) }
let(:datastore) { instance_double(Msf::DataStoreWithFallbacks) }
context 'when there are no required options' do
subject { described_class.new(name: 'name', description: 'description', option_names: option_names) }
context 'when no values are set for the options' do
before(:each) do
allow(options).to receive(:[]).and_return(instance_double(Msf::OptBase))
allow(datastore).to receive(:[]).and_return(nil)
end
it 'validates the options in the group' do
expect { subject.validate(options, datastore) }.not_to raise_error(Msf::OptionValidateError)
end
end
context 'when values are set for the options' do
before(:each) do
allow(options).to receive(:[]).and_return(instance_double(Msf::OptBase))
allow(datastore).to receive(:[]).and_return('OptionValue')
end
it 'validates the options in the group' do
expect { subject.validate(options, datastore) }.not_to raise_error(Msf::OptionValidateError)
end
end
context 'when the options have not been registered' do
before(:each) do
allow(options).to receive(:[]).and_return(nil)
end
it 'does not attempt to validate the options' do
expect { subject.validate(options, datastore) }.not_to raise_error(Msf::OptionValidateError)
end
end
end
context 'when there is a required option' do
subject { described_class.new(name: 'name', description: 'description', option_names: option_names, required_options: required_names) }
let(:error_message) { "The following options failed to validate: #{required_option_name}." }
context 'when no values are set for the options' do
before(:each) do
allow(options).to receive(:[]).and_return(instance_double(Msf::OptBase))
allow(datastore).to receive(:[]).and_return(nil)
end
it 'raises an error only for the required option' do
expect { subject.validate(options, datastore) }.to raise_error(Msf::OptionValidateError).with_message(error_message)
end
end
context 'when values are set for the options' do
before(:each) do
allow(options).to receive(:[]).and_return(instance_double(Msf::OptBase))
allow(datastore).to receive(:[]).and_return('OptionValue')
end
it 'validates the options in the group' do
expect { subject.validate(options, datastore) }.not_to raise_error(Msf::OptionValidateError)
end
end
context 'when the options have not been registered' do
before(:each) do
allow(options).to receive(:[]).and_return(nil)
end
it 'does not attempt to validate the options' do
expect { subject.validate(options, datastore) }.not_to raise_error(Msf::OptionValidateError)
end
end
end
end
end

View File

@ -0,0 +1,14 @@
# -*- coding:binary -*-
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Msf::OptionalSession::MSSQL do
subject(:mod) do
mod = ::Msf::Module.new
mod.extend described_class
mod
end
it_behaves_like Msf::OptionalSession
end

View File

@ -0,0 +1,14 @@
# -*- coding:binary -*-
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Msf::OptionalSession::MySQL do
subject(:mod) do
mod = ::Msf::Module.new
mod.extend described_class
mod
end
it_behaves_like Msf::OptionalSession
end

View File

@ -0,0 +1,14 @@
# -*- coding:binary -*-
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Msf::OptionalSession::PostgreSQL do
subject(:mod) do
mod = ::Msf::Module.new
mod.extend described_class
mod
end
it_behaves_like Msf::OptionalSession
end

View File

@ -0,0 +1,14 @@
# -*- coding:binary -*-
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Msf::OptionalSession::SMB do
subject(:mod) do
mod = ::Msf::Module.new
mod.extend described_class
mod
end
it_behaves_like Msf::OptionalSession
end

View File

@ -0,0 +1,110 @@
# -*- coding:binary -*-
# frozen_string_literal: true
require 'spec_helper'
RSpec.shared_examples_for Msf::OptionalSession do
include_context 'Msf::Simple::Framework'
let(:options) { instance_double(Msf::OptionContainer) }
let(:datastore) { instance_double(Msf::DataStoreWithFallbacks) }
let(:session) { instance_double(Msf::Sessions::SMB) }
let(:session_group) { instance_double(Msf::OptionGroup) }
let(:rhost_group) { instance_double(Msf::OptionGroup) }
let(:groups) do
{
'SESSION' => session_group,
'RHOST' => rhost_group
}
end
describe '#validate' do
before(:each) do
allow(options).to receive(:validate)
allow(options).to receive(:[]).and_return(instance_double(Msf::OptBase))
allow(options).to receive(:groups).and_return(groups)
allow(mod).to receive(:options).and_return(options)
allow(mod).to receive(:datastore).and_return(datastore)
allow(mod).to receive(:framework).and_return(framework)
allow(session_group).to receive(:validate)
allow(rhost_group).to receive(:validate)
end
context 'when neither SESSION or RHOST are set' do
before(:each) do
allow(mod).to receive(:rhost).and_return(nil)
allow(mod).to receive(:session).and_return(nil)
end
it 'raises an error' do
expect { mod.validate }.to raise_error(Msf::OptionValidateError).with_message('A SESSION or RHOST must be provided')
end
end
context 'when both SESSION and RHOST are set' do
before(:each) do
allow(datastore).to receive(:[]).with('SESSION').and_return('SESSION_ID')
allow(datastore).to receive(:[]).with('RHOST').and_return('RHOST_VALUE')
allow(mod).to receive(:session).and_return(session)
allow(mod).to receive(:rhost).and_return('RHOST_VALUE')
end
it 'validates the SESSION only' do
mod.validate
expect(session_group).to have_received(:validate).once
expect(rhost_group).not_to have_received(:validate)
end
end
context 'when only RHOST is set' do
before(:each) do
allow(datastore).to receive(:[]).with('RHOST').and_return('RHOST_VALUE')
allow(datastore).to receive(:[]).with('SESSION').and_return(nil)
allow(mod).to receive(:rhost).and_return('RHOST_VALUE')
allow(mod).to receive(:session).and_return(nil)
end
it 'only validates the RHOST group' do
mod.validate
expect(rhost_group).to have_received(:validate).once
expect(session_group).not_to have_received(:validate)
end
end
context 'when only SESSION is set' do
before(:each) do
allow(datastore).to receive(:[]).with('SESSION').and_return('SESSION_ID')
allow(datastore).to receive(:[]).with('RHOST').and_return(nil)
allow(mod).to receive(:session).and_return(session)
allow(mod).to receive(:rhost).and_return(nil)
end
it 'validates the SESSION only' do
mod.validate
expect(session_group).to have_received(:validate).once
expect(rhost_group).not_to have_received(:validate)
end
context 'when the session is not the correct type' do
before(:each) do
allow(mod).to receive(:session_types).and_return(['correct_session_type'])
allow(session).to receive(:type).and_return('wrong_session_type')
end
it 'should raise an error about the wrong session type' do
expect { mod.validate }.to raise_error(Msf::OptionValidateError) { |error| expect(error.options).to eq ['SESSION'] }
end
end
context 'when the session is the correct type' do
before(:each) do
allow(mod).to receive(:session_types).and_return(['correct_session_type'])
allow(session).to receive(:type).and_return('correct_session_type')
end
it 'should raise an error about the wrong session type' do
expect { mod.validate }.not_to raise_error
end
end
end
end
end