Skip to content

Commit 1c3b43b

Browse files
authored
Merge pull request #7 from clee-r7/MS-2891
Land #7, fix test issues
2 parents 6ffae7f + dd65141 commit 1c3b43b

File tree

13 files changed

+81
-107
lines changed

13 files changed

+81
-107
lines changed

lib/metasploit/framework/data_service/proxy/core.rb

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
require 'singleton'
21
require 'open3'
32
require 'rex/ui'
43
require 'rex/logging'
5-
require 'msf/core/db_manager'
64
require 'metasploit/framework/data_service/remote/http/core'
75
require 'metasploit/framework/data_service/remote/http/remote_service_endpoint'
86
require 'metasploit/framework/data_service/proxy/data_proxy_auto_loader'
@@ -15,11 +13,17 @@ module Metasploit
1513
module Framework
1614
module DataService
1715
class DataProxy
18-
include Singleton
1916
include DataProxyAutoLoader
2017

2118
attr_reader :usable
2219

20+
def initialize(opts = {})
21+
@data_services = {}
22+
@data_service_id = 0
23+
@usable = false
24+
setup(opts)
25+
end
26+
2327
#
2428
# Returns current error state
2529
#
@@ -48,34 +52,6 @@ def active
4852
return false
4953
end
5054

51-
#
52-
# Initializes the data service to be used - primarily on startup
53-
#
54-
def init(framework, opts)
55-
@mutex.synchronize {
56-
if (@initialized)
57-
return
58-
end
59-
60-
begin
61-
if (opts['DisableDatabase'])
62-
@error = 'disabled'
63-
return
64-
elsif (opts['DatabaseRemoteProcess'])
65-
run_remote_db_process(opts)
66-
else
67-
run_local_db_process(framework, opts)
68-
end
69-
@usable = true
70-
@initialized = true
71-
rescue Exception => e
72-
puts "Unable to initialize a dataservice #{e.message}"
73-
return
74-
end
75-
}
76-
77-
end
78-
7955
#
8056
# Registers a data service with the proxy and immediately
8157
# set as primary if online
@@ -131,6 +107,14 @@ def method_missing(method, *args, &block)
131107
end
132108
end
133109

110+
def respond_to?(method_name, include_private=false)
111+
unless @data_service.nil?
112+
return @data_service.respond_to?(method_name, include_private)
113+
end
114+
115+
false
116+
end
117+
134118
#
135119
# Attempt to shutdown the local db process if it exists
136120
#
@@ -145,10 +129,6 @@ def exit_called
145129
end
146130
end
147131

148-
#########
149-
protected
150-
#########
151-
152132
def get_data_service
153133
raise 'No registered data_service' unless @data_service
154134
return @data_service
@@ -158,12 +138,21 @@ def get_data_service
158138
private
159139
#######
160140

161-
def initialize
162-
@data_services = {}
163-
@data_service_id = 0
164-
@usable = false
165-
@initialized = false
166-
@mutex = Mutex.new()
141+
def setup(opts)
142+
begin
143+
db_manager = opts.delete(:db_manager)
144+
if !db_manager.nil?
145+
register_data_service(db_manager, true)
146+
@usable = true
147+
elsif opts['DatabaseRemoteProcess']
148+
run_remote_db_process(opts)
149+
@usable = true
150+
else
151+
@error = 'disabled'
152+
end
153+
rescue Exception => e
154+
puts "Unable to initialize a dataservice #{e.message}"
155+
end
167156
end
168157

169158
def validate(data_service)
@@ -183,15 +172,6 @@ def data_service_exist?(data_service)
183172
end
184173

185174

186-
def run_local_db_process(framework, opts)
187-
puts 'Initializing local db process'
188-
db_manager = Msf::DBManager.new(framework)
189-
if (db_manager.usable and not opts['SkipDatabaseInit'])
190-
register_data_service(db_manager, true)
191-
db_manager.init_db(opts)
192-
end
193-
end
194-
195175
def run_remote_db_process(opts)
196176
# started with no signal to prevent ctrl-c from taking out db
197177
db_script = File.join( Msf::Config.install_root, "msfdb -ns")

lib/msf/core/db_manager/connection.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def after_establish_connection
1818
migrate
1919

