Skip to content

Commit f5aa3ec

Browse files
committed
Add proper peer decoding
1 parent ab49d01 commit f5aa3ec

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

lib/rex/proto/kademlia/message.rb

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ def decode_bootstrap_res(message)
5555
# abort if this isn't a valid response
5656
return nil unless opcode = BOOTSTRAP_RES
5757
return nil unless payload.size >= 23
58-
# XXX: unsure how to get the 128-bit contact ID just yet...
59-
peer_id = payload.slice!(0,16)
58+
peer_id = decode_peer_id(payload.slice!(0,16))
6059
tcp_port, version, num_peers = payload.slice!(0,5).unpack('vCv')
6160
# protocol says there are no peers and the payload confirms this, so just return with no peers
6261
return [ tcp_port, version, []] if num_peers == 0 && payload.blank?
@@ -99,8 +98,20 @@ def decode_bootstrap_peer(peer_data)
9998
# TODO; interpret this properly
10099
peer_id = peer_data.slice!(0, 16)
101100
ip, udp_port, tcp_port, version = peer_data.unpack('VvvC')
102-
[ peer_id, Rex::Socket.addr_itoa(ip), udp_port, tcp_port, version ]
101+
[ decode_peer_id(peer_id), Rex::Socket.addr_itoa(ip), udp_port, tcp_port, version ]
102+
end
103+
104+
105+
def decode_peer_id(bytes)
106+
peer_id = 0
107+
return nil unless bytes.size == 16
108+
bytes.unpack('VVVV').map { |p| peer_id <<= 32; peer_id ^= p; }
109+
peer_id.to_s(16).upcase
110+
end
111+
112+
# TODO?
113+
def encode_peer_id(id)
103114
end
104115
end
105116
end
106-
end
117+
end

spec/lib/rex/proto/kademlia/message_spec.rb

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,13 @@
9595
peers = subject.decode_bootstrap_peers(data)
9696
expect(peers.size).to eq(2)
9797
peer1_id, peer1_ip, peer1_udp, peer1_tcp, peer1_type = peers.first
98+
expect(peer1_id).to eq('3020100070605040B0A09080F0E0D0C')
9899
expect(peer1_ip).to eq('192.168.40.4')
99100
expect(peer1_udp).to eq(54321)
100101
expect(peer1_tcp).to eq(12345)
101102
expect(peer1_type).to eq(8)
102103
peer2_id, peer2_ip, peer2_udp, peer2_tcp, peer2_type = peers.last
104+
expect(peer2_id).to eq('2020101040403030606050508080707')
103105
expect(peer2_ip).to eq('192.168.40.5')
104106
expect(peer2_udp).to eq(4444)
105107
expect(peer2_tcp).to eq(5555)
@@ -111,11 +113,27 @@
111113
it 'should properly decode valid bootstrap responses' do
112114
data = IO.read(File.join(File.dirname(__FILE__), 'kademlia_bootstrap_res.bin'))
113115
peer_id, tcp, version, peers = subject.decode_bootstrap_res(data)
114-
#expect(peer_id).to eq('XXXX')
116+
expect(peer_id).to eq('B54A83462529B21EF51FD54B956B07B0')
115117
expect(tcp).to eq(4662)
116118
expect(version).to eq(8)
117119
# don't bother checking every peer
118120
expect(peers.size).to eq(20)
119121
end
120122
end
121-
end
123+
124+
describe '#decode_peer_id' do
125+
it 'should decode a peer ID properly' do
126+
bytes = "\x00\x60\x89\x9B\x0A\x0B\xBE\xAE\x45\x35\xCB\x0E\x07\xA1\x77\x71"
127+
peer_id = "9B896000AEBE0B0A0ECB35457177A107"
128+
expect(subject.decode_peer_id(bytes)).to eq(peer_id)
129+
end
130+
end
131+
132+
describe '#encode_peer' do
133+
skip 'should encode a peer ID properly' do
134+
bytes = "\x00\x60\x89\x9B\x0A\x0B\xBE\xAE\x45\x35\xCB\x0E\x07\xA1\x77\x71"
135+
peer_id = "9B896000AEBE0B0A0ECB35457177A107"
136+
expect(subject.encode_peer_id(peer_id)).to eq(bytes)
137+
end
138+
end
139+
end

0 commit comments

Comments
 (0)