metasploit_data_models 0.15.2 → 0.16.0
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.
- data/Gemfile +2 -0
- data/app/models/mdm/client.rb +0 -1
- data/app/models/mdm/cred.rb +1 -1
- data/app/models/mdm/exploited_host.rb +0 -1
- data/app/models/mdm/listener.rb +2 -1
- data/app/models/mdm/nexpose_console.rb +2 -2
- data/app/models/mdm/session.rb +5 -1
- data/app/models/mdm/workspace.rb +0 -1
- data/db/migrate/20130525015035_remove_campaign_id_from_clients.rb +9 -0
- data/db/migrate/20130525212420_drop_table_imported_creds.rb +14 -0
- data/db/migrate/20130531144949_making_host_tags_a_real_ar_model.rb +6 -0
- data/lib/mdm/host/operating_system_normalization.rb +4 -4
- data/lib/metasploit_data_models/version.rb +1 -1
- data/spec/app/models/mdm/client_spec.rb +43 -0
- data/spec/app/models/mdm/cred_spec.rb +211 -0
- data/spec/app/models/mdm/events_spec.rb +85 -0
- data/spec/app/models/mdm/exploit_attempt_spec.rb +60 -0
- data/spec/app/models/mdm/exploited_host_spec.rb +44 -0
- data/spec/app/models/mdm/host_detail_spec.rb +49 -0
- data/spec/app/models/mdm/host_spec.rb +468 -0
- data/spec/app/models/mdm/host_tag_spec.rb +26 -0
- data/spec/app/models/mdm/listener_spec.rb +108 -0
- data/spec/app/models/mdm/loot_spec.rb +77 -0
- data/spec/app/models/mdm/nexpose_console_spec.rb +128 -0
- data/spec/app/models/mdm/note_spec.rb +84 -0
- data/spec/app/models/mdm/ref_spec.rb +13 -0
- data/spec/app/models/mdm/report_spec.rb +104 -0
- data/spec/app/models/mdm/report_template_spec.rb +52 -0
- data/spec/app/models/mdm/route_spec.rb +36 -0
- data/spec/app/models/mdm/service_spec.rb +70 -15
- data/spec/app/models/mdm/session_event_spec.rb +42 -0
- data/spec/app/models/mdm/session_spec.rb +114 -0
- data/spec/app/models/mdm/tag_spec.rb +104 -0
- data/spec/app/models/mdm/task_creds_spec.rb +32 -0
- data/spec/app/models/mdm/task_host_spec.rb +33 -0
- data/spec/app/models/mdm/task_service_spec.rb +33 -0
- data/spec/app/models/mdm/task_spec.rb +59 -5
- data/spec/app/models/mdm/user_spec.rb +51 -0
- data/spec/app/models/mdm/vuln_attempt_spec.rb +54 -0
- data/spec/app/models/mdm/vuln_details_spec.rb +66 -0
- data/spec/app/models/mdm/vuln_ref_spec.rb +24 -0
- data/spec/app/models/mdm/vuln_spec.rb +25 -0
- data/spec/app/models/mdm/web_form_spec.rb +47 -0
- data/spec/app/models/mdm/web_page_spec.rb +55 -0
- data/spec/app/models/mdm/web_site_spec.rb +86 -0
- data/spec/app/models/mdm/web_vuln_spec.rb +12 -0
- data/spec/app/models/mdm/workspace_spec.rb +567 -0
- data/spec/dummy/db/schema.rb +5 -13
- data/spec/factories/mdm/addresses.rb +5 -0
- data/spec/factories/mdm/clients.rb +8 -0
- data/spec/factories/mdm/events.rb +15 -0
- data/spec/factories/mdm/exploit_attempts.rb +8 -0
- data/spec/factories/mdm/exploited_hosts.rb +7 -0
- data/spec/factories/mdm/fingerprints/nessus_fingerprints.rb +6 -0
- data/spec/factories/mdm/fingerprints/nexpose_fingerprints.rb +6 -0
- data/spec/factories/mdm/fingerprints/nmap_fingerprints.rb +6 -0
- data/spec/factories/mdm/fingerprints/retina_fingerprints.rb +6 -0
- data/spec/factories/mdm/fingerprints/session_fingerprints.rb +6 -0
- data/spec/factories/mdm/host_details.rb +8 -0
- data/spec/factories/mdm/listeners.rb +12 -0
- data/spec/factories/mdm/loots.rb +11 -0
- data/spec/factories/mdm/nexpose_consoles.rb +15 -0
- data/spec/factories/mdm/notes.rb +12 -0
- data/spec/factories/mdm/report_templates.rb +8 -0
- data/spec/factories/mdm/reports.rb +13 -0
- data/spec/factories/mdm/routes.rb +36 -0
- data/spec/factories/mdm/session_events.rb +8 -0
- data/spec/factories/mdm/sessions.rb +13 -0
- data/spec/factories/mdm/vuln_attempts.rb +8 -0
- data/spec/factories/mdm/vuln_details.rb +8 -0
- data/spec/factories/mdm/web_forms.rb +33 -0
- data/spec/factories/mdm/web_pages.rb +64 -0
- metadata +95 -5
- data/app/models/mdm/imported_cred.rb +0 -10
data/Gemfile
CHANGED
@@ -24,4 +24,6 @@ group :test do
|
|
24
24
|
# need rspec-rails >= 2.12.0 as 2.12.0 adds support for redefining named subject in nested context that uses the
|
25
25
|
# named subject from the outer context without causing a stack overflow.
|
26
26
|
gem 'rspec-rails', '>= 2.12.0'
|
27
|
+
# used for building markup for webpage factories
|
28
|
+
gem 'builder'
|
27
29
|
end
|
data/app/models/mdm/client.rb
CHANGED
data/app/models/mdm/cred.rb
CHANGED
@@ -5,7 +5,6 @@ class Mdm::ExploitedHost < ActiveRecord::Base
|
|
5
5
|
|
6
6
|
belongs_to :host, :class_name => 'Mdm::Host'
|
7
7
|
belongs_to :service, :class_name => 'Mdm::Service'
|
8
|
-
belongs_to :workspace, :class_name => 'Mdm::Workspace'
|
9
8
|
|
10
9
|
ActiveSupport.run_load_hooks(:mdm_exploited_host, self)
|
11
10
|
end
|
data/app/models/mdm/listener.rb
CHANGED
@@ -17,7 +17,8 @@ class Mdm::Listener < ActiveRecord::Base
|
|
17
17
|
#
|
18
18
|
|
19
19
|
validates :address, :ip_format => true, :presence => true
|
20
|
-
validates :port, :presence => true
|
20
|
+
validates :port, :presence => true, :numericality => { :only_integer => true }, :inclusion => {:in => 1..65535}
|
21
|
+
|
21
22
|
|
22
23
|
ActiveSupport.run_load_hooks(:mdm_listener, self)
|
23
24
|
end
|
@@ -9,10 +9,10 @@ class Mdm::NexposeConsole < ActiveRecord::Base
|
|
9
9
|
# Validations
|
10
10
|
#
|
11
11
|
|
12
|
-
validates :address, :presence => true
|
12
|
+
validates :address, :ip_format => true, :presence => true
|
13
13
|
validates :name, :presence => true
|
14
14
|
validates :password, :presence => true
|
15
|
-
validates :port, :inclusion => {:in => 1..65535}
|
15
|
+
validates :port, :numericality => { :only_integer => true }, :inclusion => {:in => 1..65535}
|
16
16
|
validates :username, :presence => true
|
17
17
|
|
18
18
|
ActiveSupport.run_load_hooks(:mdm_nexpose_console, self)
|
data/app/models/mdm/session.rb
CHANGED
@@ -123,7 +123,11 @@ class Mdm::Session < ActiveRecord::Base
|
|
123
123
|
# @return [true] if {#platform} is some version of Windows and {#stype} is `'shell'`.
|
124
124
|
# @return [false] otherwise.
|
125
125
|
def upgradeable?
|
126
|
-
(self.platform =~ /win/ and self.stype == 'shell')
|
126
|
+
if (self.platform =~ /win/i and self.stype == 'shell')
|
127
|
+
return true
|
128
|
+
else
|
129
|
+
return false
|
130
|
+
end
|
127
131
|
end
|
128
132
|
|
129
133
|
private
|
data/app/models/mdm/workspace.rb
CHANGED
@@ -18,7 +18,6 @@ class Mdm::Workspace < ActiveRecord::Base
|
|
18
18
|
has_many :creds, :through => :services, :class_name => 'Mdm::Cred'
|
19
19
|
has_many :events, :class_name => 'Mdm::Event'
|
20
20
|
has_many :hosts, :dependent => :destroy, :class_name => 'Mdm::Host'
|
21
|
-
has_many :imported_creds, :dependent => :destroy, :class_name => 'Mdm::ImportedCred'
|
22
21
|
has_many :listeners, :dependent => :destroy, :class_name => 'Mdm::Listener'
|
23
22
|
has_many :notes, :class_name => 'Mdm::Note'
|
24
23
|
belongs_to :owner, :class_name => 'Mdm::User', :foreign_key => 'owner_id'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class DropTableImportedCreds < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
drop_table :imported_creds
|
4
|
+
end
|
5
|
+
|
6
|
+
def down
|
7
|
+
create_table :imported_creds do |t|
|
8
|
+
t.integer :workspace_id, :null => false, :default => 1
|
9
|
+
t.string :user, :limit => 512
|
10
|
+
t.string :pass, :limit => 512
|
11
|
+
t.string :ptype, :limit => 16, :default => "password"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -742,11 +742,11 @@ module Mdm::Host::OperatingSystemNormalization
|
|
742
742
|
case data[:os]
|
743
743
|
when /Windows/
|
744
744
|
ret.update(parse_windows_os_str(data[:os]))
|
745
|
-
when /Linux (
|
745
|
+
when /Linux (\d+\.\d+\.\d+\S*)\s* \((\w*)\)/
|
746
746
|
ret[:os_name] = "Linux"
|
747
|
-
ret[:name] =
|
748
|
-
ret[:os_sp] = $
|
749
|
-
ret[:arch] = get_arch_from_string($
|
747
|
+
ret[:name] = data[:name]
|
748
|
+
ret[:os_sp] = $1
|
749
|
+
ret[:arch] = get_arch_from_string($2)
|
750
750
|
else
|
751
751
|
ret[:os_name] = data[:os]
|
752
752
|
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.
|
7
|
+
VERSION = '0.16.0'
|
8
8
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdm::Client do
|
4
|
+
|
5
|
+
context 'associations' do
|
6
|
+
it { should belong_to(:host).class_name('Mdm::Host') }
|
7
|
+
end
|
8
|
+
|
9
|
+
context '#destroy' do
|
10
|
+
it 'should successfully destroy the object' do
|
11
|
+
client = FactoryGirl.create(:mdm_client, :ua_string => 'user-agent')
|
12
|
+
expect {
|
13
|
+
client.destroy
|
14
|
+
}.to_not raise_error
|
15
|
+
expect {
|
16
|
+
client.reload
|
17
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'factory' do
|
22
|
+
it 'should be valid' do
|
23
|
+
client = FactoryGirl.build(:mdm_client)
|
24
|
+
client.should be_valid
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'database' do
|
29
|
+
context 'columns' do
|
30
|
+
it { should have_db_column(:host_id).of_type(:integer)}
|
31
|
+
it { should have_db_column(:ua_string).of_type(:string).with_options(:null => false) }
|
32
|
+
it { should have_db_column(:ua_name).of_type(:string) }
|
33
|
+
it { should have_db_column(:ua_ver).of_type(:string) }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'timestamps' do
|
37
|
+
it { should have_db_column(:created_at).of_type(:datetime) }
|
38
|
+
it { should have_db_column(:updated_at).of_type(:datetime) }
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -8,6 +8,217 @@ describe Mdm::Cred do
|
|
8
8
|
it { should belong_to(:service).class_name('Mdm::Service') }
|
9
9
|
end
|
10
10
|
|
11
|
+
context 'database' do
|
12
|
+
context 'timestamps' do
|
13
|
+
it { should have_db_column(:created_at).of_type(:datetime) }
|
14
|
+
it { should have_db_column(:updated_at).of_type(:datetime) }
|
15
|
+
end
|
11
16
|
|
17
|
+
context 'columns' do
|
18
|
+
it { should have_db_column(:service_id).of_type(:integer).with_options(:null => false) }
|
19
|
+
it { should have_db_column(:user).of_type(:string) }
|
20
|
+
it { should have_db_column(:pass).of_type(:string) }
|
21
|
+
it { should have_db_column(:active).of_type(:boolean).with_options(:default => true) }
|
22
|
+
it { should have_db_column(:proof).of_type(:string) }
|
23
|
+
it { should have_db_column(:ptype).of_type(:string) }
|
24
|
+
it { should have_db_column(:source_id).of_type(:integer) }
|
25
|
+
it { should have_db_column(:source_type).of_type(:string) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context '#destroy' do
|
30
|
+
it 'should successfully destroy the object and all dependent objects' do
|
31
|
+
cred = FactoryGirl.create(:mdm_cred)
|
32
|
+
task_cred = FactoryGirl.create(:mdm_task_cred, :cred => cred)
|
33
|
+
expect {
|
34
|
+
cred.destroy
|
35
|
+
}.to_not raise_error
|
36
|
+
expect {
|
37
|
+
cred.reload
|
38
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
39
|
+
expect {
|
40
|
+
task_cred.reload
|
41
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'callbacks' do
|
46
|
+
context 'after_create' do
|
47
|
+
it 'should increment cred_count on the host' do
|
48
|
+
host = FactoryGirl.create(:mdm_host)
|
49
|
+
svc = FactoryGirl.create(:mdm_service, :host => host)
|
50
|
+
expect {
|
51
|
+
FactoryGirl.create(:mdm_cred, :service => svc)
|
52
|
+
}.to change{ Mdm::Host.find(host.id).cred_count}.by(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'after_destroy' do
|
57
|
+
it 'should decrement cred_count on the host' do
|
58
|
+
host = FactoryGirl.create(:mdm_host)
|
59
|
+
svc = FactoryGirl.create(:mdm_service, :host => host)
|
60
|
+
cred =FactoryGirl.create(:mdm_cred, :service => svc)
|
61
|
+
expect {
|
62
|
+
cred.destroy
|
63
|
+
}.to change{ Mdm::Host.find(host.id).cred_count}.by(-1)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'constants' do
|
69
|
+
it 'should define the key_id regex' do
|
70
|
+
described_class::KEY_ID_REGEX.should == /([0-9a-fA-F:]{47})/
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should define ptypes to humanize' do
|
74
|
+
described_class::PTYPES.should == {
|
75
|
+
'read/write password' => 'password_rw',
|
76
|
+
'read-only password' => 'password_ro',
|
77
|
+
'SMB hash' => 'smb_hash',
|
78
|
+
'SSH private key' => 'ssh_key',
|
79
|
+
'SSH public key' => 'ssh_pubkey'
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'methods' do
|
85
|
+
before(:all) do
|
86
|
+
Mdm::Workspace.any_instance.stub(:valid_ip_or_range? => true)
|
87
|
+
workspace = FactoryGirl.create(:mdm_workspace)
|
88
|
+
host = FactoryGirl.create(:mdm_host, :workspace => workspace)
|
89
|
+
@svc1 = FactoryGirl.create(:mdm_service, :host => host)
|
90
|
+
@svc2 = FactoryGirl.create(:mdm_service, :host => host)
|
91
|
+
@cred1 = FactoryGirl.create(:mdm_cred, :service => @svc1, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
92
|
+
@pubkey = FactoryGirl.create(:mdm_cred, :service => @svc1, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_pubkey', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
93
|
+
end
|
94
|
+
|
95
|
+
context '#ptype_human' do
|
96
|
+
it "should return 'read/write password' for 'password_rw'" do
|
97
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => 'msfadmin', :ptype => 'password_rw')
|
98
|
+
cred.ptype_human.should == 'read/write password'
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return 'read-only password' for 'password_ro'" do
|
102
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => 'msfadmin', :ptype => 'password_ro')
|
103
|
+
cred.ptype_human.should == 'read-only password'
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should return 'SMB Hash' for 'smb_hash'" do
|
107
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => 'msfadmin', :ptype => 'smb_hash')
|
108
|
+
cred.ptype_human.should == 'SMB hash'
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return 'SSH private key' for 'ssh_key'" do
|
112
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => 'msfadmin', :ptype => 'ssh_key')
|
113
|
+
cred.ptype_human.should == 'SSH private key'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should return 'SSH public key' for 'ssh_pubkey'" do
|
117
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => 'msfadmin', :ptype => 'ssh_pubkey')
|
118
|
+
cred.ptype_human.should == 'SSH public key'
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context '#ssh_key_id' do
|
123
|
+
it 'should return nil if not an ssh_key' do
|
124
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => 'msfadmin', :ptype => 'password_rw')
|
125
|
+
cred.ssh_key_id.should == nil
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'should return nil if proof does not contain the key id' do
|
129
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "no key here")
|
130
|
+
cred.ssh_key_id.should == nil
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should return the key id for an ssh_key' do
|
134
|
+
cred = FactoryGirl.build(:mdm_cred, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
135
|
+
cred.ssh_key_id.should == '57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a'
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
context '#ssh_key_matches?' do
|
141
|
+
it 'should return true if the ssh_keys match' do
|
142
|
+
cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
143
|
+
cred2.ssh_key_matches?(@cred1).should == true
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should return false if passed something other than a cred' do
|
147
|
+
@cred1.ssh_key_matches?(@svc1).should == false
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'should return false if the ptypes do not match' do
|
151
|
+
cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_pubkey', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
152
|
+
cred2.ssh_key_matches?(@cred1).should == false
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should return false if the key ids do not match' do
|
156
|
+
cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_pubkey', :proof => "KEY=66:d4:22:6e:88:d6:74:A1:44:3e:d6:d5:AA:89:73:8b")
|
157
|
+
cred2.ssh_key_matches?(@cred1).should == false
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should behave the same for public keys as private keys' do
|
161
|
+
pubkey2 = FactoryGirl.create(:mdm_cred, :service => @svc1, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_pubkey', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
162
|
+
pubkey3 = FactoryGirl.create(:mdm_cred, :service => @svc1, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_pubkey', :proof => "KEY=66:d4:22:6e:88:d6:74:A1:44:3e:d6:d5:AA:89:73:8b")
|
163
|
+
pubkey2.ssh_key_matches?(@pubkey).should == true
|
164
|
+
pubkey2.ssh_key_matches?(pubkey3).should == false
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should always return false for non ssh key creds' do
|
168
|
+
cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :ptype => 'password', :user => 'msfadmin', :pass => 'msfadmin' )
|
169
|
+
cred3 = FactoryGirl.create(:mdm_cred, :service => @svc2, :ptype => 'password', :user => 'msfadmin', :pass => 'msfadmin' )
|
170
|
+
cred2.ssh_key_matches?(cred3).should == false
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context '#ssh_keys' do
|
175
|
+
before(:all) do
|
176
|
+
@cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
177
|
+
end
|
178
|
+
it 'should return all ssh private keys with a matching id' do
|
179
|
+
@cred2.ssh_keys.should include(@cred1)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should return all ssh public keys with a matching id' do
|
183
|
+
@cred2.ssh_keys.should include(@pubkey)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context '#ssh_private_keys' do
|
188
|
+
before(:all) do
|
189
|
+
@cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should return ssh private keys with matching ids' do
|
193
|
+
@cred2.ssh_private_keys.should include(@cred1)
|
194
|
+
end
|
195
|
+
|
196
|
+
it 'should not return ssh public keys with matching ids' do
|
197
|
+
@cred2.ssh_private_keys.should_not include(@pubkey)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context '#ssh_public_keys' do
|
202
|
+
before(:all) do
|
203
|
+
@cred2 = FactoryGirl.create(:mdm_cred, :service => @svc2, :user => 'msfadmin', :pass => '/path/to/keyfile', :ptype => 'ssh_key', :proof => "KEY=57:c3:11:5d:77:c5:63:90:33:2d:c5:c4:99:78:62:7a")
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should not return ssh private keys with matching ids' do
|
207
|
+
@cred2.ssh_public_keys.should_not include(@cred1)
|
208
|
+
end
|
209
|
+
|
210
|
+
it 'should return ssh public keys with matching ids' do
|
211
|
+
@cred2.ssh_public_keys.should include(@pubkey)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'factory' do
|
218
|
+
it 'should be valid' do
|
219
|
+
cred = FactoryGirl.build(:mdm_cred)
|
220
|
+
cred.should be_valid
|
221
|
+
end
|
222
|
+
end
|
12
223
|
|
13
224
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Mdm::Event do
|
4
|
+
|
5
|
+
context 'associations' do
|
6
|
+
it { should belong_to(:host).class_name('Mdm::Host') }
|
7
|
+
it { should belong_to(:workspace).class_name('Mdm::Workspace') }
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'database' do
|
11
|
+
context 'timestamps' do
|
12
|
+
it { should have_db_column(:created_at).of_type(:datetime) }
|
13
|
+
it { should have_db_column(:updated_at).of_type(:datetime) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'columns' do
|
17
|
+
it { should have_db_column(:workspace_id).of_type(:integer) }
|
18
|
+
it { should have_db_column(:host_id).of_type(:integer) }
|
19
|
+
it { should have_db_column(:name).of_type(:string) }
|
20
|
+
it { should have_db_column(:critical).of_type(:boolean) }
|
21
|
+
it { should have_db_column(:seen).of_type(:boolean) }
|
22
|
+
it { should have_db_column(:username).of_type(:string) }
|
23
|
+
it { should have_db_column(:info).of_type(:text) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context '#destroy' do
|
28
|
+
it 'should successfully destroy the object and all dependent objects' do
|
29
|
+
event = FactoryGirl.create(:mdm_event)
|
30
|
+
expect {
|
31
|
+
event.destroy
|
32
|
+
}.to_not raise_error
|
33
|
+
expect {
|
34
|
+
event.reload
|
35
|
+
}.to raise_error(ActiveRecord::RecordNotFound)
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'scopes' do
|
41
|
+
context 'flagged' do
|
42
|
+
it 'should exclude non-critical events' do
|
43
|
+
flagged_event = FactoryGirl.create(:mdm_event, :name => 'flagme', :critical => true, :seen => false)
|
44
|
+
non_critical_event = FactoryGirl.create(:mdm_event, :name => 'dontflagmebro', :critical => false, :seen => false)
|
45
|
+
flagged_set = Mdm::Event.flagged
|
46
|
+
flagged_set.should include(flagged_event)
|
47
|
+
flagged_set.should_not include(non_critical_event)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should exclude seen events' do
|
51
|
+
flagged_event = FactoryGirl.create(:mdm_event, :name => 'flagme', :critical => true, :seen => false)
|
52
|
+
non_critical_event = FactoryGirl.create(:mdm_event, :name => 'dontflagmebro', :critical => false, :seen => true)
|
53
|
+
flagged_set = Mdm::Event.flagged
|
54
|
+
flagged_set.should include(flagged_event)
|
55
|
+
flagged_set.should_not include(non_critical_event)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'module_run' do
|
60
|
+
it 'should only return module_run events' do
|
61
|
+
flagged_event = FactoryGirl.create(:mdm_event, :name => 'module_run')
|
62
|
+
non_critical_event = FactoryGirl.create(:mdm_event, :name => 'dontflagmebro')
|
63
|
+
flagged_set = Mdm::Event.module_run
|
64
|
+
flagged_set.should include(flagged_event)
|
65
|
+
flagged_set.should_not include(non_critical_event)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'validations' do
|
71
|
+
it 'should require name' do
|
72
|
+
unnamed_event = FactoryGirl.build(:mdm_event, :name => nil)
|
73
|
+
unnamed_event.should_not be_valid
|
74
|
+
unnamed_event.errors[:name].should include("can't be blank")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'factory' do
|
79
|
+
it 'should be valid' do
|
80
|
+
event = FactoryGirl.build(:mdm_event)
|
81
|
+
event.should be_valid
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|