metasploit_data_models 0.16.4 → 0.16.5

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
@@ -1,7 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metasploit_data_models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.4
4
+ version: 0.16.5
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Samuel Huckins
@@ -11,11 +12,12 @@ authors:
11
12
  autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2013-07-05 00:00:00.000000000 Z
15
+ date: 2013-07-16 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
18
  name: rake
18
19
  requirement: !ruby/object:Gem::Requirement
20
+ none: false
19
21
  requirements:
20
22
  - - ! '>='
21
23
  - !ruby/object:Gem::Version
@@ -23,6 +25,7 @@ dependencies:
23
25
  type: :development
24
26
  prerelease: false
25
27
  version_requirements: !ruby/object:Gem::Requirement
28
+ none: false
26
29
  requirements:
27
30
  - - ! '>='
28
31
  - !ruby/object:Gem::Version
@@ -30,6 +33,7 @@ dependencies:
30
33
  - !ruby/object:Gem::Dependency
31
34
  name: yard
32
35
  requirement: !ruby/object:Gem::Requirement
36
+ none: false
33
37
  requirements:
34
38
  - - ! '>='
35
39
  - !ruby/object:Gem::Version
@@ -37,6 +41,7 @@ dependencies:
37
41
  type: :development
38
42
  prerelease: false
39
43
  version_requirements: !ruby/object:Gem::Requirement
44
+ none: false
40
45
  requirements:
41
46
  - - ! '>='
42
47
  - !ruby/object:Gem::Version
@@ -44,6 +49,7 @@ dependencies:
44
49
  - !ruby/object:Gem::Dependency
45
50
  name: pry
46
51
  requirement: !ruby/object:Gem::Requirement
52
+ none: false
47
53
  requirements:
48
54
  - - ! '>='
49
55
  - !ruby/object:Gem::Version
@@ -51,6 +57,7 @@ dependencies:
51
57
  type: :development
52
58
  prerelease: false
53
59
  version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
54
61
  requirements:
55
62
  - - ! '>='
56
63
  - !ruby/object:Gem::Version
@@ -58,6 +65,7 @@ dependencies:
58
65
  - !ruby/object:Gem::Dependency
59
66
  name: activerecord
60
67
  requirement: !ruby/object:Gem::Requirement
68
+ none: false
61
69
  requirements:
62
70
  - - ! '>='
63
71
  - !ruby/object:Gem::Version
@@ -65,6 +73,7 @@ dependencies:
65
73
  type: :runtime
66
74
  prerelease: false
67
75
  version_requirements: !ruby/object:Gem::Requirement
76
+ none: false
68
77
  requirements:
69
78
  - - ! '>='
70
79
  - !ruby/object:Gem::Version
@@ -72,6 +81,7 @@ dependencies:
72
81
  - !ruby/object:Gem::Dependency
73
82
  name: activesupport
74
83
  requirement: !ruby/object:Gem::Requirement
84
+ none: false
75
85
  requirements:
76
86
  - - ! '>='
77
87
  - !ruby/object:Gem::Version
@@ -79,6 +89,7 @@ dependencies:
79
89
  type: :runtime
80
90
  prerelease: false
81
91
  version_requirements: !ruby/object:Gem::Requirement
92
+ none: false
82
93
  requirements:
83
94
  - - ! '>='
84
95
  - !ruby/object:Gem::Version
@@ -86,6 +97,7 @@ dependencies:
86
97
  - !ruby/object:Gem::Dependency
87
98
  name: redcarpet
88
99
  requirement: !ruby/object:Gem::Requirement
100
+ none: false
89
101
  requirements:
90
102
  - - ! '>='
91
103
  - !ruby/object:Gem::Version
@@ -93,6 +105,7 @@ dependencies:
93
105
  type: :development
94
106
  prerelease: false
95
107
  version_requirements: !ruby/object:Gem::Requirement
108
+ none: false
96
109
  requirements:
97
110
  - - ! '>='
98
111
  - !ruby/object:Gem::Version
@@ -100,6 +113,7 @@ dependencies:
100
113
  - !ruby/object:Gem::Dependency
101
114
  name: pg
102
115
  requirement: !ruby/object:Gem::Requirement
116
+ none: false
103
117
  requirements:
104
118
  - - ! '>='
105
119
  - !ruby/object:Gem::Version
@@ -107,6 +121,7 @@ dependencies:
107
121
  type: :runtime
108
122
  prerelease: false
109
123
  version_requirements: !ruby/object:Gem::Requirement
124
+ none: false
110
125
  requirements:
111
126
  - - ! '>='
112
127
  - !ruby/object:Gem::Version
@@ -437,26 +452,33 @@ files:
437
452
  - spec/support/shared/examples/mdm/module/detail/supports_stance_with_mtype.rb
438
453
  homepage: ''
439
454
  licenses: []
440
- metadata: {}
441
455
  post_install_message:
442
456
  rdoc_options: []
443
457
  require_paths:
444
458
  - lib
445
459
  required_ruby_version: !ruby/object:Gem::Requirement
460
+ none: false
446
461
  requirements:
447
462
  - - ! '>='
448
463
  - !ruby/object:Gem::Version
449
464
  version: '0'
465
+ segments:
466
+ - 0
467
+ hash: -1502167183498467311
450
468
  required_rubygems_version: !ruby/object:Gem::Requirement
469
+ none: false
451
470
  requirements:
452
471
  - - ! '>='
453
472
  - !ruby/object:Gem::Version
454
473
  version: '0'
474
+ segments:
475
+ - 0
476
+ hash: -1502167183498467311
455
477
  requirements: []
456
478
  rubyforge_project:
457
- rubygems_version: 2.0.3
479
+ rubygems_version: 1.8.25
458
480
  signing_key:
459
- specification_version: 4
481
+ specification_version: 3
460
482
  summary: Database code for MSF and Metasploit Pro
461
483
  test_files:
462
484
  - spec/app/models/mdm/client_spec.rb
checksums.yaml DELETED
@@ -1,15 +0,0 @@
1
- ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZDhiOTE4MWQ2Y2YzMDQ4YzYyODE4MWQyNTg0ODNlY2Q1ZTg5NTIyOA==
5
- data.tar.gz: !binary |-
6
- MTc2ZTEyYjJiYjc4OTFiZWMzZWZmMTZjYjFjMTBhN2QxZjcyNDM1Mg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MDNiODM5MzVlNzljMTM4NTFmYjk1ZmIyMmZjMWU2NTBmMjI4ZDc1NDU1M2I0
10
- MDBmY2I1NDM3ZmQ0NzIxNTIzZmNkMzMxN2MxZmI1MzM5ZDNiZTQwMjIyYmZm
11
- YWNiZTA5MTdmNmE4NGU0MDUwOTk3MGQ2MDgwOTY5OWQ5YmUzZDc=
12
- data.tar.gz: !binary |-
13
- N2YzNGQxMDM1NTNiNDg4YTg0M2YwZjMxY2VmY2NlOGI1ZDBlM2EwN2U1YzZi
14
- NzQ0NGYzMGIzYmRhN2JlOTg1NzA4ODRkMjI3MDU4NDk5OTg0YzI1YjVhYzdl
15
- NmMyNjIzNWViOGNkNjA2YWQxZWJhMWYwNzNiNjg1MDA3MzRhYmM=