Skip to content

Commit f7a6411

Browse files
authored
LDAP - test against openLDAP, minor win-proto fixes (#4539)
* DCE/RPC: fix any() for conformant fields * Kerberos: fix crealm in Authenticator * Kerberos: add GET_SALT mode * LDAP: improve client, support for search() * Greatly improve SMB2 ACL support * Test our LDAP client against OpenLDAP * Update LDAP doc * TLS client test: also close client_socket
1 parent a07e5d5 commit f7a6411

File tree

12 files changed

+1254
-146
lines changed

12 files changed

+1254
-146
lines changed

.config/ci/install.sh

+9-1
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,22 @@ then
2727
fi
2828
fi
2929

30-
# Install wireshark data, ifconfig, vcan, samba
30+
CUR=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
31+
32+
# Install wireshark data, ifconfig, vcan, samba, openldap
3133
if [ "$OSTYPE" = "linux-gnu" ]
3234
then
3335
sudo apt-get update
3436
sudo apt-get -qy install tshark net-tools || exit 1
3537
sudo apt-get -qy install can-utils || exit 1
3638
sudo apt-get -qy install linux-modules-extra-$(uname -r) || exit 1
3739
sudo apt-get -qy install samba smbclient
40+
# For OpenLDAP, we need to pre-populate some setup questions
41+
sudo debconf-set-selections <<< 'slapd slapd/password2 password Bonjour1'
42+
sudo debconf-set-selections <<< 'slapd slapd/password1 password Bonjour1'
43+
sudo debconf-set-selections <<< 'slapd slapd/domain string scapy.net'
44+
sudo apt-get -qy install slapd
45+
ldapadd -D "cn=admin,dc=scapy,dc=net" -w Bonjour1 -f $CUR/openldap-testdata.ldif -c
3846
# Make sure libpcap is installed
3947
if [ ! -z $SCAPY_USE_LIBPCAP ]
4048
then

.config/ci/openldap-testdata.ldif

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# SPDX-License-Identifier: OLDAP-2.8
2+
# This file is https://git.openldap.org/openldap/openldap/-/blob/master/tests/data/ppolicy.ldif?ref_type=heads
3+
# (renamed to dc=scapy, dc=net)
4+
5+
dn: dc=scapy, dc=net
6+
objectClass: top
7+
objectClass: organization
8+
objectClass: dcObject
9+
o: Scapy
10+
dc: scapy
11+
12+
dn: ou=People, dc=scapy, dc=net
13+
objectClass: top
14+
objectClass: organizationalUnit
15+
ou: People
16+
17+
dn: ou=Groups, dc=scapy, dc=net
18+
objectClass: organizationalUnit
19+
ou: Groups
20+
21+
dn: cn=Policy Group, ou=Groups, dc=scapy, dc=net
22+
objectClass: groupOfNames
23+
cn: Policy Group
24+
member: uid=nd, ou=People, dc=scapy, dc=net
25+
owner: uid=ndadmin, ou=People, dc=scapy, dc=net
26+
27+
dn: cn=Test Group, ou=Groups, dc=scapy, dc=net
28+
objectClass: groupOfNames
29+
cn: Policy Group
30+
member: uid=another, ou=People, dc=scapy, dc=net
31+
32+
dn: ou=Policies, dc=scapy, dc=net
33+
objectClass: top
34+
objectClass: organizationalUnit
35+
ou: Policies
36+
37+
dn: cn=Standard Policy, ou=Policies, dc=scapy, dc=net
38+
objectClass: top
39+
objectClass: device
40+
objectClass: pwdPolicy
41+
cn: Standard Policy
42+
pwdAttribute: 2.5.4.35
43+
pwdLockoutDuration: 15
44+
pwdInHistory: 6
45+
pwdCheckQuality: 2
46+
pwdExpireWarning: 10
47+
pwdMaxAge: 30
48+
pwdMinLength: 5
49+
pwdMaxLength: 13
50+
pwdGraceAuthnLimit: 3
51+
pwdAllowUserChange: TRUE
52+
pwdMustChange: TRUE
53+
pwdMaxFailure: 3
54+
pwdFailureCountInterval: 120
55+
pwdSafeModify: TRUE
56+
pwdLockout: TRUE
57+
58+
dn: cn=Idle Expiration Policy, ou=Policies, dc=scapy, dc=net
59+
objectClass: top
60+
objectClass: device
61+
objectClass: pwdPolicy
62+
cn: Idle Expiration Policy
63+
pwdAttribute: 2.5.4.35
64+
pwdLockoutDuration: 15
65+
pwdInHistory: 6
66+
pwdCheckQuality: 2
67+
pwdExpireWarning: 10
68+
pwdMaxIdle: 15
69+
pwdMinLength: 5
70+
pwdMaxLength: 13
71+
pwdGraceAuthnLimit: 3
72+
pwdAllowUserChange: TRUE
73+
pwdMustChange: TRUE
74+
pwdMaxFailure: 3
75+
pwdFailureCountInterval: 120
76+
pwdSafeModify: TRUE
77+
pwdLockout: TRUE
78+
79+
dn: cn=Stricter Policy, ou=Policies, dc=scapy, dc=net
80+
objectClass: top
81+
objectClass: device
82+
objectClass: pwdPolicy
83+
cn: Stricter Policy
84+
pwdAttribute: 2.5.4.35
85+
pwdLockoutDuration: 15
86+
pwdInHistory: 6
87+
pwdCheckQuality: 2
88+
pwdExpireWarning: 10
89+
pwdMaxAge: 15
90+
pwdMinLength: 5
91+
pwdMaxLength: 13
92+
pwdAllowUserChange: TRUE
93+
pwdMustChange: TRUE
94+
pwdMaxFailure: 3
95+
pwdFailureCountInterval: 120
96+
pwdSafeModify: TRUE
97+
pwdLockout: TRUE
98+
99+
dn: cn=Another Policy, ou=Policies, dc=scapy, dc=net
100+
objectClass: top
101+
objectClass: device
102+
objectClass: pwdPolicy
103+
cn: Test Policy
104+
pwdAttribute: 2.5.4.35
105+
106+
dn: uid=nd, ou=People, dc=scapy, dc=net
107+
objectClass: top
108+
objectClass: person
109+
objectClass: inetOrgPerson
110+
cn: Neil Dunbar
111+
uid: nd
112+
sn: Dunbar
113+
givenName: Neil
114+
userPassword: testpassword
115+
116+
dn: uid=ndadmin, ou=People, dc=scapy, dc=net
117+
objectClass: top
118+
objectClass: person
119+
objectClass: inetOrgPerson
120+
cn: Neil Dunbar (Admin)
121+
uid: ndadmin
122+
sn: Dunbar
123+
givenName: Neil
124+
userPassword: testpw
125+
126+
dn: uid=test, ou=People, dc=scapy, dc=net
127+
objectClass: top
128+
objectClass: person
129+
objectClass: inetOrgPerson
130+
cn: test test
131+
uid: test
132+
sn: Test
133+
givenName: Test
134+
userPassword: kfhgkjhfdgkfd
135+
pwdPolicySubEntry: cn=No Policy, ou=Policies, dc=scapy, dc=net
136+
137+
dn: uid=another, ou=People, dc=scapy, dc=net
138+
objectClass: top
139+
objectClass: person
140+
objectClass: inetOrgPerson
141+
cn: Another Test
142+
uid: another
143+
sn: Test
144+
givenName: Another
145+
userPassword: testing
146+

doc/scapy/layers/ldap.rst

+27-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ LDAP
44
Scapy fully implements the LDAPv2 / LDAPv3 messages, in addition to a very basic :class:`~scapy.layers.ldap.LDAP_Client` class.
55

66
.. warning::
7-
*The String Representation of LDAP Search Filters* (RFC2254) is currently **unsupported**.
8-
This means that you can't use the commonly known LDAP search syntax, and instead have to use the binary format.
9-
PRs are welcome !
7+
Scapy's LDAP client is currently read-only. PRs are welcome !
8+
109

1110
LDAP client usage
1211
-----------------
@@ -16,6 +15,7 @@ The general idea when using the :class:`~scapy.layers.ldap.LDAP_Client` class co
1615
- instantiating the class
1716
- calling :func:`~scapy.layers.ldap.LDAP_Client.connect` with the IP (this is where to specify whether to use SSL or not)
1817
- calling :func:`~scapy.layers.ldap.LDAP_Client.bind` (this is where to specify a SSP if authentication is desired)
18+
- calling :func:`~scapy.layers.ldap.LDAP_Client.search` to search data.
1919

2020
The simplest, unauthenticated demo of the client would be something like:
2121

@@ -172,9 +172,28 @@ Once the LDAP connection is bound, it becomes possible to perform requests. For
172172
173173
client.sr1(LDAP_SearchRequest()).show()
174174
175-
Querying more complicated requests is a bit tedious, as it *currently* requires you to build the Search request yourself.
175+
We can also use the :func:`~scapy.layers.ldap.LDAP_Client.search` passing a base DN, a filter (as specified by RFC2254) and a scope.\\
176+
177+
The scope can be one of the following:
178+
179+
- 0=baseObject: only the base DN's attributes are queried
180+
- 1=singleLevel: the base DN's children are queried
181+
- 2=wholeSubtree: the entire subtree under the base DN is included
182+
176183
For instance, this corresponds to querying the DN ``CN=Users,DC=domain,DC=local`` with the filter ``(objectCategory=person)`` and asking for the attributes ``objectClass,name,description,canonicalName``:
177184

185+
.. code:: python
186+
187+
resp = client.search(
188+
"CN=Users,DC=domain,DC=local",
189+
"(objectCategory=person)",
190+
["objectClass", "name", "description", "canonicalName"],
191+
scope=1, # children
192+
)
193+
resp.show()
194+
195+
To understand exactly what's going on, note that the previous call is exactly identical to the following:
196+
178197
.. code:: python
179198
180199
resp = client.sr1(
@@ -199,4 +218,7 @@ For instance, this corresponds to querying the DN ``CN=Users,DC=domain,DC=local`
199218
attrsOnly=ASN1_BOOLEAN(0)
200219
)
201220
)
202-
resp.show()
221+
222+
223+
.. warning::
224+
Our RFC2254 parser currently does not support 'Extensible Match'.

scapy/layers/dcerpc.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1686,9 +1686,6 @@ def i2h(self, pkt, x):
16861686
def h2i(self, pkt, x):
16871687
return x
16881688

1689-
# def i2count(self, pkt, x):
1690-
# return 1
1691-
16921689
def i2len(self, pkt, x):
16931690
if x is None:
16941691
return 0
@@ -2156,7 +2153,7 @@ def i2len(self, pkt, x):
21562153
def any2i(self, pkt, x):
21572154
# User-friendly helper
21582155
if self.conformant_in_struct:
2159-
return x
2156+
return super(_NDRConfField, self).any2i(pkt, x)
21602157
if self.CONFORMANT_STRING and not isinstance(x, NDRConformantString):
21612158
return NDRConformantString(
21622159
value=super(_NDRConfField, self).any2i(pkt, x),

0 commit comments

Comments
 (0)