ruby-nmap 0.7.0 → 0.8.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +17 -0
- data/Gemfile +7 -5
- data/lib/nmap/address.rb +1 -1
- data/lib/nmap/host.rb +27 -2
- data/lib/nmap/hostname.rb +22 -0
- data/lib/nmap/os.rb +1 -1
- data/lib/nmap/program.rb +23 -0
- data/lib/nmap/task.rb +9 -9
- data/lib/nmap/version.rb +1 -1
- data/lib/nmap/xml.rb +80 -1
- data/ruby-nmap.gemspec +1 -1
- data/spec/address_spec.rb +1 -1
- data/spec/cpe/url_spec.rb +16 -16
- data/spec/cpe_examples.rb +2 -2
- data/spec/hop_spec.rb +1 -1
- data/spec/host_spec.rb +69 -44
- data/spec/hostname_spec.rb +20 -3
- data/spec/ip_id_sequence_spec.rb +2 -2
- data/spec/nmap_spec.rb +1 -1
- data/spec/os_class_spec.rb +20 -10
- data/spec/os_match_spec.rb +1 -1
- data/spec/os_spec.rb +10 -9
- data/spec/port_spec.rb +18 -10
- data/spec/run_stat_spec.rb +1 -1
- data/spec/scan.xml +1 -0
- data/spec/scan_spec.rb +4 -4
- data/spec/scan_task_spec.rb +3 -3
- data/spec/scanner_spec.rb +1 -1
- data/spec/scripts_examples.rb +2 -2
- data/spec/sequence_examples.rb +4 -2
- data/spec/service_spec.rb +11 -11
- data/spec/spec_helper.rb +0 -26
- data/spec/status_spec.rb +1 -1
- data/spec/task_spec.rb +6 -6
- data/spec/tcp_sequence_spec.rb +3 -3
- data/spec/tcp_ts_sequence_spec.rb +2 -2
- data/spec/traceroute_spec.rb +20 -9
- data/spec/uptime_spec.rb +1 -1
- data/spec/xml_spec.rb +82 -44
- metadata +3 -3
data/spec/cpe_examples.rb
CHANGED
@@ -3,9 +3,9 @@ require 'rspec'
|
|
3
3
|
shared_examples_for "CPE" do
|
4
4
|
subject { super().cpe }
|
5
5
|
|
6
|
-
it {
|
6
|
+
it { is_expected.not_to be_empty }
|
7
7
|
|
8
8
|
it "should contain CPE URLs" do
|
9
|
-
subject.
|
9
|
+
expect(subject).to all(be_kind_of(CPE::URL))
|
10
10
|
end
|
11
11
|
end
|
data/spec/hop_spec.rb
CHANGED
data/spec/host_spec.rb
CHANGED
@@ -7,63 +7,65 @@ require 'nmap/host'
|
|
7
7
|
describe Host do
|
8
8
|
subject { @xml.hosts.first }
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
describe "#start_time" do
|
11
|
+
it "should parse the start_time" do
|
12
|
+
expect(subject.start_time).to be > Time.at(0)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
describe "#end_time" do
|
17
|
+
it "should parse the end_time" do
|
18
|
+
expect(subject.end_time).to be > Time.at(0)
|
19
|
+
expect(subject.end_time).to be > subject.start_time
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
describe "#uptime" do
|
20
24
|
subject { super().uptime }
|
21
25
|
|
22
26
|
it "should return an Uptime object" do
|
23
|
-
subject.
|
27
|
+
expect(subject).to be_kind_of(Uptime)
|
24
28
|
end
|
25
29
|
|
26
30
|
it "should parse the seconds attribute" do
|
27
|
-
subject.seconds.
|
31
|
+
expect(subject.seconds).to be > 0
|
28
32
|
end
|
29
33
|
|
30
34
|
it "should parse the lastboot attribute" do
|
31
|
-
subject.last_boot.
|
35
|
+
expect(subject.last_boot).to be_kind_of(Time)
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
39
|
describe "#tcp_sequence" do
|
36
40
|
subject { super().tcp_sequence }
|
37
41
|
|
38
|
-
it {
|
42
|
+
it { is_expected.to be_kind_of(TcpSequence) }
|
39
43
|
end
|
40
44
|
|
41
45
|
describe "#ip_ip_sequence" do
|
42
46
|
subject { super().ip_id_sequence }
|
43
47
|
|
44
|
-
it {
|
48
|
+
it { is_expected.to be_kind_of(IpIdSequence) }
|
45
49
|
end
|
46
50
|
|
47
51
|
describe "#tcp_ts_sequence" do
|
48
52
|
subject { super().tcp_ts_sequence }
|
49
53
|
|
50
|
-
it {
|
54
|
+
it { is_expected.to be_kind_of(TcpTsSequence) }
|
51
55
|
end
|
52
56
|
|
53
57
|
describe "#status" do
|
54
58
|
subject { super().status }
|
55
59
|
|
56
60
|
it "should parse the state" do
|
57
|
-
subject.state.
|
61
|
+
expect(subject.state).to eq(:up).or eq(:down)
|
58
62
|
end
|
59
63
|
|
60
64
|
it "should parse the reason" do
|
61
|
-
subject.reason.
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
'reset'
|
66
|
-
)
|
65
|
+
expect(subject.reason).to eq('syn-ack').or \
|
66
|
+
eq('timestamp-reply').or \
|
67
|
+
eq('echo-reply').or \
|
68
|
+
eq('reset')
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
@@ -71,120 +73,143 @@ describe Host do
|
|
71
73
|
subject { super().addresses.first }
|
72
74
|
|
73
75
|
it "should parse the type" do
|
74
|
-
subject.type.
|
76
|
+
expect(subject.type).to eq(:ipv4)
|
75
77
|
end
|
76
78
|
|
77
79
|
it "should parser the addr" do
|
78
|
-
subject.addr.
|
80
|
+
expect(subject.addr).to eq('74.207.244.221')
|
79
81
|
end
|
82
|
+
|
80
83
|
end
|
81
84
|
|
82
85
|
describe "#mac" do
|
83
86
|
it "should parse the first MAC address" do
|
84
|
-
|
87
|
+
skip "need a host with address[@addrtype='mac']"
|
85
88
|
end
|
86
89
|
end
|
87
90
|
|
88
91
|
describe "#ipv6" do
|
89
92
|
it "should parse the first IPv6 address" do
|
90
|
-
|
93
|
+
skip "need a host with address[@addrtype='ipv6']"
|
91
94
|
end
|
92
95
|
end
|
93
96
|
|
94
97
|
describe "#ipv4" do
|
95
98
|
it "should parse the IPv4 address" do
|
96
|
-
subject.ipv4.
|
99
|
+
expect(subject.ipv4).to eq('74.207.244.221')
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
100
103
|
describe "#ip" do
|
101
104
|
it "should have an IP" do
|
102
|
-
subject.ip.
|
105
|
+
expect(subject.ip).to eq('74.207.244.221')
|
103
106
|
end
|
104
107
|
end
|
105
108
|
|
106
109
|
describe "#address" do
|
107
110
|
it "should have an address" do
|
108
|
-
subject.address.
|
111
|
+
expect(subject.address).to eq('74.207.244.221')
|
109
112
|
end
|
110
113
|
end
|
111
114
|
|
112
115
|
describe "#hostnames" do
|
113
116
|
subject { super().hostnames }
|
114
117
|
|
115
|
-
it {
|
118
|
+
it { is_expected.not_to be_empty }
|
116
119
|
|
117
120
|
it "should parse the type" do
|
118
|
-
subject.all? { |hostname| hostname.type }.
|
121
|
+
expect(subject.all? { |hostname| hostname.type }).to be_truthy
|
119
122
|
end
|
120
123
|
|
121
124
|
it "should parse the name" do
|
122
|
-
subject.all? { |hostname| hostname.name }.
|
125
|
+
expect(subject.all? { |hostname| hostname.name }).to be_truthy
|
123
126
|
end
|
124
127
|
|
125
128
|
it "should include a user hostname" do
|
126
|
-
subject.any? { |hostname| hostname.type == 'user' }.
|
129
|
+
expect(subject.any? { |hostname| hostname.type == 'user' }).to be_truthy
|
127
130
|
end
|
128
131
|
|
129
132
|
it "should include a PTR hostname" do
|
130
|
-
subject.any? { |hostname| hostname.type == 'PTR' }.
|
133
|
+
expect(subject.any? { |hostname| hostname.type == 'PTR' }).to be_truthy
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "#hostname" do
|
138
|
+
it "should return the first hostname" do
|
139
|
+
expect(subject.hostname).to be == subject.hostnames.first
|
131
140
|
end
|
132
141
|
end
|
133
142
|
|
134
143
|
describe "#os" do
|
135
144
|
subject { super().os }
|
136
145
|
|
137
|
-
it {
|
138
|
-
it {
|
146
|
+
it { is_expected.not_to be_nil }
|
147
|
+
it { is_expected.to be_kind_of(OS) }
|
139
148
|
end
|
140
149
|
|
141
150
|
describe "#ports" do
|
142
151
|
subject { super().ports }
|
143
152
|
|
144
|
-
it {
|
153
|
+
it { is_expected.not_to be_empty }
|
145
154
|
end
|
146
155
|
|
147
156
|
describe "#open_ports" do
|
148
157
|
subject { super().open_ports }
|
149
158
|
|
150
|
-
it {
|
159
|
+
it { is_expected.not_to be_empty }
|
151
160
|
|
152
161
|
it "should list the open ports" do
|
153
|
-
subject.all? { |port| port.state == :open }.
|
162
|
+
expect(subject.all? { |port| port.state == :open }).to be_truthy
|
154
163
|
end
|
155
164
|
end
|
156
165
|
|
157
166
|
describe "#tcp_ports" do
|
158
167
|
subject { super().tcp_ports }
|
159
168
|
|
160
|
-
it {
|
169
|
+
it { is_expected.not_to be_empty }
|
161
170
|
|
162
171
|
it "should contain TCP ports" do
|
163
|
-
subject.all? { |port| port.protocol == :tcp }.
|
172
|
+
expect(subject.all? { |port| port.protocol == :tcp }).to be_truthy
|
164
173
|
end
|
165
174
|
end
|
166
175
|
|
167
176
|
describe "#udp_ports" do
|
168
177
|
subject { super().udp_ports }
|
169
178
|
|
170
|
-
it {
|
179
|
+
it { is_expected.not_to be_empty }
|
171
180
|
|
172
181
|
it "should contain UDP ports" do
|
173
|
-
subject.all? { |port| port.protocol == :udp }.
|
182
|
+
expect(subject.all? { |port| port.protocol == :udp }).to be_truthy
|
174
183
|
end
|
175
184
|
end
|
176
185
|
|
177
|
-
|
178
|
-
|
186
|
+
describe "#to_s" do
|
187
|
+
it "should return the first hostname" do
|
188
|
+
expect(subject.to_s).to eq('scanme.nmap.org')
|
189
|
+
end
|
190
|
+
|
191
|
+
context "when #hostname returns nil" do
|
192
|
+
before { expect(subject).to receive(:hostname).and_return(nil) }
|
193
|
+
|
194
|
+
it "should return the first address" do
|
195
|
+
expect(subject.to_s).to eq('74.207.244.221')
|
196
|
+
end
|
197
|
+
end
|
179
198
|
end
|
180
199
|
|
181
200
|
describe "#inspect" do
|
182
|
-
it "should include the
|
183
|
-
subject.inspect.
|
201
|
+
it "should include the String representation of the host" do
|
202
|
+
expect(subject.inspect).to include(subject.to_s)
|
184
203
|
end
|
185
204
|
end
|
186
205
|
|
187
|
-
|
206
|
+
skip "scan.xml does not currently include any hostscripts" do
|
188
207
|
include_examples "#scripts"
|
189
208
|
end
|
209
|
+
|
210
|
+
describe "#vendor" do
|
211
|
+
it "should parse the vendor name" do
|
212
|
+
expect(subject.vendor).to eq('Cadmus Computer Systems')
|
213
|
+
end
|
214
|
+
end
|
190
215
|
end
|
data/spec/hostname_spec.rb
CHANGED
@@ -2,14 +2,31 @@ require 'spec_helper'
|
|
2
2
|
require 'nmap/hostname'
|
3
3
|
|
4
4
|
describe Hostname do
|
5
|
+
let(:name) { 'scanme.nmap.org' }
|
6
|
+
|
7
|
+
describe "#user?" do
|
8
|
+
subject { described_class.new('user', name) }
|
9
|
+
|
10
|
+
it "should check if type is 'user'" do
|
11
|
+
expect(subject.user?).to eq(true)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#user?" do
|
16
|
+
subject { described_class.new('PTR', name) }
|
17
|
+
|
18
|
+
it "should check if type is 'PTR'" do
|
19
|
+
expect(subject.ptr?).to eq(true)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
5
23
|
describe "#to_s" do
|
6
|
-
let(:type) {
|
7
|
-
let(:name) { 'scanme.nmap.org' }
|
24
|
+
let(:type) { 'user' }
|
8
25
|
|
9
26
|
subject { described_class.new(type, name) }
|
10
27
|
|
11
28
|
it "should return the hostname" do
|
12
|
-
subject.to_s.
|
29
|
+
expect(subject.to_s).to eq(name)
|
13
30
|
end
|
14
31
|
end
|
15
32
|
end
|
data/spec/ip_id_sequence_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe IpIdSequence do
|
|
8
8
|
|
9
9
|
describe "#description" do
|
10
10
|
it "should parse the description" do
|
11
|
-
subject.description.
|
11
|
+
expect(subject.description).to eq("All zeros")
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -26,7 +26,7 @@ describe IpIdSequence do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should contain the description and values" do
|
29
|
-
subject.to_s.
|
29
|
+
expect(subject.to_s).to match(regexp)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
data/spec/nmap_spec.rb
CHANGED
data/spec/os_class_spec.rb
CHANGED
@@ -7,24 +7,34 @@ require 'cgi'
|
|
7
7
|
describe OS do
|
8
8
|
subject { @xml.hosts.first.os.classes.first }
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
describe "#type" do
|
11
|
+
it "should parse the type" do
|
12
|
+
expect(subject.type).to eq(:"general purpose")
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
describe "#vendor" do
|
17
|
+
it "should parse the vendor" do
|
18
|
+
expect(subject.vendor).to eq('Linux')
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
|
-
|
19
|
-
|
22
|
+
describe "#family" do
|
23
|
+
it "should parse the family" do
|
24
|
+
expect(subject.family).to eq(:Linux)
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
|
-
|
23
|
-
|
28
|
+
describe "#gen" do
|
29
|
+
it "should parse the gen" do
|
30
|
+
expect(subject.gen).to eq(:'2.6.X')
|
31
|
+
end
|
24
32
|
end
|
25
33
|
|
26
|
-
|
27
|
-
|
34
|
+
describe "#accuracy" do
|
35
|
+
it "should parse the accuracy" do
|
36
|
+
expect(subject.accuracy).to be_between(0,100)
|
37
|
+
end
|
28
38
|
end
|
29
39
|
|
30
40
|
it_should_behave_like "CPE"
|
data/spec/os_match_spec.rb
CHANGED
data/spec/os_spec.rb
CHANGED
@@ -9,10 +9,10 @@ describe OS do
|
|
9
9
|
describe "#classes" do
|
10
10
|
subject { super().classes }
|
11
11
|
|
12
|
-
it {
|
12
|
+
it { is_expected.not_to be_empty }
|
13
13
|
|
14
14
|
it "should return OSClass objects" do
|
15
|
-
subject.
|
15
|
+
expect(subject).to all(be_kind_of(OSClass))
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -20,24 +20,25 @@ describe OS do
|
|
20
20
|
subject { super().matches.first }
|
21
21
|
|
22
22
|
it "should parse the name" do
|
23
|
-
subject.name.
|
23
|
+
expect(subject.name).to eq('Linux 2.6.39')
|
24
24
|
end
|
25
25
|
|
26
26
|
it "should parse the accuracy" do
|
27
|
-
subject.accuracy.
|
27
|
+
expect(subject.accuracy).to be_between(0,100)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "#ports_used" do
|
32
32
|
subject { super().ports_used }
|
33
33
|
|
34
|
-
it { subject.
|
35
|
-
it { subject.
|
34
|
+
it { expect(subject).not_to be_empty }
|
35
|
+
it { expect(subject).to all(be_between(0,65535)) }
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
describe "#fingerprint" do
|
39
|
+
it "should parse the OS fingerprints" do
|
40
|
+
pending "scan.xml does not currently have an osfingerprint"
|
41
|
+
expect(subject.fingerprint).to eq(CGI.unescapeHTML("SCAN(V=4.68%D=8/16%OT=443%CT=21%CU=%PV=Y%DS=1%G=N%M=001D7E%TM=48A77607%P=i686-pc-linux-gnu)
SEQ(SP=19%GCD=FA00%ISR=9E%TI=I%TS=1)
OPS(O1=M5B4NW0NNT11%O2=M5B4NW0NNT11%O3=M5B4NW0NNT11%O4=M5B4NW0NNT11%O5=M5B4NW0NNT11%O6=M5B4NNT11)
WIN(W1=2000%W2=2000%W3=2000%W4=2000%W5=2000%W6=2000)
ECN(R=Y%DF=N%TG=40%W=2000%O=M5B4NW0%CC=N%Q=)
T1(R=Y%DF=N%TG=40%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=N)
T5(R=Y%DF=N%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=N)
T7(R=N)
U1(R=N)
IE(R=N)
"))
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
data/spec/port_spec.rb
CHANGED
@@ -4,27 +4,35 @@ require 'nmap/port'
|
|
4
4
|
describe Port do
|
5
5
|
subject { @xml.hosts.first.ports.first }
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
describe "#protocol" do
|
8
|
+
it "should parse the protocol" do
|
9
|
+
expect(subject.protocol).to eq(:tcp)
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
+
describe "#number" do
|
14
|
+
it "should parse the port number" do
|
15
|
+
expect(subject.number).to eq(22)
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
describe "#state" do
|
20
|
+
it "should parse the state" do
|
21
|
+
expect(subject.state).to eq(:open)
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
19
|
-
|
20
|
-
|
25
|
+
describe "#reason" do
|
26
|
+
it "should parse the reason" do
|
27
|
+
expect(subject.reason).to eq('syn-ack')
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
31
|
describe "#service" do
|
24
32
|
subject { super().service }
|
25
33
|
|
26
34
|
it "should return a Service object" do
|
27
|
-
subject.
|
35
|
+
expect(subject).to be_kind_of(Service)
|
28
36
|
end
|
29
37
|
end
|
30
38
|
|
@@ -32,7 +40,7 @@ describe Port do
|
|
32
40
|
|
33
41
|
describe "#inspect" do
|
34
42
|
it "should include the number" do
|
35
|
-
subject.inspect.
|
43
|
+
expect(subject.inspect).to include(subject.number.to_s)
|
36
44
|
end
|
37
45
|
end
|
38
46
|
end
|