2020
# Set the default workspace
21-
framework.db.workspace = framework.db.default_workspace
21+
self.workspace = self.default_workspace
2222
rescue ::Exception => exception
2323
self.error = exception
2424
elog("DB.connect threw an exception: #{exception}")

lib/msf/core/db_manager/host.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def each_host(wspace=workspace, &block)
5656

5757
# Exactly like report_host but waits for the database to create a host and returns it.
5858
def find_or_create_host(opts)
59-
host = get_host(opts)
59+
host = get_host(opts.clone)
6060
return host unless host.nil?
6161

6262
report_host(opts)

lib/msf/core/db_manager/workspace.rb

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,20 +58,23 @@ def workspace_associations_counts()
5858
end
5959

6060
def delete_all_workspaces()
61-
delete_workspaces(workspaces.map(&:name))
61+
return delete_workspaces(workspaces.map(&:name))
6262
end
6363

6464
def delete_workspaces(names)
65+
status_msg = []
66+
error_msg = []
67+
6568
switched = false
6669
# Delete workspaces
6770
names.each do |name|
6871
workspace = framework.db.find_workspace(name)
6972
if workspace.nil?
70-
print_error("Workspace not found: #{name}")
73+
error << "Workspace not found: #{name}"
7174
elsif workspace.default?
7275
workspace.destroy
7376
workspace = framework.db.add_workspace(name)
74-
print_status("Deleted and recreated the default workspace")
77+
status_msg << 'Deleted and recreated the default workspace'
7578
else
7679
# switch to the default workspace if we're about to delete the current one
7780
if framework.db.workspace.name == workspace.name
@@ -80,10 +83,11 @@ def delete_workspaces(names)
8083
end
8184
# now destroy the named workspace
8285
workspace.destroy
83-
print_status("Deleted workspace: #{name}")
86+
status_msg << "Deleted workspace: #{name}"
8487
end
8588
end
86-
print_status("Switched workspace: #{framework.db.workspace.name}") if switched
89+
(status_msg << "Switched workspace: #{framework.db.workspace.name}") if switched
90+
return status_msg, error_msg
8791
end
8892

8993
#

lib/msf/core/framework.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def version
199199
# @return [Metasploit::Framework::DataService::DataProxy]
200200
def db
201201
synchronize {
202-
@db ||= Metasploit::Framework::DataService::DataProxy.instance
202+
@db ||= get_db
203203
}
204204
end
205205

@@ -268,6 +268,19 @@ def search(match, logger: nil)
268268
attr_writer :db # :nodoc:
269269
attr_writer :uuid_db # :nodoc:
270270
attr_writer :browser_profiles # :nodoc:
271+
272+
private
273+
274+
def get_db
275+
if !options['DatabaseRemoteProcess'] && !options['DisableDatabase']
276+
db_manager = Msf::DBManager.new(self)
277+
db_manager.init_db(options)
278+
options[:db_manager] = db_manager
279+
end
280+
281+
Metasploit::Framework::DataService::DataProxy.new(options)
282+
end
283+
271284
end
272285

273286
class FrameworkEventSubscriber

lib/msf/core/modules/metadata/store.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def configure_user_store
104104

105105
def get_user_store
106106
store_dir = ::File.join(Msf::Config.config_directory, "store")
107-
FileUtils.mkdir(store_dir) if !::File.exist?(store_dir)
107+
FileUtils.makedirs(store_dir) if !::File.exist?(store_dir)
108108
return ::File.join(store_dir, UserMetaDataFile)
109109
end
110110

lib/msf/ui/console/command_dispatcher/creds.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,6 @@ def creds_search(*args)
393393
}
394394

395395
tbl = Rex::Text::Table.new(tbl_opts)
396-
opts = {}
397396
opts[:wspace] = framework.db.workspace
398397
query = framework.db.creds(opts)
399398

lib/msf/ui/console/command_dispatcher/db.rb

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,11 @@ def active?
9090
end
9191

9292
def cmd_set_data_service(service_id)
93-
data_proxy = Metasploit::Framework::DataService::DataProxy.instance
94-
data_proxy.set_data_service(service_id)
93+
framework.db.set_data_service(service_id)
9594
end
9695

