metasploit_data_models 0.16.4-java → 0.16.5-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,20 +3,98 @@
3
3
  class EnforceAddressUniquenessInWorkspaceInHosts < ActiveRecord::Migration
4
4
  TABLE_NAME = :hosts
5
5
 
6
+ # maps Table -> Association Column for models that "belong to" a Host
7
+ HOST_ASSOCIATION_MAP = {
8
+ 'clients' => 'host_id',
9
+ 'events' => 'host_id',
10
+ 'exploit_attempts' => 'host_id',
11
+ 'exploited_hosts' => 'host_id',
12
+ 'host_details' => 'host_id',
13
+ 'hosts_tags' => 'host_id',
14
+ 'loots' => 'host_id',
15
+ 'notes' => 'host_id',
16
+ 'sessions' => 'host_id',
17
+ 'services' => 'host_id',
18
+ 'vulns' => 'host_id'
19
+ }
20
+
21
+ # Historically there a few scenarios where a user could end up with Hosts
22
+ # in the same workspace with the same IP. Primarily, if you run a Nexpose Scan
23
+ # and a Discover scan simultaneously, AR does not know about these separate
24
+ # transactions, so the Hosts will be valid when added and the user will end up
25
+ # (when transaction completes) with two hosts with the same IP in the same workspace.
26
+ #
27
+ # Since we are adding a DB uniq constraint here, this migration could fail if the user
28
+ # has hit aforementioned scenarios. So we try to "merge" any hosts with the same
29
+ # address in the same workspace before adding the DB constraint, to prevent the
30
+ # migration from simply failing.
31
+ #
32
+ # Note: We can't rely on AR directly here (or in any migration), since we have no
33
+ # idea what version of the code the user has checked out. So we fall back to SQL :(
34
+ def find_and_merge_duplicate_hosts!
35
+ # find all duplicate addresses within the same workspace currently in the db
36
+ dupe_addresses_and_workspaces = ActiveRecord::Base.connection.execute(%Q{
37
+ SELECT workspace_id, address, count_addr
38
+ FROM (
39
+ SELECT workspace_id, address, COUNT(address) AS count_addr
40
+ FROM hosts
41
+ GROUP BY address, workspace_id
42
+ ) X
43
+ WHERE count_addr > 1
44
+ })
45
+
46
+ if dupe_addresses_and_workspaces.present? and
47
+ not dupe_addresses_and_workspaces.num_tuples.zero?
48
+ puts "Duplicate hosts in workspace found. Merging host references."
49
+ # iterate through the duped IPs
50
+ dupe_addresses_and_workspaces.each do |result|
51
+ # so its come to this
52
+ address = ActiveRecord::Base.connection.quote(result['address'])
53
+ workspace_id = result['workspace_id'].to_i
54
+ # look up the duplicate Host table entries to find all IDs of the duped Hosts
55
+ hosts = ActiveRecord::Base.connection.execute(%Q|
56
+ SELECT id
57
+ FROM hosts
58
+ WHERE address=#{address} AND workspace_id=#{workspace_id}
59
+ ORDER BY id DESC
60
+ |)
61
+ # grab and quote the ID for each result row
62
+ hosts = hosts.map { |h| h["id"].to_i }
63
+ # grab every Host entry besides the first one
64
+ first_host_id = hosts.first
65
+ dupe_host_ids = hosts[1..-1]
66
+ # update associations to these duplicate Hosts
67
+ HOST_ASSOCIATION_MAP.each do |table, column|
68
+ ActiveRecord::Base.connection.execute(%Q|
69
+ UPDATE #{table} SET #{column}=#{first_host_id}
70
+ WHERE #{column} IN (#{dupe_host_ids.join(',')})
71
+ |)
72
+ end
73
+ # destroy the duplicate host rows
74
+ ActiveRecord::Base.connection.execute(%Q|
75
+ DELETE FROM hosts WHERE id IN (#{dupe_host_ids.join(',')})
76
+ |)
77
+ end
78
+
79
+ # At this point all duped hosts in the same workspace should be merged.
80
+ # You could end up with duplicate services, but hey its better than just
81
+ # dropping all data about the old Host.
82
+ end
83
+ end
84
+
6
85
  # Restores old index on address
7
86
  def down
8
87
  change_table TABLE_NAME do |t|
9
88
  t.remove_index [:workspace_id, :address]
10
-
11
89
  t.index :address
12
90
  end
13
91
  end
14
92
 
15
93
  # Make index on address scope to workspace_id and be unique
16
94
  def up
95
+ find_and_merge_duplicate_hosts!
17
96
  change_table TABLE_NAME do |t|
18
97
  t.remove_index :address
19
-
20
98
  t.index [:workspace_id, :address], :unique => true
21
99
  end
22
100
  end
@@ -4,5 +4,5 @@ module MetasploitDataModels
4
4
  # metasploit-framework/data/sql/migrate to db/migrate in this project, not all models have specs that verify the
5
5
  # migrations (with have_db_column and have_db_index) and certain models may not be shared between metasploit-framework
6
6
  # and pro, so models may be removed in the future. Because of the unstable API the version should remain below 1.0.0
7
- VERSION = '0.16.4'
7
+ VERSION = '0.16.5'
8
8
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: metasploit_data_models
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.16.4
5
+ version: 0.16.5
6
6
  platform: java
7
7
  authors:
8
8
  - Samuel Huckins
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-07-05 00:00:00.000000000 Z
15
+ date: 2013-07-16 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rake