diff --git a/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb b/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb index 71ab70be56..dc0c536ba2 100644 --- a/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb +++ b/lib/metasploit/framework/data_service/proxy/workspace_data_proxy.rb @@ -64,4 +64,13 @@ module WorkspaceDataProxy self.log_error(e, "Problem deleting workspaces") end end + + def update_workspace(opts) + begin + data_service = self.get_data_service + data_service.update_workspace(opts) + rescue Exception => e + self.log_error(e, "Problem updating workspace") + end + end end diff --git a/lib/metasploit/framework/data_service/remote/http/remote_workspace_data_service.rb b/lib/metasploit/framework/data_service/remote/http/remote_workspace_data_service.rb index 47d4a05c60..ff7e699a26 100644 --- a/lib/metasploit/framework/data_service/remote/http/remote_workspace_data_service.rb +++ b/lib/metasploit/framework/data_service/remote/http/remote_workspace_data_service.rb @@ -40,6 +40,15 @@ module RemoteWorkspaceDataService json_to_mdm_object(self.delete_data(WORKSPACE_API_PATH, opts), WORKSPACE_MDM_CLASS, []) end + def update_workspace(opts) + path = WORKSPACE_API_PATH + if opts && opts[:id] + id = opts.delete(:id) + path = "#{WORKSPACE_API_PATH}/#{id}" + end + json_to_mdm_object(self.put_data(path, opts), WORKSPACE_MDM_CLASS, []) + end + ######### protected ######### diff --git a/lib/metasploit/framework/data_service/stubs/workspace_data_service.rb b/lib/metasploit/framework/data_service/stubs/workspace_data_service.rb index a0ce761adc..cffe0ba758 100644 --- a/lib/metasploit/framework/data_service/stubs/workspace_data_service.rb +++ b/lib/metasploit/framework/data_service/stubs/workspace_data_service.rb @@ -27,9 +27,4 @@ module WorkspaceDataService def workspace_associations_counts() raise 'WorkspaceDataService#workspace_associations_counts is not implemented' end - - def rename_workspace(from_name, to_name) - raise 'WorkspaceDataService#rename_workspace is not implemented' - end - -end \ No newline at end of file +end diff --git a/lib/msf/core/db_manager/http/servlet/workspace_servlet.rb b/lib/msf/core/db_manager/http/servlet/workspace_servlet.rb index 01d2c933c5..ef940bfc68 100644 --- a/lib/msf/core/db_manager/http/servlet/workspace_servlet.rb +++ b/lib/msf/core/db_manager/http/servlet/workspace_servlet.rb @@ -4,9 +4,14 @@ module WorkspaceServlet '/api/v1/workspaces' end + def self.api_path_with_id + "#{WorkspaceServlet.api_path}/?:id?" + end + def self.registered(app) app.get WorkspaceServlet.api_path, &get_workspace app.post WorkspaceServlet.api_path, &add_workspace + app.put WorkspaceServlet.api_path_with_id, &update_workspace end ####### @@ -42,4 +47,18 @@ module WorkspaceServlet end } end + + def self.update_workspace + lambda { + begin + opts = parse_json_request(request, false) + tmp_params = params.symbolize_keys + opts[:id] = tmp_params[:id] if tmp_params[:id] + data = get_db.update_workspace(opts) + set_json_response(data) + rescue Exception => e + set_error_on_response(e) + end + } + end end \ No newline at end of file diff --git a/lib/msf/core/db_manager/workspace.rb b/lib/msf/core/db_manager/workspace.rb index a2ca076e97..783af1be14 100644 --- a/lib/msf/core/db_manager/workspace.rb +++ b/lib/msf/core/db_manager/workspace.rb @@ -59,29 +59,14 @@ module Msf::DBManager::Workspace } end - # - # Renames a workspace - # - def rename_workspace(from_name, to_name) - raise "Workspace exists: #{to_name}" if framework.db.find_workspace(to_name) + def update_workspace(opts) + raise ArgumentError.new("The following options are required: :id") if opts[:id].nil? + workspace = opts.delete(:wspace) || opts.delete(:workspace) || workspace # TODO: Not used, but we do need to delete the key - workspace = find_workspace(from_name) - raise "Workspace not found: #{name}" if workspace.nil? - - workspace.name = new - workspace.save! - - # Recreate the default workspace to avoid errors - if workspace.default? - framework.db.add_workspace(from_name) - #print_status("Recreated default workspace after rename") - end - - # Switch to new workspace if old name was active - if (@workspace_name == workspace.name) - framework.db.workspace = workspace - #print_status("Switched workspace: #{framework.db.workspace.name}") - end + ::ActiveRecord::Base.connection_pool.with_connection { + id = opts.delete(:id) + Mdm::Workspace.update(id, opts) + } end def get_workspace(opts) diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index 22102bc9ff..156da8d4cb 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -170,8 +170,10 @@ class Db return end - old, new = names - framework.db.rename_workspace(old, new) + opts = {} + opts[:id] = framework.db.find_workspace(names.first).id + opts[:name] = names.last + framework.db.update_workspace(opts) elsif names name = names.last # Switch workspace