Skip to content

Commit 98b0232

Browse files
committed
SSH: fix _ComaStrField length calculation
AI-Assisted: yes (Claude Sonnet 4.6)
1 parent ab3b1bb commit 98b0232

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

scapy/layers/ssh.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ def m2i(self, pkt, x):
6262
def i2m(self, pkt, x):
6363
return super(_ComaStrField, self).i2m(pkt, b",".join(x))
6464

65+
def i2len(self, pkt, x):
66+
return len(self.i2m(pkt, x))
67+
6568

6669
class SSHString(Packet):
6770
fields_desc = [

test/scapy/layers/ssh.uts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,45 @@ assert pkts[10].pay.H_hash.value.data.key.value == b"\xef\xecj=~\xe4Y'\xe9\xad\x
3535

3636
assert isinstance(pkts[10][SSH:2].pay, SSHNewKeys)
3737
assert isinstance(pkts[12].pay, SSHNewKeys)
38+
39+
= ComaStrField encode/decode
40+
41+
import struct
42+
from scapy.layers.ssh import _ComaStrField
43+
44+
csf = _ComaStrField("names", [])
45+
46+
# m2i splits on commas
47+
assert csf.m2i(None, b"curve25519-sha256,diffie-hellman-group14-sha256") == \
48+
[b"curve25519-sha256", b"diffie-hellman-group14-sha256"]
49+
50+
# i2m joins with commas
51+
assert csf.i2m(None, [b"curve25519-sha256", b"diffie-hellman-group14-sha256"]) == \
52+
b"curve25519-sha256,diffie-hellman-group14-sha256"
53+
54+
# single element, no comma
55+
assert csf.m2i(None, b"ssh-ed25519") == [b"ssh-ed25519"]
56+
assert csf.i2m(None, [b"ssh-ed25519"]) == b"ssh-ed25519"
57+
58+
# empty string <-> single empty-name list
59+
assert csf.m2i(None, b"") == [b""]
60+
assert csf.i2m(None, [b""]) == b""
61+
62+
# round trips
63+
names = [b"a", b"b", b"c"]
64+
assert csf.m2i(None, csf.i2m(None, names)) == names
65+
raw = b"x,y,z"
66+
assert csf.i2m(None, csf.m2i(None, raw)) == raw
67+
68+
# through NameList length
69+
nl = NameList(names=[b"curve25519-sha256"])
70+
raw = bytes(nl)
71+
assert struct.unpack("!I", raw[:4])[0] == len(b"curve25519-sha256"), \
72+
"NameList length field encodes item count instead of byte length"
73+
74+
# Multi-name list
75+
nl2 = NameList(names=[b"curve25519-sha256", b"diffie-hellman-group14-sha256"])
76+
raw2 = bytes(nl2)
77+
expected = b"curve25519-sha256,diffie-hellman-group14-sha256"
78+
assert raw2[4:] == expected
79+
assert struct.unpack("!I", raw2[:4])[0] == len(expected)

0 commit comments

Comments
 (0)