Skip to content

Commit b98a433

Browse files
committed
Add the NTPHeader specs
1 parent 17045b7 commit b98a433

File tree

1 file changed

+294
-0
lines changed

1 file changed

+294
-0
lines changed

spec/lib/rex/proto/ntp/header_spec.rb

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
# -*- coding:binary -*-
2+
3+
require 'spec_helper'
4+
5+
RSpec.describe Rex::Proto::NTP::Header::NTPShort do
6+
context 'in the default state' do
7+
describe '#to_binary_s' do
8+
it 'is four null bytes' do
9+
expect(subject.to_binary_s).to eq "\x00\x00\x00\x00".b
10+
end
11+
end
12+
13+
describe '#value' do
14+
it 'is a BigDecimal instance' do
15+
expect(subject.value).to be_a(BigDecimal)
16+
end
17+
18+
it 'is zero' do
19+
expect(subject.value).to eq 0
20+
end
21+
end
22+
end
23+
24+
context 'when set to a real value' do
25+
let(:value) { 10.015182 }
26+
let(:subject) { described_class.new(value) }
27+
28+
describe '#to_binary_s' do
29+
it 'is four null bytes' do
30+
expect(subject.to_binary_s).to eq "\x00\x0a\x03\xe3".b
31+
end
32+
end
33+
34+
describe '#value' do
35+
it 'is a BigDecimal instance' do
36+
expect(subject.value).to be_a(BigDecimal)
37+
end
38+
39+
it 'is the correct value' do
40+
expect(subject.value.round(6)).to eq value
41+
end
42+
end
43+
end
44+
end
45+
46+
RSpec.describe Rex::Proto::NTP::Header::NTPTimestamp do
47+
context 'in the default state' do
48+
describe '#to_binary_s' do
49+
it 'is eight null bytes' do
50+
expect(subject.to_binary_s).to eq "\x00\x00\x00\x00\x00\x00\x00\x00".b
51+
end
52+
end
53+
54+
describe '#value' do
55+
it 'is nil' do
56+
expect(subject.value).to be_nil
57+
end
58+
end
59+
end
60+
61+
context 'when set to a real value' do
62+
let(:timestamp) { Time.parse('2024-12-12 15:32:42.555253 +0000') }
63+
context 'from parts' do
64+
let(:subject) { described_class.new.tap { |ts| ts.seconds = 0xeb05809a; ts.fraction = 0x8e2517e7 } }
65+
66+
describe '#to_binary_s' do
67+
it 'is correct' do
68+
expect(subject.to_binary_s).to eq "\xeb\x05\x80\x9a\x8e\x25\x17\xe7".b
69+
end
70+
end
71+
72+
describe '#value' do
73+
it 'is a Time instance' do
74+
expect(subject.value).to be_a(Time)
75+
end
76+
77+
it 'is the correct value' do
78+
expect(subject.value.round(6)).to eq timestamp
79+
end
80+
end
81+
end
82+
83+
context 'from a timestamp' do
84+
let(:subject) { described_class.new(timestamp) }
85+
86+
describe '#to_binary_s' do
87+
it 'is correct' do
88+
expect(subject.to_binary_s).to eq "\xeb\x05\x80\x9a\x8e\x25\x0f\x84".b
89+
end
90+
end
91+
92+
describe '#value' do
93+
it 'is a Time instance' do
94+
expect(subject.value).to be_a(Time)
95+
end
96+
97+
it 'is the correct value' do
98+
expect(subject.value.round(6)).to eq timestamp
99+
end
100+
end
101+
end
102+
end
103+
end
104+
105+
RSpec.describe Rex::Proto::NTP::Header::NTPHeader do
106+
context 'in the default state' do
107+
describe '#to_binary_s' do
108+
it 'is correct' do
109+
expect(subject.to_binary_s).to eq ("\x20".b + ("\x00".b * 47))
110+
end
111+
end
112+
113+
describe '#version_number' do
114+
it 'is the latest supported version' do
115+
expect(subject.version_number).to eq 4
116+
end
117+
118+
it 'throws an exception when set to an invalid value' do
119+
expect { subject.version_number = 0 }.to raise_error(BinData::ValidityError)
120+
expect { subject.version_number = 5 }.to raise_error(BinData::ValidityError)
121+
end
122+
end
123+
124+
describe '#root_delay' do
125+
it 'is an NTPShort' do
126+
expect(subject.root_delay).to be_a Rex::Proto::NTP::Header::NTPShort
127+
end
128+
129+
it 'is 0' do
130+
expect(subject.root_delay).to eq 0
131+
end
132+
end
133+
134+
describe '#root_dispersion' do
135+
it 'is an NTPShort' do
136+
expect(subject.root_dispersion).to be_a Rex::Proto::NTP::Header::NTPShort
137+
end
138+
139+
it 'is 0' do
140+
expect(subject.root_dispersion).to eq 0
141+
end
142+
end
143+
144+
describe '#reference_id' do
145+
it 'is an empty string' do
146+
expect(subject.reference_id).to eq ''
147+
end
148+
end
149+
150+
describe '#reference_timestamp' do
151+
it 'is an NTPTimestamp' do
152+
expect(subject.reference_timestamp).to be_a Rex::Proto::NTP::Header::NTPTimestamp
153+
end
154+
155+
it 'is nil' do
156+
expect(subject.reference_timestamp).to eq nil
157+
end
158+
end
159+
160+
describe '#origin_timestamp' do
161+
it 'is an NTPTimestamp' do
162+
expect(subject.origin_timestamp).to be_a Rex::Proto::NTP::Header::NTPTimestamp
163+
end
164+
165+
it 'is nil' do
166+
expect(subject.origin_timestamp).to eq nil
167+
end
168+
end
169+
170+
describe '#receive_timestamp' do
171+
it 'is an NTPTimestamp' do
172+
expect(subject.receive_timestamp).to be_a Rex::Proto::NTP::Header::NTPTimestamp
173+
end
174+
175+
it 'is nil' do
176+
expect(subject.receive_timestamp).to eq nil
177+
end
178+
end
179+
180+
describe '#transmit_timestamp' do
181+
it 'is an NTPTimestamp' do
182+
expect(subject.transmit_timestamp).to be_a Rex::Proto::NTP::Header::NTPTimestamp
183+
end
184+
185+
it 'is nil' do
186+
expect(subject.transmit_timestamp).to eq nil
187+
end
188+
end
189+
190+
describe '#extensions' do
191+
it 'is empty' do
192+
expect(subject.extensions).to be_empty
193+
end
194+
end
195+
196+
describe '#key_identifier' do
197+
it 'is not set' do
198+
expect(subject.key_identifier?).to be_falsey
199+
end
200+
201+
it 'is zero' do
202+
expect(subject.key_identifier).to eq 0
203+
end
204+
end
205+
206+
describe '#message_digest' do
207+
it 'is not set' do
208+
expect(subject.message_digest?).to be_falsey
209+
end
210+
211+
it 'is empty' do
212+
expect(subject.message_digest).to be_empty
213+
end
214+
end
215+
end
216+
217+
describe '#read' do
218+
let(:subject) { described_class.new.read(packed) }
219+
context 'when there is no MIC' do
220+
let(:packed) { "\x20" + ("\x00".b * 47) }
221+
222+
describe '#key_identifier' do
223+
it 'is not set' do
224+
expect(subject.key_identifier?).to be_falsey
225+
end
226+
227+
it 'is zero' do
228+
expect(subject.key_identifier).to eq 0
229+
end
230+
end
231+
232+
describe '#message_digest' do
233+
it 'is not set' do
234+
expect(subject.message_digest?).to be_falsey
235+
end
236+
237+
it 'is empty' do
238+
expect(subject.message_digest).to be_empty
239+
end
240+
end
241+
end
242+
243+
context 'when there is a key identifier but no message_digest (Crypto-NAK)' do
244+
let(:key_identifier) { 0xdead1337 }
245+
let(:packed) { "\x20" + ("\x00".b * 47) + [key_identifier].pack('N') }
246+
247+
describe '#key_identifier' do
248+
it 'is set' do
249+
expect(subject.key_identifier?).to be_truthy
250+
end
251+
252+
it 'is correct' do
253+
expect(subject.key_identifier).to eq key_identifier
254+
end
255+
end
256+
257+
describe '#message_digest' do
258+
it 'is not set' do
259+
expect(subject.message_digest?).to be_falsey
260+
end
261+
262+
it 'is empty' do
263+
expect(subject.message_digest).to be_empty
264+
end
265+
end
266+
end
267+
268+
context 'when there is a key identifier and a message digest' do
269+
let(:key_identifier) { 0xdead1337 }
270+
let(:message_digest) { (0..15).to_a }
271+
let(:packed) { "\x20" + ("\x00".b * 47) + [key_identifier].pack('N') + message_digest.pack('C*') }
272+
273+
describe '#key_identifier' do
274+
it 'is set' do
275+
expect(subject.key_identifier?).to be_truthy
276+
end
277+
278+
it 'is correct' do
279+
expect(subject.key_identifier).to eq key_identifier
280+
end
281+
end
282+
283+
describe '#message_digest' do
284+
it 'is set' do
285+
expect(subject.message_digest?).to be_truthy
286+
end
287+
288+
it 'is empty' do
289+
expect(subject.message_digest).to eq message_digest
290+
end
291+
end
292+
end
293+
end
294+
end

0 commit comments

Comments
 (0)