9796
def cmd_list_data_services()
98-
data_service_manager = Metasploit::Framework::DataService::DataProxy.instance
99-
data_service_manager.print_data_services
97+
framework.db.print_data_services
10098
end
10199

102100
def cmd_add_data_service(*args)
@@ -111,8 +109,7 @@ def cmd_add_data_service(*args)
111109

112110
remote_service_endpoint = Metasploit::Framework::DataService::RemoteServiceEndpoint.new(host, port)
113111
remote_data_service = Metasploit::Framework::DataService::RemoteHTTPDataService.new(remote_service_endpoint)
114-
data_service_manager = Metasploit::Framework::DataService::DataProxy.instance
115-
data_service_manager.register_data_service(remote_data_service)
112+
framework.db.register_data_service(remote_data_service)
116113
end
117114

118115
def cmd_test_data_service_host(*args)
@@ -129,8 +126,7 @@ def cmd_test_data_service_host(*args)
129126
end
130127

131128
puts 'Reporting test host to data service'
132-
data_service = Metasploit::Framework::DataService::DataProxy.instance
133-
data_service.report_host host
129+
framework.db.report_host host
134130
end
135131

136132
def cmd_test_data_service_loot(*args)
@@ -153,8 +149,7 @@ def cmd_test_data_service_loot(*args)
153149
end
154150

155151
puts 'Reporting test loot to data service'
156-
data_service = Metasploit::Framework::DataService::DataProxy.instance
157-
data_service.report_loot loot
152+
framework.db.report_loot loot
158153
end
159154

160155
def cmd_perf_test_data_service_loot(*args)
@@ -198,11 +193,10 @@ def cmd_perf_test_data_service_loot(*args)
198193
end
199194

200195
puts 'Reporting test loot to data service'
201-
data_service = Metasploit::Framework::DataService::DataProxy.instance
202196
start_time = Time.now
203197
puts "#{start_time} - Staring loot perf test"
204198
loots.each do |loot|
205-
data_service.report_loot loot
199+
framework.db.report_loot loot
206200
end
207201
end_time = Time.now
208202
puts "#{end_time} - Ending loot perf test. Duration was #{end_time - start_time}"
@@ -256,9 +250,11 @@ def cmd_workspace(*args)
256250
end
257251
framework.db.workspace = workspace
258252
elsif deleting and names
259-
framework.db.delete_workspaces(names)
253+
status_msg, error_msg = framework.db.delete_workspaces(names)
254+
print_msgs(status_msg, error_msg)
260255
elsif delete_all
261-
framework.db.delete_all_workspaces()
256+
status_msg, error_msg = framework.db.delete_all_workspaces()
257+
print_msgs(status_msg, error_msg)
262258
elsif renaming
263259
if names.length != 2
264260
print_error("Wrong number of arguments to rename")
@@ -1993,6 +1989,18 @@ def each_host_range_chunk(host_ranges, &block)
19931989
end
19941990
end
19951991

1992+
private
1993+
1994+
def print_msgs(status_msg, error_msg)
1995+
status_msg.each do |s|
1996+
print_status(s)
1997+
end
1998+
1999+
error_msg.each do |e|
2000+
print_error(e)
2001+
end
2002+
end
2003+
19962004
end
19972005

19982006
end end end end

lib/msf/ui/console/driver.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ def initialize(prompt = DefaultPrompt, prompt_char = DefaultPromptChar, opts = {
122122
enstack_dispatcher(dispatcher)
123123
end
124124

125-
framework.db.init(framework, opts)
126125
if (framework.db.active)
127126
require 'msf/ui/console/command_dispatcher/db'
128127
enstack_dispatcher(CommandDispatcher::Db)

spec/lib/msf/core/auxiliary/cisco_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def myworkspace
7777

7878
context '#cisco_ios_config_eater' do
7979
before(:example) do
80-
expect(aux_cisco).to receive(:myworkspace).and_return(workspace)
80+
expect(aux_cisco).to receive(:myworkspace).at_least(:once).and_return(workspace)
8181
end
8282

8383
it 'deals with udp ports' do

0 commit comments

Comments
 (0)