python/tests: add auth_pad test for the dcerpc raw_protocol test
[samba.git] / python / samba / tests / dcerpc / raw_protocol.py
1 #!/usr/bin/env python
2 # Unix SMB/CIFS implementation.
3 # Copyright (C) Stefan Metzmacher 2014,2015
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 #
18
19 import sys
20 import os
21
22 sys.path.insert(0, "bin/python")
23 os.environ["PYTHONUNBUFFERED"] = "1"
24
25 import samba.dcerpc.dcerpc as dcerpc
26 import samba.dcerpc.base as base
27 import samba.dcerpc.epmapper
28 import samba.dcerpc.mgmt
29 import samba.dcerpc.netlogon
30 import struct
31 from samba.credentials import Credentials
32 from samba import gensec
33 from samba.tests import RawDCERPCTest
34
35 global_ndr_print = False
36 global_hexdump = False
37
38 class TestDCERPC_BIND(RawDCERPCTest):
39
40     def setUp(self):
41         super(TestDCERPC_BIND, self).setUp()
42         self.do_ndr_print = global_ndr_print
43         self.do_hexdump = global_hexdump
44
45     def _test_no_auth_request_bind_pfc_flags(self, req_pfc_flags, rep_pfc_flags):
46         ndr32 = base.transfer_syntax_ndr()
47
48         tsf1_list = [ndr32]
49         ctx1 = dcerpc.ctx_list()
50         ctx1.context_id = 1
51         ctx1.num_transfer_syntaxes = len(tsf1_list)
52         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
53         ctx1.transfer_syntaxes = tsf1_list
54
55         req = self.generate_bind(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1])
56         self.send_pdu(req)
57         rep = self.recv_pdu()
58         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
59                         pfc_flags=rep_pfc_flags, auth_length=0)
60         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
61         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
62         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
63         self.assertEquals(rep.u.secondary_address_size, 4)
64         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
65         self.assertEquals(len(rep.u._pad1), 2)
66         # sometimes windows sends random bytes
67         # self.assertEquals(rep.u._pad1, '\0' * 2)
68         self.assertEquals(rep.u.num_results, 1)
69         self.assertEquals(rep.u.ctx_list[0].result,
70                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
71         self.assertEquals(rep.u.ctx_list[0].reason,
72                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
73         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
74         self.assertEquals(rep.u.auth_info, '\0' * 0)
75
76         # And now try a request
77         req = self.generate_request(call_id = 1,
78                                     context_id=ctx1.context_id,
79                                     opnum=0,
80                                     stub="")
81         self.send_pdu(req)
82         rep = self.recv_pdu()
83         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
84                         auth_length=0)
85         self.assertNotEquals(rep.u.alloc_hint, 0)
86         self.assertEquals(rep.u.context_id, req.u.context_id)
87         self.assertEquals(rep.u.cancel_count, 0)
88         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
89
90     def _test_no_auth_request_alter_pfc_flags(self, req_pfc_flags, rep_pfc_flags):
91         ndr32 = base.transfer_syntax_ndr()
92
93         tsf1_list = [ndr32]
94         ctx1 = dcerpc.ctx_list()
95         ctx1.context_id = 1
96         ctx1.num_transfer_syntaxes = len(tsf1_list)
97         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
98         ctx1.transfer_syntaxes = tsf1_list
99
100         req = self.generate_bind(call_id=0, ctx_list=[ctx1])
101         self.send_pdu(req)
102         rep = self.recv_pdu()
103         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
104                         auth_length=0)
105         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
106         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
107         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
108         self.assertEquals(rep.u.secondary_address_size, 4)
109         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
110         self.assertEquals(len(rep.u._pad1), 2)
111         # sometimes windows sends random bytes
112         # self.assertEquals(rep.u._pad1, '\0' * 2)
113         self.assertEquals(rep.u.num_results, 1)
114         self.assertEquals(rep.u.ctx_list[0].result,
115                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
116         self.assertEquals(rep.u.ctx_list[0].reason,
117                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
118         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
119         self.assertEquals(rep.u.auth_info, '\0' * 0)
120
121         # And now try a alter context
122         req = self.generate_alter(call_id=0, pfc_flags=req_pfc_flags, ctx_list=[ctx1])
123         self.send_pdu(req)
124         rep = self.recv_pdu()
125         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id,
126                         pfc_flags=rep_pfc_flags, auth_length=0)
127         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
128         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
129         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
130         self.assertEquals(rep.u.secondary_address_size, 0)
131         self.assertEquals(rep.u.secondary_address, "")
132         self.assertEquals(len(rep.u._pad1), 2)
133         # sometimes windows sends random bytes
134         # self.assertEquals(rep.u._pad1, '\0' * 2)
135         self.assertEquals(rep.u.num_results, 1)
136         self.assertEquals(rep.u.ctx_list[0].result,
137                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
138         self.assertEquals(rep.u.ctx_list[0].reason,
139                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
140         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
141         self.assertEquals(rep.u.auth_info, '\0' * 0)
142
143         # And now try a request
144         req = self.generate_request(call_id = 1,
145                                     context_id=ctx1.context_id,
146                                     opnum=0,
147                                     stub="")
148         self.send_pdu(req)
149         rep = self.recv_pdu()
150         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
151                         auth_length=0)
152         self.assertNotEquals(rep.u.alloc_hint, 0)
153         self.assertEquals(rep.u.context_id, req.u.context_id)
154         self.assertEquals(rep.u.cancel_count, 0)
155         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
156
157     def test_no_auth_request(self):
158         return self._test_no_auth_request_bind_pfc_flags(
159                                         req_pfc_flags=0 |
160                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
161                                         dcerpc.DCERPC_PFC_FLAG_LAST,
162                                         rep_pfc_flags=0 |
163                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
164                                         dcerpc.DCERPC_PFC_FLAG_LAST)
165
166     def test_no_auth_request_bind_pfc_00(self):
167         return self._test_no_auth_request_bind_pfc_flags(
168                                         req_pfc_flags=0 |
169                                         0,
170                                         rep_pfc_flags=0 |
171                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
172                                         dcerpc.DCERPC_PFC_FLAG_LAST)
173
174     def test_no_auth_request_bind_pfc_FIRST(self):
175         return self._test_no_auth_request_bind_pfc_flags(
176                                         req_pfc_flags=0 |
177                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
178                                         0,
179                                         rep_pfc_flags=0 |
180                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
181                                         dcerpc.DCERPC_PFC_FLAG_LAST)
182
183     def test_no_auth_request_bind_pfc_LAST(self):
184         return self._test_no_auth_request_bind_pfc_flags(
185                                         req_pfc_flags=0 |
186                                         dcerpc.DCERPC_PFC_FLAG_LAST |
187                                         0,
188                                         rep_pfc_flags=0 |
189                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
190                                         dcerpc.DCERPC_PFC_FLAG_LAST)
191
192     # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
193     # without authentication
194     def _test_no_auth_request_bind_pfc_HDR_SIGNING(self):
195         return self._test_no_auth_request_bind_pfc_flags(
196                                         req_pfc_flags=0 |
197                                         dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
198                                         0,
199                                         rep_pfc_flags=0 |
200                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
201                                         dcerpc.DCERPC_PFC_FLAG_LAST |
202                                         dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)
203
204     def test_no_auth_request_bind_pfc_08(self):
205         return self._test_no_auth_request_bind_pfc_flags(
206                                         req_pfc_flags=0 |
207                                         8 |
208                                         0,
209                                         rep_pfc_flags=0 |
210                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
211                                         dcerpc.DCERPC_PFC_FLAG_LAST)
212
213     # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX
214     # by default
215     def _test_no_auth_request_bind_pfc_CONC_MPX(self):
216         return self._test_no_auth_request_bind_pfc_flags(
217                                         req_pfc_flags=0 |
218                                         dcerpc.DCERPC_PFC_FLAG_CONC_MPX |
219                                         0,
220                                         rep_pfc_flags=0 |
221                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
222                                         dcerpc.DCERPC_PFC_FLAG_LAST |
223                                         dcerpc.DCERPC_PFC_FLAG_CONC_MPX)
224
225     def test_no_auth_request_bind_pfc_DID_NOT_EXECUTE(self):
226         return self._test_no_auth_request_bind_pfc_flags(
227                                         req_pfc_flags=0 |
228                                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
229                                         0,
230                                         rep_pfc_flags=0 |
231                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
232                                         dcerpc.DCERPC_PFC_FLAG_LAST)
233
234     def test_no_auth_request_bind_pfc_MAYBE(self):
235         return self._test_no_auth_request_bind_pfc_flags(
236                                         req_pfc_flags=0 |
237                                         dcerpc.DCERPC_PFC_FLAG_MAYBE |
238                                         0,
239                                         rep_pfc_flags=0 |
240                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
241                                         dcerpc.DCERPC_PFC_FLAG_LAST)
242
243     def test_no_auth_request_bind_pfc_OBJECT_UUID(self):
244         return self._test_no_auth_request_bind_pfc_flags(
245                                         req_pfc_flags=0 |
246                                         dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID |
247                                         0,
248                                         rep_pfc_flags=0 |
249                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
250                                         dcerpc.DCERPC_PFC_FLAG_LAST)
251
252     # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
253     # without authentication
254     # TODO: doesn't announce DCERPC_PFC_FLAG_CONC_MPX
255     # by default
256     def _test_no_auth_request_bind_pfc_ff(self):
257         return self._test_no_auth_request_bind_pfc_flags(
258                                         req_pfc_flags=0 |
259                                         0xff |
260                                         0,
261                                         rep_pfc_flags=0 |
262                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
263                                         dcerpc.DCERPC_PFC_FLAG_LAST |
264                                         dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
265                                         dcerpc.DCERPC_PFC_FLAG_CONC_MPX)
266
267     def test_no_auth_request_alter_pfc_00(self):
268         return self._test_no_auth_request_alter_pfc_flags(
269                                         req_pfc_flags=0 |
270                                         0,
271                                         rep_pfc_flags=0 |
272                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
273                                         dcerpc.DCERPC_PFC_FLAG_LAST)
274
275     def test_no_auth_request_alter_pfc_FIRST(self):
276         return self._test_no_auth_request_alter_pfc_flags(
277                                         req_pfc_flags=0 |
278                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
279                                         0,
280                                         rep_pfc_flags=0 |
281                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
282                                         dcerpc.DCERPC_PFC_FLAG_LAST)
283
284     def test_no_auth_request_alter_pfc_LAST(self):
285         return self._test_no_auth_request_alter_pfc_flags(
286                                         req_pfc_flags=0 |
287                                         dcerpc.DCERPC_PFC_FLAG_LAST |
288                                         0,
289                                         rep_pfc_flags=0 |
290                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
291                                         dcerpc.DCERPC_PFC_FLAG_LAST)
292
293     # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
294     # without authentication
295     def _test_no_auth_request_alter_pfc_HDR_SIGNING(self):
296         return self._test_no_auth_request_alter_pfc_flags(
297                                         req_pfc_flags=0 |
298                                         dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
299                                         0,
300                                         rep_pfc_flags=0 |
301                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
302                                         dcerpc.DCERPC_PFC_FLAG_LAST |
303                                         dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)
304
305     def test_no_auth_request_alter_pfc_08(self):
306         return self._test_no_auth_request_alter_pfc_flags(
307                                         req_pfc_flags=0 |
308                                         8 |
309                                         0,
310                                         rep_pfc_flags=0 |
311                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
312                                         dcerpc.DCERPC_PFC_FLAG_LAST)
313
314     def test_no_auth_request_alter_pfc_CONC_MPX(self):
315         return self._test_no_auth_request_alter_pfc_flags(
316                                         req_pfc_flags=0 |
317                                         dcerpc.DCERPC_PFC_FLAG_CONC_MPX |
318                                         0,
319                                         rep_pfc_flags=0 |
320                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
321                                         dcerpc.DCERPC_PFC_FLAG_LAST)
322
323     def test_no_auth_request_alter_pfc_DID_NOT_EXECUTE(self):
324         return self._test_no_auth_request_alter_pfc_flags(
325                                         req_pfc_flags=0 |
326                                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
327                                         0,
328                                         rep_pfc_flags=0 |
329                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
330                                         dcerpc.DCERPC_PFC_FLAG_LAST)
331
332     def test_no_auth_request_alter_pfc_MAYBE(self):
333         return self._test_no_auth_request_alter_pfc_flags(
334                                         req_pfc_flags=0 |
335                                         dcerpc.DCERPC_PFC_FLAG_MAYBE |
336                                         0,
337                                         rep_pfc_flags=0 |
338                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
339                                         dcerpc.DCERPC_PFC_FLAG_LAST)
340
341     def test_no_auth_request_alter_pfc_OBJECT_UUID(self):
342         return self._test_no_auth_request_alter_pfc_flags(
343                                         req_pfc_flags=0 |
344                                         dcerpc.DCERPC_PFC_FLAG_OBJECT_UUID |
345                                         0,
346                                         rep_pfc_flags=0 |
347                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
348                                         dcerpc.DCERPC_PFC_FLAG_LAST)
349
350     # TODO: doesn't announce DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
351     # without authentication
352     def _test_no_auth_request_alter_pfc_ff(self):
353         return self._test_no_auth_request_alter_pfc_flags(
354                                         req_pfc_flags=0 |
355                                         0xff |
356                                         0,
357                                         rep_pfc_flags=0 |
358                                         dcerpc.DCERPC_PFC_FLAG_FIRST |
359                                         dcerpc.DCERPC_PFC_FLAG_LAST |
360                                         dcerpc.DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)
361
362     def test_no_auth_no_ctx(self):
363         # send an useless bind
364         req = self.generate_bind(call_id=0)
365         self.send_pdu(req)
366         rep = self.recv_pdu()
367         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
368                         auth_length=0)
369         self.assertEquals(rep.u.reject_reason,
370                 dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
371         self.assertEquals(rep.u.num_versions, 1)
372         self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
373         self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
374         self.assertEquals(len(rep.u._pad), 3)
375         self.assertEquals(rep.u._pad, '\0' * 3)
376
377     def test_invalid_auth_noctx(self):
378         req = self.generate_bind(call_id=0)
379         req.auth_length = dcerpc.DCERPC_AUTH_TRAILER_LENGTH
380         self.send_pdu(req)
381         rep = self.recv_pdu()
382         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
383                         auth_length=0)
384         self.assertEquals(rep.u.reject_reason,
385                 dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED)
386         self.assertEquals(rep.u.num_versions, 1)
387         self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
388         self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
389         self.assertEquals(len(rep.u._pad), 3)
390         self.assertEquals(rep.u._pad, '\0' * 3)
391
392     def test_no_auth_valid_valid_request(self):
393         ndr32 = base.transfer_syntax_ndr()
394
395         tsf1_list = [ndr32]
396         ctx1 = dcerpc.ctx_list()
397         ctx1.context_id = 1
398         ctx1.num_transfer_syntaxes = len(tsf1_list)
399         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
400         ctx1.transfer_syntaxes = tsf1_list
401
402         req = self.generate_bind(call_id=0, ctx_list=[ctx1])
403         self.send_pdu(req)
404         rep = self.recv_pdu()
405         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
406                         auth_length=0)
407         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
408         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
409         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
410         self.assertEquals(rep.u.secondary_address_size, 4)
411         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
412         self.assertEquals(len(rep.u._pad1), 2)
413         self.assertEquals(rep.u._pad1, '\0' * 2)
414         self.assertEquals(rep.u.num_results, 1)
415         self.assertEquals(rep.u.ctx_list[0].result,
416                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
417         self.assertEquals(rep.u.ctx_list[0].reason,
418                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
419         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
420         self.assertEquals(rep.u.auth_info, '\0' * 0)
421
422         # Send a bind again
423         tsf2_list = [ndr32]
424         ctx2 = dcerpc.ctx_list()
425         ctx2.context_id = 2
426         ctx2.num_transfer_syntaxes = len(tsf2_list)
427         ctx2.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
428         ctx2.transfer_syntaxes = tsf2_list
429
430         req = self.generate_bind(call_id=1, ctx_list=[ctx2])
431         self.send_pdu(req)
432         rep = self.recv_pdu()
433         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
434                         auth_length=0)
435         self.assertEquals(rep.u.reject_reason,
436                 dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
437         self.assertEquals(rep.u.num_versions, 1)
438         self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
439         self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
440         self.assertEquals(len(rep.u._pad), 3)
441         self.assertEquals(rep.u._pad, '\0' * 3)
442
443         # wait for a disconnect
444         rep = self.recv_pdu()
445         self.assertIsNone(rep)
446         self.assertNotConnected()
447
448     def test_no_auth_invalid_valid_request(self):
449         # send an useless bind
450         req = self.generate_bind(call_id=0)
451         self.send_pdu(req)
452         rep = self.recv_pdu()
453         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
454                         auth_length=0)
455         self.assertEquals(rep.u.reject_reason,
456                 dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
457         self.assertEquals(rep.u.num_versions, 1)
458         self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
459         self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
460         self.assertEquals(len(rep.u._pad), 3)
461         self.assertEquals(rep.u._pad, '\0' * 3)
462
463         ndr32 = base.transfer_syntax_ndr()
464
465         tsf1_list = [ndr32]
466         ctx1 = dcerpc.ctx_list()
467         ctx1.context_id = 1
468         ctx1.num_transfer_syntaxes = len(tsf1_list)
469         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
470         ctx1.transfer_syntaxes = tsf1_list
471
472         # wait for a disconnect
473         rep = self.recv_pdu()
474         self.assertIsNone(rep)
475         self.assertNotConnected()
476
477     def test_alter_no_auth_no_ctx(self):
478         ndr32 = base.transfer_syntax_ndr()
479
480         tsf1_list = [ndr32]
481         ctx1 = dcerpc.ctx_list()
482         ctx1.context_id = 1
483         ctx1.num_transfer_syntaxes = len(tsf1_list)
484         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
485         ctx1.transfer_syntaxes = tsf1_list
486
487         req = self.generate_bind(call_id=0, ctx_list=[ctx1])
488         self.send_pdu(req)
489         rep = self.recv_pdu()
490         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
491                         auth_length=0)
492         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
493         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
494         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
495         self.assertEquals(rep.u.secondary_address_size, 4)
496         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
497         self.assertEquals(len(rep.u._pad1), 2)
498         self.assertEquals(rep.u._pad1, '\0' * 2)
499         self.assertEquals(rep.u.num_results, 1)
500         self.assertEquals(rep.u.ctx_list[0].result,
501                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
502         self.assertEquals(rep.u.ctx_list[0].reason,
503                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
504         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
505         self.assertEquals(rep.u.auth_info, '\0' * 0)
506
507         # Send a alter
508         req = self.generate_alter(call_id=1, ctx_list=[])
509         self.send_pdu(req)
510         rep = self.recv_pdu()
511         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
512                         pfc_flags=req.pfc_flags |
513                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
514                         auth_length=0)
515         self.assertNotEquals(rep.u.alloc_hint, 0)
516         self.assertEquals(rep.u.context_id, 0)
517         self.assertEquals(rep.u.cancel_count, 0)
518         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
519         self.assertEquals(len(rep.u._pad), 4)
520         self.assertEquals(rep.u._pad, '\0' * 4)
521
522         # wait for a disconnect
523         rep = self.recv_pdu()
524         self.assertIsNone(rep)
525         self.assertNotConnected()
526
527     def _test_auth_none_level_bind(self, auth_level,
528                                    reason=dcerpc.DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE):
529         ndr32 = base.transfer_syntax_ndr()
530
531         tsf1_list = [ndr32]
532         ctx1 = dcerpc.ctx_list()
533         ctx1.context_id = 1
534         ctx1.num_transfer_syntaxes = len(tsf1_list)
535         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
536         ctx1.transfer_syntaxes = tsf1_list
537         ctx_list = [ctx1]
538
539         auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE
540         auth_context_id = 0
541
542         auth_info = self.generate_auth(auth_type=auth_type,
543                                        auth_level=auth_level,
544                                        auth_context_id=auth_context_id,
545                                        auth_blob="none")
546
547         req = self.generate_bind(call_id=0,
548                                  ctx_list=ctx_list,
549                                  auth_info=auth_info)
550         self.send_pdu(req)
551         rep = self.recv_pdu()
552         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
553                         auth_length=0)
554         self.assertEquals(rep.u.reject_reason, reason)
555         self.assertEquals(rep.u.num_versions, 1)
556         self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
557         self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
558         self.assertEquals(len(rep.u._pad), 3)
559         self.assertEquals(rep.u._pad, '\0' * 3)
560
561         ndr32 = base.transfer_syntax_ndr()
562
563         tsf1_list = [ndr32]
564         ctx1 = dcerpc.ctx_list()
565         ctx1.context_id = 1
566         ctx1.num_transfer_syntaxes = len(tsf1_list)
567         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
568         ctx1.transfer_syntaxes = tsf1_list
569
570         # wait for a disconnect
571         rep = self.recv_pdu()
572         self.assertIsNone(rep)
573         self.assertNotConnected()
574
575     def test_auth_none_none_bind(self):
576         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_NONE,
577                             reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
578
579     def test_auth_none_connect_bind(self):
580         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_CONNECT)
581
582     def test_auth_none_call_bind(self):
583         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_CALL)
584
585     def test_auth_none_packet_bind(self):
586         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_PACKET)
587
588     def test_auth_none_integrity_bind(self):
589         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY)
590
591     def test_auth_none_privacy_bind(self):
592         return self._test_auth_none_level_bind(dcerpc.DCERPC_AUTH_LEVEL_PRIVACY)
593
594     def test_auth_none_0_bind(self):
595         return self._test_auth_none_level_bind(0,
596                             reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
597
598     def test_auth_none_7_bind(self):
599         return self._test_auth_none_level_bind(7,
600                             reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
601
602     def test_auth_none_255_bind(self):
603         return self._test_auth_none_level_bind(255,
604                             reason=dcerpc.DCERPC_BIND_NAK_REASON_NOT_SPECIFIED)
605
606     def _test_auth_none_level_request(self, auth_level):
607         ndr32 = base.transfer_syntax_ndr()
608
609         tsf1_list = [ndr32]
610         ctx1 = dcerpc.ctx_list()
611         ctx1.context_id = 1
612         ctx1.num_transfer_syntaxes = len(tsf1_list)
613         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
614         ctx1.transfer_syntaxes = tsf1_list
615         ctx_list = [ctx1]
616
617         auth_type = dcerpc.DCERPC_AUTH_TYPE_NONE
618         auth_context_id = 0
619
620         req = self.generate_bind(call_id=0,
621                                  ctx_list=ctx_list)
622
623         self.send_pdu(req)
624         rep = self.recv_pdu()
625         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
626         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
627         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
628         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
629         self.assertEquals(rep.u.secondary_address_size, 4)
630         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
631         self.assertEquals(len(rep.u._pad1), 2)
632         self.assertEquals(rep.u._pad1, '\0' * 2)
633         self.assertEquals(rep.u.num_results, 1)
634         self.assertEquals(rep.u.ctx_list[0].result,
635                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
636         self.assertEquals(rep.u.ctx_list[0].reason,
637                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
638         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
639         self.assertEquals(len(rep.u.auth_info), 0)
640
641         # And now try a request without auth_info
642         req = self.generate_request(call_id = 2,
643                                     context_id=ctx1.context_id,
644                                     opnum=0,
645                                     stub="")
646         self.send_pdu(req)
647         rep = self.recv_pdu()
648         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
649                         auth_length=0)
650         self.assertNotEquals(rep.u.alloc_hint, 0)
651         self.assertEquals(rep.u.context_id, req.u.context_id)
652         self.assertEquals(rep.u.cancel_count, 0)
653         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
654
655         auth_info = self.generate_auth(auth_type=auth_type,
656                                        auth_level=auth_level,
657                                        auth_context_id=auth_context_id,
658                                        auth_blob="none")
659
660         req = self.generate_request(call_id = 3,
661                                     context_id=ctx1.context_id,
662                                     opnum=0,
663                                     stub="",
664                                     auth_info=auth_info)
665         self.send_pdu(req)
666         rep = self.recv_pdu()
667         # We get a fault back
668         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
669                         auth_length=0)
670         self.assertNotEquals(rep.u.alloc_hint, 0)
671         self.assertEquals(rep.u.context_id, req.u.context_id)
672         self.assertEquals(rep.u.cancel_count, 0)
673         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
674         self.assertEquals(len(rep.u._pad), 4)
675         self.assertEquals(rep.u._pad, '\0' * 4)
676
677         # wait for a disconnect
678         rep = self.recv_pdu()
679         self.assertIsNone(rep)
680         self.assertNotConnected()
681
682     def test_auth_none_none_request(self):
683         return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_NONE)
684
685     def test_auth_none_connect_request(self):
686         return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_CONNECT)
687
688     def test_auth_none_call_request(self):
689         return self._test_auth_none_level_request(dcerpc.DCERPC_AUTH_LEVEL_CALL)
690
691     def _test_neg_xmit_check_values(self,
692                                     req_xmit=None,
693                                     req_recv=None,
694                                     rep_both=None,
695                                     alter_xmit=None,
696                                     alter_recv=None):
697         ndr32 = base.transfer_syntax_ndr()
698
699         tsf1_list = [ndr32]
700         ctx1 = dcerpc.ctx_list()
701         ctx1.context_id = 1
702         ctx1.num_transfer_syntaxes = len(tsf1_list)
703         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
704         ctx1.transfer_syntaxes = tsf1_list
705
706         req = self.generate_bind(call_id=0,
707                                  max_xmit_frag=req_xmit,
708                                  max_recv_frag=req_recv,
709                                  ctx_list=[ctx1])
710         self.send_pdu(req)
711         rep = self.recv_pdu()
712         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
713                         auth_length=0)
714         self.assertEquals(rep.u.max_xmit_frag, rep_both)
715         self.assertEquals(rep.u.max_recv_frag, rep_both)
716         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
717         self.assertEquals(rep.u.secondary_address_size, 4)
718         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
719         self.assertEquals(len(rep.u._pad1), 2)
720         self.assertEquals(rep.u._pad1, '\0' * 2)
721         self.assertEquals(rep.u.num_results, 1)
722         self.assertEquals(rep.u.ctx_list[0].result,
723                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
724         self.assertEquals(rep.u.ctx_list[0].reason,
725                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
726         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
727         self.assertEquals(rep.u.auth_info, '\0' * 0)
728
729         assoc_group_id = rep.u.assoc_group_id
730         if alter_xmit is None:
731             alter_xmit = rep_both - 8
732         if alter_recv is None:
733             alter_recv = rep_both - 8
734
735         # max_{xmit,recv}_frag and assoc_group_id are completely
736         # ignored in alter_context requests
737         req = self.generate_alter(call_id=1,
738                                   max_xmit_frag=alter_xmit,
739                                   max_recv_frag=alter_recv,
740                                   assoc_group_id=0xffffffff-rep.u.assoc_group_id,
741                                   ctx_list=[ctx1])
742         self.send_pdu(req)
743         rep = self.recv_pdu()
744         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id,
745                         auth_length=0)
746         self.assertEquals(rep.u.max_xmit_frag, rep_both)
747         self.assertEquals(rep.u.max_recv_frag, rep_both)
748         self.assertEquals(rep.u.assoc_group_id, rep.u.assoc_group_id)
749         self.assertEquals(rep.u.secondary_address_size, 0)
750         self.assertEquals(len(rep.u._pad1), 2)
751         #self.assertEquals(rep.u._pad1, '\0' * 2)
752         self.assertEquals(rep.u.num_results, 1)
753         self.assertEquals(rep.u.ctx_list[0].result,
754                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
755         self.assertEquals(rep.u.ctx_list[0].reason,
756                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
757         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
758         self.assertEquals(rep.u.auth_info, '\0' * 0)
759
760         chunk_size = rep_both - dcerpc.DCERPC_REQUEST_LENGTH
761         req = self.generate_request(call_id = 2,
762                                     context_id=ctx1.context_id,
763                                     opnum=0,
764                                     alloc_hint=0xffffffff,
765                                     stub="\00" * chunk_size)
766         self.send_pdu(req,ndr_print=True,hexdump=True)
767         rep = self.recv_pdu(ndr_print=True,hexdump=True)
768         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
769                         auth_length=0)
770         self.assertNotEquals(rep.u.alloc_hint, 0)
771         self.assertEquals(rep.u.context_id, req.u.context_id)
772         self.assertEquals(rep.u.cancel_count, 0)
773         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
774
775         chunk_size = 5840 - dcerpc.DCERPC_REQUEST_LENGTH
776         req = self.generate_request(call_id = 2,
777                                     context_id=ctx1.context_id,
778                                     opnum=0,
779                                     alloc_hint=0xffffffff,
780                                     stub="\00" * chunk_size)
781         self.send_pdu(req)
782         rep = self.recv_pdu()
783         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
784                         auth_length=0)
785         self.assertNotEquals(rep.u.alloc_hint, 0)
786         self.assertEquals(rep.u.context_id, req.u.context_id)
787         self.assertEquals(rep.u.cancel_count, 0)
788         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
789
790         chunk_size += 1
791         req = self.generate_request(call_id = 3,
792                                     context_id=ctx1.context_id,
793                                     opnum=0,
794                                     alloc_hint=0xffffffff,
795                                     stub="\00" * chunk_size)
796         self.send_pdu(req)
797         rep = self.recv_pdu()
798         # We get a fault
799         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
800                         auth_length=0)
801         self.assertNotEquals(rep.u.alloc_hint, 0)
802         self.assertEquals(rep.u.context_id, 0)
803         self.assertEquals(rep.u.cancel_count, 0)
804         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
805         self.assertEquals(len(rep.u._pad), 4)
806         self.assertEquals(rep.u._pad, '\0' * 4)
807
808         # wait for a disconnect
809         rep = self.recv_pdu()
810         self.assertIsNone(rep)
811         self.assertNotConnected()
812
813     def test_neg_xmit_ffff_ffff(self):
814         return self._test_neg_xmit_check_values(req_xmit=0xffff,
815                                                 req_recv=0xffff,
816                                                 rep_both=5840)
817
818     def test_neg_xmit_0_ffff(self):
819         return self._test_neg_xmit_check_values(req_xmit=0,
820                                                 req_recv=0xffff,
821                                                 rep_both=2048,
822                                                 alter_xmit=0xffff,
823                                                 alter_recv=0xffff)
824
825     def test_neg_xmit_ffff_0(self):
826         return self._test_neg_xmit_check_values(req_xmit=0xffff,
827                                                 req_recv=0,
828                                                 rep_both=2048)
829
830     def test_neg_xmit_0_0(self):
831         return self._test_neg_xmit_check_values(req_xmit=0,
832                                                 req_recv=0,
833                                                 rep_both=2048,
834                                                 alter_xmit=0xffff,
835                                                 alter_recv=0xffff)
836
837     def test_neg_xmit_3199_0(self):
838         return self._test_neg_xmit_check_values(req_xmit=3199,
839                                                 req_recv=0,
840                                                 rep_both=2048)
841     def test_neg_xmit_0_3199(self):
842         return self._test_neg_xmit_check_values(req_xmit=0,
843                                                 req_recv=3199,
844                                                 rep_both=2048)
845
846     def test_neg_xmit_3199_ffff(self):
847         return self._test_neg_xmit_check_values(req_xmit=3199,
848                                                 req_recv=0xffff,
849                                                 rep_both=3192)
850     def test_neg_xmit_ffff_3199(self):
851         return self._test_neg_xmit_check_values(req_xmit=0xffff,
852                                                 req_recv=3199,
853                                                 rep_both=3192)
854
855     def test_alloc_hint(self):
856         ndr32 = base.transfer_syntax_ndr()
857
858         tsf1_list = [ndr32]
859         ctx = dcerpc.ctx_list()
860         ctx.context_id = 0
861         ctx.num_transfer_syntaxes = len(tsf1_list)
862         ctx.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
863         ctx.transfer_syntaxes = tsf1_list
864
865         req = self.generate_bind(call_id=0,
866                                  ctx_list=[ctx])
867         self.send_pdu(req)
868         rep = self.recv_pdu()
869         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
870                         auth_length=0)
871         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
872         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
873         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
874         self.assertEquals(rep.u.secondary_address_size, 4)
875         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
876         self.assertEquals(len(rep.u._pad1), 2)
877         self.assertEquals(rep.u._pad1, '\0' * 2)
878         self.assertEquals(rep.u.num_results, 1)
879         self.assertEquals(rep.u.ctx_list[0].result,
880                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
881         self.assertEquals(rep.u.ctx_list[0].reason,
882                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
883         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
884         self.assertEquals(rep.u.auth_info, '\0' * 0)
885
886         # And now try a request without auth_info
887         req = self.generate_request(call_id = 2,
888                                     context_id=ctx.context_id,
889                                     opnum=0,
890                                     alloc_hint=0xffffffff,
891                                     stub="")
892         self.send_pdu(req)
893         rep = self.recv_pdu()
894         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
895                         auth_length=0)
896         self.assertNotEquals(rep.u.alloc_hint, 0)
897         self.assertEquals(rep.u.context_id, req.u.context_id)
898         self.assertEquals(rep.u.cancel_count, 0)
899         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
900
901         req = self.generate_request(call_id = 3,
902                                     context_id=ctx.context_id,
903                                     opnum=1,
904                                     alloc_hint=0xffffffff,
905                                     stub="\04\00\00\00\00\00\00\00")
906         self.send_pdu(req)
907         rep = self.recv_pdu()
908         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
909                         auth_length=0)
910         self.assertNotEquals(rep.u.alloc_hint, 0)
911         self.assertEquals(rep.u.context_id, req.u.context_id)
912         self.assertEquals(rep.u.cancel_count, 0)
913         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
914
915         req = self.generate_request(call_id = 4,
916                                     context_id=ctx.context_id,
917                                     opnum=1,
918                                     alloc_hint=1,
919                                     stub="\04\00\00\00\00\00\00\00")
920         self.send_pdu(req)
921         rep = self.recv_pdu()
922         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
923                         auth_length=0)
924         self.assertNotEquals(rep.u.alloc_hint, 0)
925         self.assertEquals(rep.u.context_id, req.u.context_id)
926         self.assertEquals(rep.u.cancel_count, 0)
927         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
928
929     def _get_netlogon_ctx(self):
930         abstract = samba.dcerpc.netlogon.abstract_syntax()
931         self.epmap_reconnect(abstract)
932
933         ndr32 = base.transfer_syntax_ndr()
934
935         tsf1_list = [ndr32]
936         ctx = dcerpc.ctx_list()
937         ctx.context_id = 0
938         ctx.num_transfer_syntaxes = len(tsf1_list)
939         ctx.abstract_syntax = abstract
940         ctx.transfer_syntaxes = tsf1_list
941
942         req = self.generate_bind(call_id=0,
943                                  ctx_list=[ctx])
944         self.send_pdu(req)
945         rep = self.recv_pdu()
946         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id,
947                         auth_length=0)
948         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
949         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
950         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
951         port_str = "%d" % self.tcp_port
952         port_len = len(port_str) + 1
953         mod_len = (2 + port_len) % 4
954         if mod_len != 0:
955             port_pad = 4 - mod_len
956         else:
957             port_pad = 0
958         self.assertEquals(rep.u.secondary_address_size, port_len)
959         self.assertEquals(rep.u.secondary_address, port_str)
960         self.assertEquals(len(rep.u._pad1), port_pad)
961         self.assertEquals(rep.u._pad1, '\0' * port_pad)
962         self.assertEquals(rep.u.num_results, 1)
963         self.assertEquals(rep.u.ctx_list[0].result,
964                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
965         self.assertEquals(rep.u.ctx_list[0].reason,
966                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
967         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
968         self.assertEquals(rep.u.auth_info, '\0' * 0)
969
970         server = '\\\\' + self.host
971         server_utf16 = unicode(server, 'utf-8').encode('utf-16-le')
972         computer = 'UNKNOWNCOMPUTER'
973         computer_utf16 = unicode(computer, 'utf-8').encode('utf-16-le')
974
975         real_stub  = struct.pack('<IIII', 0x00200000,
976                                  len(server)+1, 0, len(server)+1)
977         real_stub += server_utf16 + '\x00\x00'
978         mod_len = len(real_stub) % 4
979         if mod_len != 0:
980             real_stub += '\x00' * (4 - mod_len)
981         real_stub += struct.pack('<III',
982                                  len(computer)+1, 0, len(computer)+1)
983         real_stub += computer_utf16 + '\x00\x00'
984         real_stub += '\x11\x22\x33\x44\x55\x66\x77\x88'
985
986         return (ctx, rep, real_stub)
987
988     def _test_fragmented_requests(self, remaining=None, alloc_hint=None,
989                                   fault_first=None, fault_last=None):
990         (ctx, rep, real_stub) = self._get_netlogon_ctx()
991
992         chunk = rep.u.max_recv_frag - dcerpc.DCERPC_REQUEST_LENGTH
993
994         total = 0
995         first = True
996         while remaining > 0:
997             thistime = min(remaining, chunk)
998             remaining -= thistime
999             total += thistime
1000
1001             pfc_flags = 0
1002             if first:
1003                 pfc_flags |= dcerpc.DCERPC_PFC_FLAG_FIRST
1004                 first = False
1005                 stub = real_stub + '\x00' * (thistime - len(real_stub))
1006             else:
1007                 stub = "\x00" * thistime
1008
1009             if remaining == 0:
1010                 pfc_flags |= dcerpc.DCERPC_PFC_FLAG_LAST
1011
1012             # And now try a request without auth_info
1013             # netr_ServerReqChallenge()
1014             req = self.generate_request(call_id = 2,
1015                                         pfc_flags=pfc_flags,
1016                                         context_id=ctx.context_id,
1017                                         opnum=4,
1018                                         alloc_hint=alloc_hint,
1019                                         stub=stub)
1020             if alloc_hint >= thistime:
1021                 alloc_hint -= thistime
1022             else:
1023                 alloc_hint = 0
1024             self.send_pdu(req,hexdump=False)
1025             if fault_first is not None:
1026                 rep = self.recv_pdu()
1027                 # We get a fault back
1028                 self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1029                                 auth_length=0)
1030                 self.assertNotEquals(rep.u.alloc_hint, 0)
1031                 self.assertEquals(rep.u.context_id, req.u.context_id)
1032                 self.assertEquals(rep.u.cancel_count, 0)
1033                 self.assertEquals(rep.u.status, fault_first)
1034                 self.assertEquals(len(rep.u._pad), 4)
1035                 self.assertEquals(rep.u._pad, '\0' * 4)
1036
1037                 # wait for a disconnect
1038                 rep = self.recv_pdu()
1039                 self.assertIsNone(rep)
1040                 self.assertNotConnected()
1041                 return
1042             if remaining == 0:
1043                 break
1044             if total >= 0x400000 and fault_last is not None:
1045                 rep = self.recv_pdu()
1046                 # We get a fault back
1047                 self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1048                                 auth_length=0)
1049                 self.assertNotEquals(rep.u.alloc_hint, 0)
1050                 self.assertEquals(rep.u.context_id, req.u.context_id)
1051                 self.assertEquals(rep.u.cancel_count, 0)
1052                 self.assertEquals(rep.u.status, fault_last)
1053                 self.assertEquals(len(rep.u._pad), 4)
1054                 self.assertEquals(rep.u._pad, '\0' * 4)
1055
1056                 # wait for a disconnect
1057                 rep = self.recv_pdu()
1058                 self.assertIsNone(rep)
1059                 self.assertNotConnected()
1060                 return
1061             rep = self.recv_pdu(timeout=0.01)
1062             self.assertIsNone(rep)
1063             self.assertIsConnected()
1064
1065         if total >= 0x400000 and fault_last is not None:
1066             rep = self.recv_pdu()
1067             # We get a fault back
1068             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1069                             auth_length=0)
1070             self.assertNotEquals(rep.u.alloc_hint, 0)
1071             self.assertEquals(rep.u.context_id, req.u.context_id)
1072             self.assertEquals(rep.u.cancel_count, 0)
1073             self.assertEquals(rep.u.status, fault_last)
1074             self.assertEquals(len(rep.u._pad), 4)
1075             self.assertEquals(rep.u._pad, '\0' * 4)
1076
1077             # wait for a disconnect
1078             rep = self.recv_pdu()
1079             self.assertIsNone(rep)
1080             self.assertNotConnected()
1081             return
1082         rep = self.recv_pdu()
1083         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1084                         auth_length=0)
1085         self.assertNotEquals(rep.u.alloc_hint, 0)
1086         self.assertEquals(rep.u.context_id, req.u.context_id)
1087         self.assertEquals(rep.u.cancel_count, 0)
1088         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1089
1090         self.assertEquals(len(rep.u.stub_and_verifier), 12)
1091         status = struct.unpack_from("<I", rep.u.stub_and_verifier, len(rep.u.stub_and_verifier) - 4)
1092         self.assertEquals(status[0], 0)
1093
1094     def test_fragmented_requests01(self):
1095         return self._test_fragmented_requests(remaining=0x400000,
1096                                               alloc_hint=0x400000)
1097
1098     def test_fragmented_requests02(self):
1099         return self._test_fragmented_requests(remaining=0x400000,
1100                                               alloc_hint=0x100000)
1101
1102     def test_fragmented_requests03(self):
1103         return self._test_fragmented_requests(remaining=0x400000,
1104                                               alloc_hint=0)
1105
1106     def test_fragmented_requests04(self):
1107         return self._test_fragmented_requests(remaining=0x400000,
1108                                               alloc_hint=0x400001,
1109                                               fault_first=dcerpc.DCERPC_FAULT_ACCESS_DENIED)
1110
1111     def test_fragmented_requests05(self):
1112         return self._test_fragmented_requests(remaining=0x500001,
1113                                               alloc_hint=0,
1114                                               fault_last=dcerpc.DCERPC_FAULT_ACCESS_DENIED)
1115
1116     def _test_same_requests(self, pfc_flags, fault_1st=False, fault_2nd=False):
1117         (ctx, rep, real_stub) = self._get_netlogon_ctx()
1118
1119         # netr_ServerReqChallenge with given flags
1120         req = self.generate_request(call_id = 2,
1121                                     pfc_flags=pfc_flags,
1122                                     context_id=ctx.context_id,
1123                                     opnum=4,
1124                                     stub=real_stub)
1125         self.send_pdu(req)
1126         if fault_1st:
1127             rep = self.recv_pdu()
1128             # We get a fault back
1129             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1130                             auth_length=0)
1131             self.assertNotEquals(rep.u.alloc_hint, 0)
1132             self.assertEquals(rep.u.context_id, req.u.context_id)
1133             self.assertEquals(rep.u.cancel_count, 0)
1134             self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
1135             self.assertEquals(len(rep.u._pad), 4)
1136             self.assertEquals(rep.u._pad, '\0' * 4)
1137
1138             # wait for a disconnect
1139             rep = self.recv_pdu()
1140             self.assertIsNone(rep)
1141             self.assertNotConnected()
1142             return
1143         rep = self.recv_pdu(timeout=0.1)
1144         self.assertIsNone(rep)
1145         self.assertIsConnected()
1146
1147         # netr_ServerReqChallenge without DCERPC_PFC_FLAG_LAST
1148         # with the same call_id
1149         req = self.generate_request(call_id = 2,
1150                                     pfc_flags=pfc_flags,
1151                                     context_id=ctx.context_id,
1152                                     opnum=4,
1153                                     stub=real_stub)
1154         self.send_pdu(req)
1155         if fault_2nd:
1156             rep = self.recv_pdu()
1157             # We get a fault back
1158             self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1159                             auth_length=0)
1160             self.assertNotEquals(rep.u.alloc_hint, 0)
1161             self.assertEquals(rep.u.context_id, req.u.context_id)
1162             self.assertEquals(rep.u.cancel_count, 0)
1163             self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
1164             self.assertEquals(len(rep.u._pad), 4)
1165             self.assertEquals(rep.u._pad, '\0' * 4)
1166
1167             # wait for a disconnect
1168             rep = self.recv_pdu()
1169             self.assertIsNone(rep)
1170             self.assertNotConnected()
1171             return
1172
1173         rep = self.recv_pdu(timeout=0.1)
1174         self.assertIsNone(rep)
1175         self.assertIsConnected()
1176
1177     def test_first_only_requests(self):
1178         return self._test_same_requests(pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
1179                                         fault_2nd=True)
1180
1181     def test_none_only_requests(self):
1182         return self._test_same_requests(pfc_flags=0, fault_1st=True)
1183
1184     def test_last_only_requests(self):
1185         return self._test_same_requests(pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
1186                                         fault_1st=True)
1187
1188     def test_first_maybe_requests(self):
1189         return self._test_same_requests(pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1190                                         dcerpc.DCERPC_PFC_FLAG_MAYBE,
1191                                         fault_2nd=True)
1192
1193     def test_first_didnot_requests(self):
1194         return self._test_same_requests(pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1195                                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
1196                                         fault_2nd=True)
1197
1198     def test_first_cmpx_requests(self):
1199         return self._test_same_requests(pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1200                                         dcerpc.DCERPC_PFC_FLAG_CONC_MPX,
1201                                         fault_2nd=True)
1202
1203     def test_first_08_requests(self):
1204         return self._test_same_requests(pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1205                                         0x08,
1206                                         fault_2nd=True)
1207
1208     def test_first_cancel_requests(self):
1209         (ctx, rep, real_stub) = self._get_netlogon_ctx()
1210
1211         # netr_ServerReqChallenge with given flags
1212         req = self.generate_request(call_id = 2,
1213                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1214                                               dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
1215                                     context_id=ctx.context_id,
1216                                     opnum=4,
1217                                     stub=real_stub)
1218         self.send_pdu(req)
1219         rep = self.recv_pdu()
1220         # We get a fault back
1221         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1222                         pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1223                         dcerpc.DCERPC_PFC_FLAG_LAST |
1224                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
1225                         auth_length=0)
1226         self.assertNotEquals(rep.u.alloc_hint, 0)
1227         self.assertEquals(rep.u.context_id, req.u.context_id)
1228         self.assertEquals(rep.u.cancel_count, 0)
1229         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_NO_CALL_ACTIVE)
1230         self.assertEquals(len(rep.u._pad), 4)
1231         self.assertEquals(rep.u._pad, '\0' * 4)
1232
1233         # wait for a disconnect
1234         rep = self.recv_pdu()
1235         self.assertIsNone(rep)
1236         self.assertNotConnected()
1237
1238     def test_2nd_cancel_requests(self):
1239         (ctx, rep, real_stub) = self._get_netlogon_ctx()
1240
1241         # netr_ServerReqChallenge with given flags
1242         req = self.generate_request(call_id = 2,
1243                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
1244                                     context_id=ctx.context_id,
1245                                     opnum=4,
1246                                     stub=real_stub)
1247         self.send_pdu(req)
1248         rep = self.recv_pdu(timeout=0.1)
1249         self.assertIsNone(rep)
1250         self.assertIsConnected()
1251
1252         # netr_ServerReqChallenge with given flags
1253         req = self.generate_request(call_id = 2,
1254                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
1255                                     context_id=ctx.context_id,
1256                                     opnum=4,
1257                                     stub=real_stub)
1258         self.send_pdu(req)
1259         rep = self.recv_pdu(timeout=0.1)
1260         self.assertIsNone(rep)
1261         self.assertIsConnected()
1262
1263         # netr_ServerReqChallenge with given flags
1264         req = self.generate_request(call_id = 2,
1265                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST,
1266                                     context_id=ctx.context_id,
1267                                     opnum=4,
1268                                     stub=real_stub)
1269         self.send_pdu(req)
1270         rep = self.recv_pdu()
1271         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1272                         auth_length=0)
1273         self.assertNotEquals(rep.u.alloc_hint, 0)
1274         self.assertEquals(rep.u.context_id, req.u.context_id)
1275         self.assertEquals(rep.u.cancel_count, 0)
1276         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1277
1278         self.assertEquals(len(rep.u.stub_and_verifier), 12)
1279         status = struct.unpack_from("<I", rep.u.stub_and_verifier, len(rep.u.stub_and_verifier) - 4)
1280         self.assertEquals(status[0], 0)
1281
1282     def test_last_cancel_requests(self):
1283         (ctx, rep, real_stub) = self._get_netlogon_ctx()
1284
1285         # netr_ServerReqChallenge with given flags
1286         req = self.generate_request(call_id = 2,
1287                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
1288                                     context_id=ctx.context_id,
1289                                     opnum=4,
1290                                     stub=real_stub[:4])
1291         self.send_pdu(req)
1292         rep = self.recv_pdu(timeout=0.1)
1293         self.assertIsNone(rep)
1294         self.assertIsConnected()
1295
1296         # netr_ServerReqChallenge with given flags
1297         req = self.generate_request(call_id = 2,
1298                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_LAST |
1299                                     dcerpc.DCERPC_PFC_FLAG_PENDING_CANCEL,
1300                                     context_id=ctx.context_id,
1301                                     opnum=4,
1302                                     stub=real_stub[4:])
1303         self.send_pdu(req)
1304         rep = self.recv_pdu()
1305         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1306                         auth_length=0)
1307         self.assertNotEquals(rep.u.alloc_hint, 0)
1308         self.assertEquals(rep.u.context_id, req.u.context_id)
1309         self.assertEquals(rep.u.cancel_count, 0)
1310         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1311
1312         self.assertEquals(len(rep.u.stub_and_verifier), 12)
1313         status = struct.unpack_from("<I", rep.u.stub_and_verifier, len(rep.u.stub_and_verifier) - 4)
1314         self.assertEquals(status[0], 0)
1315
1316     def test_mix_requests(self):
1317         (ctx, rep, real_stub) = self._get_netlogon_ctx()
1318
1319         # netr_ServerReqChallenge with given flags
1320         req = self.generate_request(call_id = 50,
1321                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
1322                                     context_id=ctx.context_id,
1323                                     opnum=4,
1324                                     stub=real_stub)
1325         self.send_pdu(req)
1326         rep = self.recv_pdu(timeout=0.1)
1327         self.assertIsNone(rep)
1328         self.assertIsConnected()
1329
1330         # netr_ServerReqChallenge with given flags
1331         req = self.generate_request(call_id = 51,
1332                                     pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST,
1333                                     context_id=ctx.context_id,
1334                                     opnum=4,
1335                                     stub=real_stub)
1336         self.send_pdu(req)
1337         rep = self.recv_pdu()
1338         # We get a fault back
1339         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, 50,
1340                         pfc_flags=dcerpc.DCERPC_PFC_FLAG_FIRST |
1341                         dcerpc.DCERPC_PFC_FLAG_LAST,
1342                         auth_length=0)
1343         self.assertNotEquals(rep.u.alloc_hint, 0)
1344         self.assertEquals(rep.u.context_id, req.u.context_id)
1345         self.assertEquals(rep.u.cancel_count, 0)
1346         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
1347         self.assertEquals(len(rep.u._pad), 4)
1348         self.assertEquals(rep.u._pad, '\0' * 4)
1349
1350     def test_spnego_connect_request(self):
1351         ndr32 = base.transfer_syntax_ndr()
1352
1353         tsf1_list = [ndr32]
1354         ctx1 = dcerpc.ctx_list()
1355         ctx1.context_id = 1
1356         ctx1.num_transfer_syntaxes = len(tsf1_list)
1357         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
1358         ctx1.transfer_syntaxes = tsf1_list
1359         ctx_list = [ctx1]
1360
1361         c = Credentials()
1362         c.set_anonymous()
1363         g = gensec.Security.start_client(self.settings)
1364         g.set_credentials(c)
1365         g.want_feature(gensec.FEATURE_DCE_STYLE)
1366         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1367         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
1368         auth_context_id = 2
1369         g.start_mech_by_authtype(auth_type, auth_level)
1370         from_server = ""
1371         (finished, to_server) = g.update(from_server)
1372         self.assertFalse(finished)
1373
1374         auth_info = self.generate_auth(auth_type=auth_type,
1375                                        auth_level=auth_level,
1376                                        auth_context_id=auth_context_id,
1377                                        auth_blob=to_server)
1378
1379         req = self.generate_bind(call_id=0,
1380                                  ctx_list=ctx_list,
1381                                  auth_info=auth_info)
1382
1383         self.send_pdu(req)
1384         rep = self.recv_pdu()
1385         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
1386         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1387         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1388         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1389         self.assertEquals(rep.u.secondary_address_size, 4)
1390         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
1391         self.assertEquals(len(rep.u._pad1), 2)
1392         self.assertEquals(rep.u._pad1, '\0' * 2)
1393         self.assertEquals(rep.u.num_results, 1)
1394         self.assertEquals(rep.u.ctx_list[0].result,
1395                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1396         self.assertEquals(rep.u.ctx_list[0].reason,
1397                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1398         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1399         self.assertNotEquals(len(rep.u.auth_info), 0)
1400         a = self.parse_auth(rep.u.auth_info)
1401
1402         from_server = a.credentials
1403         (finished, to_server) = g.update(from_server)
1404         self.assertFalse(finished)
1405
1406         auth_info = self.generate_auth(auth_type=auth_type,
1407                                        auth_level=auth_level,
1408                                        auth_context_id=auth_context_id,
1409                                        auth_blob=to_server)
1410
1411         req = self.generate_alter(call_id=0,
1412                                   ctx_list=ctx_list,
1413                                   assoc_group_id=rep.u.assoc_group_id,
1414                                   auth_info=auth_info)
1415
1416         self.send_pdu(req)
1417         rep = self.recv_pdu()
1418         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
1419         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1420         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1421         self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1422         self.assertEquals(rep.u.secondary_address_size, 0)
1423         self.assertEquals(len(rep.u._pad1), 2)
1424         # Windows sends garbage
1425         #self.assertEquals(rep.u._pad1, '\0' * 2)
1426         self.assertEquals(rep.u.num_results, 1)
1427         self.assertEquals(rep.u.ctx_list[0].result,
1428                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1429         self.assertEquals(rep.u.ctx_list[0].reason,
1430                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1431         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1432         self.assertNotEquals(len(rep.u.auth_info), 0)
1433         a = self.parse_auth(rep.u.auth_info)
1434
1435         from_server = a.credentials
1436         (finished, to_server) = g.update(from_server)
1437         self.assertTrue(finished)
1438
1439         # And now try a request without auth_info
1440         req = self.generate_request(call_id = 2,
1441                                     context_id=ctx1.context_id,
1442                                     opnum=0,
1443                                     stub="")
1444         self.send_pdu(req)
1445         rep = self.recv_pdu()
1446         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1447                         auth_length=0)
1448         self.assertNotEquals(rep.u.alloc_hint, 0)
1449         self.assertEquals(rep.u.context_id, req.u.context_id)
1450         self.assertEquals(rep.u.cancel_count, 0)
1451         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1452
1453         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
1454         auth_info = self.generate_auth(auth_type=auth_type,
1455                                        auth_level=auth_level,
1456                                        auth_context_id=auth_context_id,
1457                                        auth_blob="\x01"+"\x00"*15)
1458         req = self.generate_request(call_id = 3,
1459                                     context_id=ctx1.context_id,
1460                                     opnum=0,
1461                                     stub="",
1462                                     auth_info=auth_info)
1463         self.send_pdu(req)
1464         rep = self.recv_pdu()
1465         # We don't get an auth_info back
1466         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1467                         auth_length=0)
1468         self.assertNotEquals(rep.u.alloc_hint, 0)
1469         self.assertEquals(rep.u.context_id, req.u.context_id)
1470         self.assertEquals(rep.u.cancel_count, 0)
1471         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1472
1473         # Now a request with auth_info DCERPC_AUTH_LEVEL_INTEGRITY
1474         auth_info = self.generate_auth(auth_type=auth_type,
1475                                        auth_level=dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY,
1476                                        auth_context_id=auth_context_id,
1477                                        auth_blob="\x01"+"\x00"*15)
1478         req = self.generate_request(call_id = 4,
1479                                     context_id=ctx1.context_id,
1480                                     opnum=0,
1481                                     stub="",
1482                                     auth_info=auth_info)
1483         self.send_pdu(req)
1484         rep = self.recv_pdu()
1485         # We get a fault back
1486         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1487                         auth_length=0)
1488         self.assertNotEquals(rep.u.alloc_hint, 0)
1489         self.assertEquals(rep.u.context_id, req.u.context_id)
1490         self.assertEquals(rep.u.cancel_count, 0)
1491         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
1492         self.assertEquals(len(rep.u._pad), 4)
1493         self.assertEquals(rep.u._pad, '\0' * 4)
1494
1495         # wait for a disconnect
1496         rep = self.recv_pdu()
1497         self.assertIsNone(rep)
1498         self.assertNotConnected()
1499
1500     def test_spnego_integrity_request(self):
1501         ndr32 = base.transfer_syntax_ndr()
1502
1503         tsf1_list = [ndr32]
1504         ctx1 = dcerpc.ctx_list()
1505         ctx1.context_id = 1
1506         ctx1.num_transfer_syntaxes = len(tsf1_list)
1507         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
1508         ctx1.transfer_syntaxes = tsf1_list
1509         ctx_list = [ctx1]
1510
1511         c = Credentials()
1512         c.set_anonymous()
1513         g = gensec.Security.start_client(self.settings)
1514         g.set_credentials(c)
1515         g.want_feature(gensec.FEATURE_DCE_STYLE)
1516         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1517         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
1518         auth_context_id = 2
1519         g.start_mech_by_authtype(auth_type, auth_level)
1520         from_server = ""
1521         (finished, to_server) = g.update(from_server)
1522         self.assertFalse(finished)
1523
1524         auth_info = self.generate_auth(auth_type=auth_type,
1525                                        auth_level=auth_level,
1526                                        auth_context_id=auth_context_id,
1527                                        auth_blob=to_server)
1528
1529         req = self.generate_bind(call_id=0,
1530                                  ctx_list=ctx_list,
1531                                  auth_info=auth_info)
1532
1533         self.send_pdu(req)
1534         rep = self.recv_pdu()
1535         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
1536         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1537         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1538         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1539         self.assertEquals(rep.u.secondary_address_size, 4)
1540         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
1541         self.assertEquals(len(rep.u._pad1), 2)
1542         self.assertEquals(rep.u._pad1, '\0' * 2)
1543         self.assertEquals(rep.u.num_results, 1)
1544         self.assertEquals(rep.u.ctx_list[0].result,
1545                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1546         self.assertEquals(rep.u.ctx_list[0].reason,
1547                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1548         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1549         self.assertNotEquals(len(rep.u.auth_info), 0)
1550         a = self.parse_auth(rep.u.auth_info)
1551
1552         from_server = a.credentials
1553         (finished, to_server) = g.update(from_server)
1554         self.assertFalse(finished)
1555
1556         auth_info = self.generate_auth(auth_type=auth_type,
1557                                        auth_level=auth_level,
1558                                        auth_context_id=auth_context_id,
1559                                        auth_blob=to_server)
1560
1561         req = self.generate_alter(call_id=0,
1562                                   ctx_list=ctx_list,
1563                                   assoc_group_id=rep.u.assoc_group_id,
1564                                   auth_info=auth_info)
1565
1566         self.send_pdu(req)
1567         rep = self.recv_pdu()
1568         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
1569         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1570         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1571         self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1572         self.assertEquals(rep.u.secondary_address_size, 0)
1573         self.assertEquals(len(rep.u._pad1), 2)
1574         # Windows sends garbage
1575         #self.assertEquals(rep.u._pad1, '\0' * 2)
1576         self.assertEquals(rep.u.num_results, 1)
1577         self.assertEquals(rep.u.ctx_list[0].result,
1578                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1579         self.assertEquals(rep.u.ctx_list[0].reason,
1580                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1581         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1582         self.assertNotEquals(len(rep.u.auth_info), 0)
1583         a = self.parse_auth(rep.u.auth_info)
1584
1585         from_server = a.credentials
1586         (finished, to_server) = g.update(from_server)
1587         self.assertTrue(finished)
1588
1589         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
1590         auth_info = self.generate_auth(auth_type=auth_type,
1591                                        auth_level=dcerpc.DCERPC_AUTH_LEVEL_CONNECT,
1592                                        auth_context_id=auth_context_id,
1593                                        auth_blob="\x01"+"\x00"*15)
1594         req = self.generate_request(call_id = 3,
1595                                     context_id=ctx1.context_id,
1596                                     opnum=0,
1597                                     stub="",
1598                                     auth_info=auth_info)
1599         self.send_pdu(req)
1600         rep = self.recv_pdu()
1601         # We get a fault back
1602         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1603                         auth_length=0)
1604         self.assertNotEquals(rep.u.alloc_hint, 0)
1605         self.assertEquals(rep.u.context_id, req.u.context_id)
1606         self.assertEquals(rep.u.cancel_count, 0)
1607         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
1608         self.assertEquals(len(rep.u._pad), 4)
1609         self.assertEquals(rep.u._pad, '\0' * 4)
1610
1611         # wait for a disconnect
1612         rep = self.recv_pdu()
1613         self.assertIsNone(rep)
1614         self.assertNotConnected()
1615
1616     def test_spnego_unfinished_request(self):
1617         ndr32 = base.transfer_syntax_ndr()
1618
1619         tsf1_list = [ndr32]
1620         ctx1 = dcerpc.ctx_list()
1621         ctx1.context_id = 1
1622         ctx1.num_transfer_syntaxes = len(tsf1_list)
1623         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
1624         ctx1.transfer_syntaxes = tsf1_list
1625         ctx_list = [ctx1]
1626
1627         c = Credentials()
1628         c.set_anonymous()
1629         g = gensec.Security.start_client(self.settings)
1630         g.set_credentials(c)
1631         g.want_feature(gensec.FEATURE_DCE_STYLE)
1632         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1633         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
1634         auth_context_id = 2
1635         g.start_mech_by_authtype(auth_type, auth_level)
1636         from_server = ""
1637         (finished, to_server) = g.update(from_server)
1638         self.assertFalse(finished)
1639
1640         auth_info = self.generate_auth(auth_type=auth_type,
1641                                        auth_level=auth_level,
1642                                        auth_context_id=auth_context_id,
1643                                        auth_blob=to_server)
1644
1645         req = self.generate_bind(call_id=0,
1646                                  ctx_list=ctx_list,
1647                                  auth_info=auth_info)
1648
1649         self.send_pdu(req)
1650         rep = self.recv_pdu()
1651         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
1652         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1653         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1654         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1655         assoc_group_id = rep.u.assoc_group_id
1656         self.assertEquals(rep.u.secondary_address_size, 4)
1657         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
1658         self.assertEquals(len(rep.u._pad1), 2)
1659         self.assertEquals(rep.u._pad1, '\0' * 2)
1660         self.assertEquals(rep.u.num_results, 1)
1661         self.assertEquals(rep.u.ctx_list[0].result,
1662                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1663         self.assertEquals(rep.u.ctx_list[0].reason,
1664                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1665         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1666         self.assertNotEquals(len(rep.u.auth_info), 0)
1667         a = self.parse_auth(rep.u.auth_info)
1668
1669         from_server = a.credentials
1670         (finished, to_server) = g.update(from_server)
1671         self.assertFalse(finished)
1672
1673         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
1674         auth_info = self.generate_auth(auth_type=auth_type,
1675                                        auth_level=auth_level,
1676                                        auth_context_id=auth_context_id,
1677                                        auth_blob="\x01"+"\x00"*15)
1678         req = self.generate_request(call_id = 1,
1679                                     context_id=ctx1.context_id,
1680                                     opnum=0,
1681                                     stub="",
1682                                     auth_info=auth_info)
1683         self.send_pdu(req)
1684         rep = self.recv_pdu()
1685         # We get a fault
1686         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1687                         pfc_flags=req.pfc_flags |
1688                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
1689                         auth_length=0)
1690         self.assertNotEquals(rep.u.alloc_hint, 0)
1691         self.assertEquals(rep.u.context_id, 0)
1692         self.assertEquals(rep.u.cancel_count, 0)
1693         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
1694         self.assertEquals(len(rep.u._pad), 4)
1695         self.assertEquals(rep.u._pad, '\0' * 4)
1696
1697         # wait for a disconnect
1698         rep = self.recv_pdu()
1699         self.assertIsNone(rep)
1700         self.assertNotConnected()
1701
1702     def test_spnego_auth3(self):
1703         ndr32 = base.transfer_syntax_ndr()
1704
1705         tsf1_list = [ndr32]
1706         ctx1 = dcerpc.ctx_list()
1707         ctx1.context_id = 1
1708         ctx1.num_transfer_syntaxes = len(tsf1_list)
1709         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
1710         ctx1.transfer_syntaxes = tsf1_list
1711         ctx_list = [ctx1]
1712
1713         c = Credentials()
1714         c.set_anonymous()
1715         g = gensec.Security.start_client(self.settings)
1716         g.set_credentials(c)
1717         g.want_feature(gensec.FEATURE_DCE_STYLE)
1718         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1719         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
1720         auth_context_id = 2
1721         g.start_mech_by_authtype(auth_type, auth_level)
1722         from_server = ""
1723         (finished, to_server) = g.update(from_server)
1724         self.assertFalse(finished)
1725
1726         auth_info = self.generate_auth(auth_type=auth_type,
1727                                        auth_level=auth_level,
1728                                        auth_context_id=auth_context_id,
1729                                        auth_blob=to_server)
1730         req = self.generate_bind(call_id=0,
1731                                  ctx_list=ctx_list,
1732                                  auth_info=auth_info)
1733         self.send_pdu(req)
1734         rep = self.recv_pdu()
1735         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
1736         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1737         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1738         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1739         self.assertEquals(rep.u.secondary_address_size, 4)
1740         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
1741         self.assertEquals(len(rep.u._pad1), 2)
1742         #self.assertEquals(rep.u._pad1, '\0' * 2)
1743         self.assertEquals(rep.u.num_results, 1)
1744         self.assertEquals(rep.u.ctx_list[0].result,
1745                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1746         self.assertEquals(rep.u.ctx_list[0].reason,
1747                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1748         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1749         self.assertNotEquals(len(rep.u.auth_info), 0)
1750         a = self.parse_auth(rep.u.auth_info)
1751
1752         from_server = a.credentials
1753         (finished, to_server) = g.update(from_server)
1754         self.assertFalse(finished)
1755
1756         auth_info = self.generate_auth(auth_type=auth_type,
1757                                        auth_level=auth_level,
1758                                        auth_context_id=auth_context_id,
1759                                        auth_blob=to_server)
1760         req = self.generate_auth3(call_id=0,
1761                                   auth_info=auth_info)
1762         self.send_pdu(req)
1763         rep = self.recv_pdu()
1764         self.assertIsNone(rep)
1765         self.assertIsConnected()
1766
1767         # And now try a request without auth_info
1768         req = self.generate_request(call_id = 2,
1769                                     context_id=ctx1.context_id,
1770                                     opnum=0,
1771                                     stub="")
1772         self.send_pdu(req)
1773         rep = self.recv_pdu()
1774         # We get a fault back
1775         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1776                         auth_length=0)
1777         self.assertNotEquals(rep.u.alloc_hint, 0)
1778         self.assertEquals(rep.u.context_id, req.u.context_id)
1779         self.assertEquals(rep.u.cancel_count, 0)
1780         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
1781         self.assertEquals(len(rep.u._pad), 4)
1782         self.assertEquals(rep.u._pad, '\0' * 4)
1783
1784         # wait for a disconnect
1785         rep = self.recv_pdu()
1786         self.assertIsNone(rep)
1787         self.assertNotConnected()
1788
1789     def test_spnego_connect_reauth_alter(self):
1790         ndr32 = base.transfer_syntax_ndr()
1791         ndr64 = base.transfer_syntax_ndr64()
1792
1793         tsf1_list = [ndr32]
1794         ctx1 = dcerpc.ctx_list()
1795         ctx1.context_id = 1
1796         ctx1.num_transfer_syntaxes = len(tsf1_list)
1797         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
1798         ctx1.transfer_syntaxes = tsf1_list
1799         ctx_list = [ctx1]
1800
1801         c = Credentials()
1802         c.set_anonymous()
1803         g = gensec.Security.start_client(self.settings)
1804         g.set_credentials(c)
1805         g.want_feature(gensec.FEATURE_DCE_STYLE)
1806         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1807         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
1808         auth_context_id = 2
1809         g.start_mech_by_authtype(auth_type, auth_level)
1810         from_server = ""
1811         (finished, to_server) = g.update(from_server)
1812         self.assertFalse(finished)
1813
1814         auth_info = self.generate_auth(auth_type=auth_type,
1815                                        auth_level=auth_level,
1816                                        auth_context_id=auth_context_id,
1817                                        auth_blob=to_server)
1818
1819         req = self.generate_bind(call_id=0,
1820                                  ctx_list=ctx_list,
1821                                  auth_info=auth_info)
1822
1823         self.send_pdu(req)
1824         rep = self.recv_pdu()
1825         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
1826         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1827         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1828         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1829         self.assertEquals(rep.u.secondary_address_size, 4)
1830         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
1831         self.assertEquals(len(rep.u._pad1), 2)
1832         self.assertEquals(rep.u._pad1, '\0' * 2)
1833         self.assertEquals(rep.u.num_results, 1)
1834         self.assertEquals(rep.u.ctx_list[0].result,
1835                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1836         self.assertEquals(rep.u.ctx_list[0].reason,
1837                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1838         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1839         self.assertNotEquals(len(rep.u.auth_info), 0)
1840         a = self.parse_auth(rep.u.auth_info)
1841
1842         from_server = a.credentials
1843         (finished, to_server) = g.update(from_server)
1844         self.assertFalse(finished)
1845
1846         auth_info = self.generate_auth(auth_type=auth_type,
1847                                        auth_level=auth_level,
1848                                        auth_context_id=auth_context_id,
1849                                        auth_blob=to_server)
1850         req = self.generate_alter(call_id=0,
1851                                   ctx_list=[ctx1],
1852                                   assoc_group_id=rep.u.assoc_group_id,
1853                                   auth_info=auth_info)
1854         self.send_pdu(req)
1855         rep = self.recv_pdu()
1856         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
1857         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1858         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1859         self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1860         self.assertEquals(rep.u.secondary_address_size, 0)
1861         self.assertEquals(len(rep.u._pad1), 2)
1862         # Windows sends garbage
1863         #self.assertEquals(rep.u._pad1, '\0' * 2)
1864         self.assertEquals(rep.u.num_results, 1)
1865         self.assertEquals(rep.u.ctx_list[0].result,
1866                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1867         self.assertEquals(rep.u.ctx_list[0].reason,
1868                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1869         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
1870         self.assertNotEquals(len(rep.u.auth_info), 0)
1871         a = self.parse_auth(rep.u.auth_info)
1872
1873         from_server = a.credentials
1874         (finished, to_server) = g.update(from_server)
1875         self.assertTrue(finished)
1876
1877         # And now try a request without auth_info
1878         req = self.generate_request(call_id = 2,
1879                                     context_id=ctx1.context_id,
1880                                     opnum=0,
1881                                     stub="")
1882         self.send_pdu(req)
1883         rep = self.recv_pdu()
1884         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1885                         auth_length=0)
1886         self.assertNotEquals(rep.u.alloc_hint, 0)
1887         self.assertEquals(rep.u.context_id, req.u.context_id)
1888         self.assertEquals(rep.u.cancel_count, 0)
1889         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1890
1891         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
1892         auth_info = self.generate_auth(auth_type=auth_type,
1893                                        auth_level=auth_level,
1894                                        auth_context_id=auth_context_id,
1895                                        auth_blob="\x01"+"\x00"*15)
1896         req = self.generate_request(call_id = 3,
1897                                     context_id=ctx1.context_id,
1898                                     opnum=0,
1899                                     stub="",
1900                                     auth_info=auth_info)
1901         self.send_pdu(req)
1902         rep = self.recv_pdu()
1903         # We don't get an auth_info back
1904         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
1905                         auth_length=0)
1906         self.assertNotEquals(rep.u.alloc_hint, 0)
1907         self.assertEquals(rep.u.context_id, req.u.context_id)
1908         self.assertEquals(rep.u.cancel_count, 0)
1909         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
1910
1911         # Now a reauth
1912
1913         g = gensec.Security.start_client(self.settings)
1914         g.set_credentials(c)
1915         g.want_feature(gensec.FEATURE_DCE_STYLE)
1916         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1917         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
1918         auth_context_id = 2
1919         g.start_mech_by_authtype(auth_type, auth_level)
1920         from_server = ""
1921         (finished, to_server) = g.update(from_server)
1922         self.assertFalse(finished)
1923
1924         auth_info = self.generate_auth(auth_type=auth_type,
1925                                        auth_level=auth_level,
1926                                        auth_context_id=auth_context_id,
1927                                        auth_blob=to_server)
1928         req = self.generate_alter(call_id=0,
1929                                   ctx_list=ctx_list,
1930                                   auth_info=auth_info)
1931         self.send_pdu(req)
1932         rep = self.recv_pdu()
1933         # We get a fault
1934         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
1935                         pfc_flags=req.pfc_flags |
1936                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
1937                         auth_length=0)
1938         self.assertNotEquals(rep.u.alloc_hint, 0)
1939         self.assertEquals(rep.u.context_id, 0)
1940         self.assertEquals(rep.u.cancel_count, 0)
1941         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
1942         self.assertEquals(len(rep.u._pad), 4)
1943         self.assertEquals(rep.u._pad, '\0' * 4)
1944
1945         # wait for a disconnect
1946         rep = self.recv_pdu()
1947         self.assertIsNone(rep)
1948         self.assertNotConnected()
1949
1950     def test_spnego_connect_reauth_auth3(self):
1951         ndr32 = base.transfer_syntax_ndr()
1952         ndr64 = base.transfer_syntax_ndr64()
1953
1954         tsf1_list = [ndr32]
1955         ctx1 = dcerpc.ctx_list()
1956         ctx1.context_id = 1
1957         ctx1.num_transfer_syntaxes = len(tsf1_list)
1958         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
1959         ctx1.transfer_syntaxes = tsf1_list
1960         ctx_list = [ctx1]
1961
1962         c = Credentials()
1963         c.set_anonymous()
1964         g = gensec.Security.start_client(self.settings)
1965         g.set_credentials(c)
1966         g.want_feature(gensec.FEATURE_DCE_STYLE)
1967         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
1968         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
1969         auth_context_id = 2
1970         g.start_mech_by_authtype(auth_type, auth_level)
1971         from_server = ""
1972         (finished, to_server) = g.update(from_server)
1973         self.assertFalse(finished)
1974
1975         auth_info = self.generate_auth(auth_type=auth_type,
1976                                        auth_level=auth_level,
1977                                        auth_context_id=auth_context_id,
1978                                        auth_blob=to_server)
1979
1980         req = self.generate_bind(call_id=0,
1981                                  ctx_list=ctx_list,
1982                                  auth_info=auth_info)
1983
1984         self.send_pdu(req)
1985         rep = self.recv_pdu()
1986         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
1987         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
1988         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
1989         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
1990         self.assertEquals(rep.u.secondary_address_size, 4)
1991         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
1992         self.assertEquals(len(rep.u._pad1), 2)
1993         self.assertEquals(rep.u._pad1, '\0' * 2)
1994         self.assertEquals(rep.u.num_results, 1)
1995         self.assertEquals(rep.u.ctx_list[0].result,
1996                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
1997         self.assertEquals(rep.u.ctx_list[0].reason,
1998                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
1999         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2000         self.assertNotEquals(len(rep.u.auth_info), 0)
2001         a = self.parse_auth(rep.u.auth_info)
2002
2003         from_server = a.credentials
2004         (finished, to_server) = g.update(from_server)
2005         self.assertFalse(finished)
2006
2007         auth_info = self.generate_auth(auth_type=auth_type,
2008                                        auth_level=auth_level,
2009                                        auth_context_id=auth_context_id,
2010                                        auth_blob=to_server)
2011         req = self.generate_alter(call_id=0,
2012                                   ctx_list=[ctx1],
2013                                   assoc_group_id=rep.u.assoc_group_id,
2014                                   auth_info=auth_info)
2015         self.send_pdu(req)
2016         rep = self.recv_pdu()
2017         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
2018         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2019         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2020         self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2021         self.assertEquals(rep.u.secondary_address_size, 0)
2022         self.assertEquals(len(rep.u._pad1), 2)
2023         # Windows sends garbage
2024         #self.assertEquals(rep.u._pad1, '\0' * 2)
2025         self.assertEquals(rep.u.num_results, 1)
2026         self.assertEquals(rep.u.ctx_list[0].result,
2027                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2028         self.assertEquals(rep.u.ctx_list[0].reason,
2029                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2030         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2031         self.assertNotEquals(len(rep.u.auth_info), 0)
2032         a = self.parse_auth(rep.u.auth_info)
2033
2034         from_server = a.credentials
2035         (finished, to_server) = g.update(from_server)
2036         self.assertTrue(finished)
2037
2038         # And now try a request without auth_info
2039         req = self.generate_request(call_id = 2,
2040                                     context_id=ctx1.context_id,
2041                                     opnum=0,
2042                                     stub="")
2043         self.send_pdu(req)
2044         rep = self.recv_pdu()
2045         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
2046                         auth_length=0)
2047         self.assertNotEquals(rep.u.alloc_hint, 0)
2048         self.assertEquals(rep.u.context_id, req.u.context_id)
2049         self.assertEquals(rep.u.cancel_count, 0)
2050         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
2051
2052         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
2053         auth_info = self.generate_auth(auth_type=auth_type,
2054                                        auth_level=auth_level,
2055                                        auth_context_id=auth_context_id,
2056                                        auth_blob="\x01"+"\x00"*15)
2057         req = self.generate_request(call_id = 3,
2058                                     context_id=ctx1.context_id,
2059                                     opnum=0,
2060                                     stub="",
2061                                     auth_info=auth_info)
2062         self.send_pdu(req)
2063         rep = self.recv_pdu()
2064         # We don't get an auth_info back
2065         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
2066                         auth_length=0)
2067         self.assertNotEquals(rep.u.alloc_hint, 0)
2068         self.assertEquals(rep.u.context_id, req.u.context_id)
2069         self.assertEquals(rep.u.cancel_count, 0)
2070         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
2071
2072         # Now a reauth
2073
2074         g = gensec.Security.start_client(self.settings)
2075         g.set_credentials(c)
2076         g.want_feature(gensec.FEATURE_DCE_STYLE)
2077         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2078         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
2079         auth_context_id = 2
2080         g.start_mech_by_authtype(auth_type, auth_level)
2081         from_server = ""
2082         (finished, to_server) = g.update(from_server)
2083         self.assertFalse(finished)
2084
2085         auth_info = self.generate_auth(auth_type=auth_type,
2086                                        auth_level=auth_level,
2087                                        auth_context_id=auth_context_id,
2088                                        auth_blob=to_server)
2089         req = self.generate_auth3(call_id=0,
2090                                   auth_info=auth_info)
2091         self.send_pdu(req)
2092         rep = self.recv_pdu()
2093         # We get a fault
2094         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2095                         pfc_flags=req.pfc_flags |
2096                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2097                         auth_length=0)
2098         self.assertNotEquals(rep.u.alloc_hint, 0)
2099         self.assertEquals(rep.u.context_id, 0)
2100         self.assertEquals(rep.u.cancel_count, 0)
2101         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
2102         self.assertEquals(len(rep.u._pad), 4)
2103         self.assertEquals(rep.u._pad, '\0' * 4)
2104
2105         # wait for a disconnect
2106         rep = self.recv_pdu()
2107         self.assertIsNone(rep)
2108         self.assertNotConnected()
2109
2110     def test_spnego_change_auth_level(self):
2111         ndr32 = base.transfer_syntax_ndr()
2112
2113         tsf1_list = [ndr32]
2114         ctx1 = dcerpc.ctx_list()
2115         ctx1.context_id = 1
2116         ctx1.num_transfer_syntaxes = len(tsf1_list)
2117         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2118         ctx1.transfer_syntaxes = tsf1_list
2119
2120         c = Credentials()
2121         c.set_anonymous()
2122         g = gensec.Security.start_client(self.settings)
2123         g.set_credentials(c)
2124         g.want_feature(gensec.FEATURE_DCE_STYLE)
2125         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2126         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
2127         auth_context_id = 2
2128         g.start_mech_by_authtype(auth_type, auth_level)
2129         from_server = ""
2130         (finished, to_server) = g.update(from_server)
2131         self.assertFalse(finished)
2132
2133         auth_info = self.generate_auth(auth_type=auth_type,
2134                                        auth_level=auth_level,
2135                                        auth_context_id=auth_context_id,
2136                                        auth_blob=to_server)
2137         req = self.generate_bind(call_id=0,
2138                                  ctx_list=[ctx1],
2139                                  auth_info=auth_info)
2140         self.send_pdu(req)
2141         rep = self.recv_pdu()
2142         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2143         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2144         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2145         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2146         self.assertEquals(rep.u.secondary_address_size, 4)
2147         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2148         self.assertEquals(len(rep.u._pad1), 2)
2149         self.assertEquals(rep.u._pad1, '\0' * 2)
2150         self.assertEquals(rep.u.num_results, 1)
2151         self.assertEquals(rep.u.ctx_list[0].result,
2152                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2153         self.assertEquals(rep.u.ctx_list[0].reason,
2154                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2155         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2156         self.assertNotEquals(len(rep.u.auth_info), 0)
2157         a = self.parse_auth(rep.u.auth_info)
2158
2159         from_server = a.credentials
2160         (finished, to_server) = g.update(from_server)
2161         self.assertFalse(finished)
2162
2163         auth_info = self.generate_auth(auth_type=auth_type,
2164                                        auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
2165                                        auth_context_id=auth_context_id,
2166                                        auth_blob=to_server)
2167         req = self.generate_alter(call_id=0,
2168                                   ctx_list=[ctx1],
2169                                   assoc_group_id=rep.u.assoc_group_id,
2170                                   auth_info=auth_info)
2171         self.send_pdu(req)
2172         rep = self.recv_pdu()
2173         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2174                         pfc_flags=req.pfc_flags |
2175                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2176                         auth_length=0)
2177         self.assertNotEquals(rep.u.alloc_hint, 0)
2178         self.assertEquals(rep.u.context_id, 0)
2179         self.assertEquals(rep.u.cancel_count, 0)
2180         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
2181         self.assertEquals(len(rep.u._pad), 4)
2182         self.assertEquals(rep.u._pad, '\0' * 4)
2183
2184         # wait for a disconnect
2185         rep = self.recv_pdu()
2186         self.assertIsNone(rep)
2187         self.assertNotConnected()
2188
2189     def test_spnego_change_abstract(self):
2190         ndr32 = base.transfer_syntax_ndr()
2191
2192         tsf1_list = [ndr32]
2193         ctx1 = dcerpc.ctx_list()
2194         ctx1.context_id = 1
2195         ctx1.num_transfer_syntaxes = len(tsf1_list)
2196         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2197         ctx1.transfer_syntaxes = tsf1_list
2198
2199         ctx1b = dcerpc.ctx_list()
2200         ctx1b.context_id = 1
2201         ctx1b.num_transfer_syntaxes = len(tsf1_list)
2202         ctx1b.abstract_syntax = samba.dcerpc.epmapper.abstract_syntax()
2203         ctx1b.transfer_syntaxes = tsf1_list
2204
2205         c = Credentials()
2206         c.set_anonymous()
2207         g = gensec.Security.start_client(self.settings)
2208         g.set_credentials(c)
2209         g.want_feature(gensec.FEATURE_DCE_STYLE)
2210         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2211         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
2212         auth_context_id = 2
2213         g.start_mech_by_authtype(auth_type, auth_level)
2214         from_server = ""
2215         (finished, to_server) = g.update(from_server)
2216         self.assertFalse(finished)
2217
2218         auth_info = self.generate_auth(auth_type=auth_type,
2219                                        auth_level=auth_level,
2220                                        auth_context_id=auth_context_id,
2221                                        auth_blob=to_server)
2222         req = self.generate_bind(call_id=0,
2223                                  ctx_list=[ctx1],
2224                                  auth_info=auth_info)
2225         self.send_pdu(req)
2226         rep = self.recv_pdu()
2227         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2228         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2229         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2230         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2231         self.assertEquals(rep.u.secondary_address_size, 4)
2232         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2233         self.assertEquals(len(rep.u._pad1), 2)
2234         #self.assertEquals(rep.u._pad1, '\0' * 2)
2235         self.assertEquals(rep.u.num_results, 1)
2236         self.assertEquals(rep.u.ctx_list[0].result,
2237                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2238         self.assertEquals(rep.u.ctx_list[0].reason,
2239                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2240         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2241         self.assertNotEquals(len(rep.u.auth_info), 0)
2242         a = self.parse_auth(rep.u.auth_info)
2243
2244         from_server = a.credentials
2245         (finished, to_server) = g.update(from_server)
2246         self.assertFalse(finished)
2247
2248         auth_info = self.generate_auth(auth_type=auth_type,
2249                                        auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
2250                                        auth_context_id=auth_context_id,
2251                                        auth_blob=to_server)
2252         req = self.generate_alter(call_id=0,
2253                                   ctx_list=[ctx1b],
2254                                   assoc_group_id=rep.u.assoc_group_id,
2255                                   auth_info=auth_info)
2256         self.send_pdu(req)
2257         rep = self.recv_pdu()
2258         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2259                         pfc_flags=req.pfc_flags |
2260                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2261                         auth_length=0)
2262         self.assertNotEquals(rep.u.alloc_hint, 0)
2263         self.assertEquals(rep.u.context_id, 0)
2264         self.assertEquals(rep.u.cancel_count, 0)
2265         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
2266         self.assertEquals(len(rep.u._pad), 4)
2267         self.assertEquals(rep.u._pad, '\0' * 4)
2268
2269         # wait for a disconnect
2270         rep = self.recv_pdu()
2271         self.assertIsNone(rep)
2272         self.assertNotConnected()
2273
2274     def test_spnego_change_transfer(self):
2275         ndr32 = base.transfer_syntax_ndr()
2276         ndr64 = base.transfer_syntax_ndr64()
2277
2278         tsf1_list = [ndr32]
2279         ctx1 = dcerpc.ctx_list()
2280         ctx1.context_id = 1
2281         ctx1.num_transfer_syntaxes = len(tsf1_list)
2282         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2283         ctx1.transfer_syntaxes = tsf1_list
2284
2285         tsf1b_list = [ndr32,ndr64]
2286         ctx1b = dcerpc.ctx_list()
2287         ctx1b.context_id = 1
2288         ctx1b.num_transfer_syntaxes = len(tsf1b_list)
2289         ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2290         ctx1b.transfer_syntaxes = tsf1b_list
2291
2292         c = Credentials()
2293         c.set_anonymous()
2294         g = gensec.Security.start_client(self.settings)
2295         g.set_credentials(c)
2296         g.want_feature(gensec.FEATURE_DCE_STYLE)
2297         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2298         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
2299         auth_context_id = 2
2300         g.start_mech_by_authtype(auth_type, auth_level)
2301         from_server = ""
2302         (finished, to_server) = g.update(from_server)
2303         self.assertFalse(finished)
2304
2305         auth_info = self.generate_auth(auth_type=auth_type,
2306                                        auth_level=auth_level,
2307                                        auth_context_id=auth_context_id,
2308                                        auth_blob=to_server)
2309         req = self.generate_bind(call_id=0,
2310                                  ctx_list=[ctx1],
2311                                  auth_info=auth_info)
2312         self.send_pdu(req)
2313         rep = self.recv_pdu()
2314         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2315         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2316         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2317         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2318         self.assertEquals(rep.u.secondary_address_size, 4)
2319         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2320         self.assertEquals(len(rep.u._pad1), 2)
2321         #self.assertEquals(rep.u._pad1, '\0' * 2)
2322         self.assertEquals(rep.u.num_results, 1)
2323         self.assertEquals(rep.u.ctx_list[0].result,
2324                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2325         self.assertEquals(rep.u.ctx_list[0].reason,
2326                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2327         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2328         self.assertNotEquals(len(rep.u.auth_info), 0)
2329         a = self.parse_auth(rep.u.auth_info)
2330
2331         from_server = a.credentials
2332         (finished, to_server) = g.update(from_server)
2333         self.assertFalse(finished)
2334
2335         # We change ctx_list and auth_level
2336         auth_info = self.generate_auth(auth_type=auth_type,
2337                                        auth_level=dcerpc.DCERPC_AUTH_LEVEL_PRIVACY,
2338                                        auth_context_id=auth_context_id,
2339                                        auth_blob=to_server)
2340         req = self.generate_alter(call_id=0,
2341                                   ctx_list=[ctx1b],
2342                                   assoc_group_id=rep.u.assoc_group_id,
2343                                   auth_info=auth_info)
2344         self.send_pdu(req)
2345         rep = self.recv_pdu()
2346         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2347                         pfc_flags=req.pfc_flags |
2348                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2349                         auth_length=0)
2350         self.assertNotEquals(rep.u.alloc_hint, 0)
2351         self.assertEquals(rep.u.context_id, 0)
2352         self.assertEquals(rep.u.cancel_count, 0)
2353         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
2354         self.assertEquals(len(rep.u._pad), 4)
2355         self.assertEquals(rep.u._pad, '\0' * 4)
2356
2357         # wait for a disconnect
2358         rep = self.recv_pdu()
2359         self.assertIsNone(rep)
2360         self.assertNotConnected()
2361
2362     def test_spnego_change_auth_type1(self):
2363         ndr32 = base.transfer_syntax_ndr()
2364         ndr64 = base.transfer_syntax_ndr64()
2365
2366         tsf1_list = [ndr32]
2367         ctx1 = dcerpc.ctx_list()
2368         ctx1.context_id = 1
2369         ctx1.num_transfer_syntaxes = len(tsf1_list)
2370         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2371         ctx1.transfer_syntaxes = tsf1_list
2372
2373         c = Credentials()
2374         c.set_anonymous()
2375         g = gensec.Security.start_client(self.settings)
2376         g.set_credentials(c)
2377         g.want_feature(gensec.FEATURE_DCE_STYLE)
2378         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2379         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
2380         auth_context_id = 2
2381         g.start_mech_by_authtype(auth_type, auth_level)
2382         from_server = ""
2383         (finished, to_server) = g.update(from_server)
2384         self.assertFalse(finished)
2385
2386         auth_info = self.generate_auth(auth_type=auth_type,
2387                                        auth_level=auth_level,
2388                                        auth_context_id=auth_context_id,
2389                                        auth_blob=to_server)
2390         req = self.generate_bind(call_id=0,
2391                                  ctx_list=[ctx1],
2392                                  auth_info=auth_info)
2393         self.send_pdu(req)
2394         rep = self.recv_pdu()
2395         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2396         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2397         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2398         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2399         self.assertEquals(rep.u.secondary_address_size, 4)
2400         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2401         self.assertEquals(len(rep.u._pad1), 2)
2402         #self.assertEquals(rep.u._pad1, '\0' * 2)
2403         self.assertEquals(rep.u.num_results, 1)
2404         self.assertEquals(rep.u.ctx_list[0].result,
2405                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2406         self.assertEquals(rep.u.ctx_list[0].reason,
2407                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2408         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2409         self.assertNotEquals(len(rep.u.auth_info), 0)
2410         a = self.parse_auth(rep.u.auth_info)
2411
2412         from_server = a.credentials
2413         (finished, to_server) = g.update(from_server)
2414         self.assertFalse(finished)
2415
2416         # We change ctx_list and auth_level
2417         auth_info = self.generate_auth(auth_type=dcerpc.DCERPC_AUTH_TYPE_KRB5,
2418                                        auth_level=auth_level,
2419                                        auth_context_id=auth_context_id,
2420                                        auth_blob=to_server)
2421         req = self.generate_alter(call_id=0,
2422                                   ctx_list=[ctx1],
2423                                   assoc_group_id=rep.u.assoc_group_id,
2424                                   auth_info=auth_info)
2425         self.send_pdu(req)
2426         rep = self.recv_pdu()
2427         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2428                         pfc_flags=req.pfc_flags |
2429                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2430                         auth_length=0)
2431         self.assertNotEquals(rep.u.alloc_hint, 0)
2432         self.assertEquals(rep.u.context_id, 0)
2433         self.assertEquals(rep.u.cancel_count, 0)
2434         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_SEC_PKG_ERROR)
2435         self.assertEquals(len(rep.u._pad), 4)
2436         self.assertEquals(rep.u._pad, '\0' * 4)
2437
2438         # wait for a disconnect
2439         rep = self.recv_pdu()
2440         self.assertIsNone(rep)
2441         self.assertNotConnected()
2442
2443     def test_spnego_change_auth_type2(self):
2444         ndr32 = base.transfer_syntax_ndr()
2445         ndr64 = base.transfer_syntax_ndr64()
2446
2447         tsf1_list = [ndr32]
2448         ctx1 = dcerpc.ctx_list()
2449         ctx1.context_id = 1
2450         ctx1.num_transfer_syntaxes = len(tsf1_list)
2451         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2452         ctx1.transfer_syntaxes = tsf1_list
2453
2454         tsf1b_list = [ndr32,ndr64]
2455         ctx1b = dcerpc.ctx_list()
2456         ctx1b.context_id = 1
2457         ctx1b.num_transfer_syntaxes = len(tsf1b_list)
2458         ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2459         ctx1b.transfer_syntaxes = tsf1b_list
2460
2461         c = Credentials()
2462         c.set_anonymous()
2463         g = gensec.Security.start_client(self.settings)
2464         g.set_credentials(c)
2465         g.want_feature(gensec.FEATURE_DCE_STYLE)
2466         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2467         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
2468         auth_context_id = 2
2469         g.start_mech_by_authtype(auth_type, auth_level)
2470         from_server = ""
2471         (finished, to_server) = g.update(from_server)
2472         self.assertFalse(finished)
2473
2474         auth_info = self.generate_auth(auth_type=auth_type,
2475                                        auth_level=auth_level,
2476                                        auth_context_id=auth_context_id,
2477                                        auth_blob=to_server)
2478         req = self.generate_bind(call_id=0,
2479                                  ctx_list=[ctx1],
2480                                  auth_info=auth_info)
2481         self.send_pdu(req)
2482         rep = self.recv_pdu()
2483         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2484         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2485         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2486         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2487         self.assertEquals(rep.u.secondary_address_size, 4)
2488         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2489         self.assertEquals(len(rep.u._pad1), 2)
2490         #self.assertEquals(rep.u._pad1, '\0' * 2)
2491         self.assertEquals(rep.u.num_results, 1)
2492         self.assertEquals(rep.u.ctx_list[0].result,
2493                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2494         self.assertEquals(rep.u.ctx_list[0].reason,
2495                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2496         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2497         self.assertNotEquals(len(rep.u.auth_info), 0)
2498         a = self.parse_auth(rep.u.auth_info)
2499
2500         from_server = a.credentials
2501         (finished, to_server) = g.update(from_server)
2502         self.assertFalse(finished)
2503
2504         # We change ctx_list and auth_level
2505         auth_info = self.generate_auth(auth_type=dcerpc.DCERPC_AUTH_TYPE_KRB5,
2506                                        auth_level=auth_level,
2507                                        auth_context_id=auth_context_id,
2508                                        auth_blob=to_server)
2509         req = self.generate_alter(call_id=0,
2510                                   ctx_list=[ctx1b],
2511                                   assoc_group_id=rep.u.assoc_group_id,
2512                                   auth_info=auth_info)
2513         self.send_pdu(req)
2514         rep = self.recv_pdu()
2515         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2516                         pfc_flags=req.pfc_flags |
2517                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2518                         auth_length=0)
2519         self.assertNotEquals(rep.u.alloc_hint, 0)
2520         self.assertEquals(rep.u.context_id, 0)
2521         self.assertEquals(rep.u.cancel_count, 0)
2522         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
2523         self.assertEquals(len(rep.u._pad), 4)
2524         self.assertEquals(rep.u._pad, '\0' * 4)
2525
2526         # wait for a disconnect
2527         rep = self.recv_pdu()
2528         self.assertIsNone(rep)
2529         self.assertNotConnected()
2530
2531     def test_spnego_change_auth_type3(self):
2532         ndr32 = base.transfer_syntax_ndr()
2533         ndr64 = base.transfer_syntax_ndr64()
2534
2535         tsf1_list = [ndr32]
2536         ctx1 = dcerpc.ctx_list()
2537         ctx1.context_id = 1
2538         ctx1.num_transfer_syntaxes = len(tsf1_list)
2539         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2540         ctx1.transfer_syntaxes = tsf1_list
2541
2542         tsf1b_list = [ndr32,ndr64]
2543         ctx1b = dcerpc.ctx_list()
2544         ctx1b.context_id = 1
2545         ctx1b.num_transfer_syntaxes = len(tsf1b_list)
2546         ctx1b.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2547         ctx1b.transfer_syntaxes = tsf1b_list
2548
2549         c = Credentials()
2550         c.set_anonymous()
2551         g = gensec.Security.start_client(self.settings)
2552         g.set_credentials(c)
2553         g.want_feature(gensec.FEATURE_DCE_STYLE)
2554         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2555         auth_level = dcerpc.DCERPC_AUTH_LEVEL_INTEGRITY
2556         auth_context_id = 2
2557         g.start_mech_by_authtype(auth_type, auth_level)
2558         from_server = ""
2559         (finished, to_server) = g.update(from_server)
2560         self.assertFalse(finished)
2561
2562         auth_info = self.generate_auth(auth_type=auth_type,
2563                                        auth_level=auth_level,
2564                                        auth_context_id=auth_context_id,
2565                                        auth_blob=to_server)
2566         req = self.generate_bind(call_id=0,
2567                                  ctx_list=[ctx1],
2568                                  auth_info=auth_info)
2569         self.send_pdu(req)
2570         rep = self.recv_pdu()
2571         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2572         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2573         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2574         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2575         self.assertEquals(rep.u.secondary_address_size, 4)
2576         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2577         self.assertEquals(len(rep.u._pad1), 2)
2578         #self.assertEquals(rep.u._pad1, '\0' * 2)
2579         self.assertEquals(rep.u.num_results, 1)
2580         self.assertEquals(rep.u.ctx_list[0].result,
2581                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2582         self.assertEquals(rep.u.ctx_list[0].reason,
2583                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2584         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2585         self.assertNotEquals(len(rep.u.auth_info), 0)
2586         a = self.parse_auth(rep.u.auth_info)
2587
2588         from_server = a.credentials
2589         (finished, to_server) = g.update(from_server)
2590         self.assertFalse(finished)
2591
2592         # We change ctx_list and auth_level
2593         auth_info = self.generate_auth(auth_type=dcerpc.DCERPC_AUTH_TYPE_NONE,
2594                                        auth_level=auth_level,
2595                                        auth_context_id=auth_context_id,
2596                                        auth_blob=to_server)
2597         req = self.generate_alter(call_id=0,
2598                                   ctx_list=[ctx1b],
2599                                   assoc_group_id=rep.u.assoc_group_id,
2600                                   auth_info=auth_info)
2601         self.send_pdu(req)
2602         rep = self.recv_pdu()
2603         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2604                         pfc_flags=req.pfc_flags |
2605                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2606                         auth_length=0)
2607         self.assertNotEquals(rep.u.alloc_hint, 0)
2608         self.assertEquals(rep.u.context_id, 0)
2609         self.assertEquals(rep.u.cancel_count, 0)
2610         self.assertEquals(rep.u.status, dcerpc.DCERPC_FAULT_ACCESS_DENIED)
2611         self.assertEquals(len(rep.u._pad), 4)
2612         self.assertEquals(rep.u._pad, '\0' * 4)
2613
2614         # wait for a disconnect
2615         rep = self.recv_pdu()
2616         self.assertIsNone(rep)
2617         self.assertNotConnected()
2618
2619     def test_spnego_auth_pad_ok(self):
2620         ndr32 = base.transfer_syntax_ndr()
2621
2622         tsf1_list = [ndr32]
2623         ctx1 = dcerpc.ctx_list()
2624         ctx1.context_id = 1
2625         ctx1.num_transfer_syntaxes = len(tsf1_list)
2626         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2627         ctx1.transfer_syntaxes = tsf1_list
2628         ctx_list = [ctx1]
2629
2630         c = Credentials()
2631         c.set_anonymous()
2632         g = gensec.Security.start_client(self.settings)
2633         g.set_credentials(c)
2634         g.want_feature(gensec.FEATURE_DCE_STYLE)
2635         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2636         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
2637         auth_context_id = 2
2638         g.start_mech_by_authtype(auth_type, auth_level)
2639         from_server = ""
2640         (finished, to_server) = g.update(from_server)
2641         self.assertFalse(finished)
2642
2643         auth_info = self.generate_auth(auth_type=auth_type,
2644                                        auth_level=auth_level,
2645                                        auth_context_id=auth_context_id,
2646                                        auth_blob=to_server)
2647
2648         req = self.generate_bind(call_id=0,
2649                                  ctx_list=ctx_list,
2650                                  auth_info=auth_info)
2651         req_pdu = samba.ndr.ndr_pack(req)
2652
2653         auth_pad_ok = len(req_pdu)
2654         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
2655         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
2656         auth_pad_ok -= len(to_server)
2657
2658         auth_info = self.generate_auth(auth_type=auth_type,
2659                                        auth_level=auth_level,
2660                                        auth_context_id=auth_context_id,
2661                                        auth_pad_length=auth_pad_ok,
2662                                        auth_blob=to_server)
2663
2664         req = self.generate_bind(call_id=0,
2665                                  ctx_list=ctx_list,
2666                                  auth_info=auth_info)
2667         self.send_pdu(req)
2668         rep = self.recv_pdu()
2669         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2670         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2671         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2672         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2673         self.assertEquals(rep.u.secondary_address_size, 4)
2674         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2675         self.assertEquals(len(rep.u._pad1), 2)
2676         #self.assertEquals(rep.u._pad1, '\0' * 2)
2677         self.assertEquals(rep.u.num_results, 1)
2678         self.assertEquals(rep.u.ctx_list[0].result,
2679                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2680         self.assertEquals(rep.u.ctx_list[0].reason,
2681                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2682         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2683         self.assertNotEquals(len(rep.u.auth_info), 0)
2684         a = self.parse_auth(rep.u.auth_info)
2685
2686         from_server = a.credentials
2687         (finished, to_server) = g.update(from_server)
2688         self.assertFalse(finished)
2689
2690         auth_info = self.generate_auth(auth_type=auth_type,
2691                                        auth_level=auth_level,
2692                                        auth_context_id=auth_context_id,
2693                                        auth_blob=to_server)
2694         req = self.generate_alter(call_id=0,
2695                                   ctx_list=ctx_list,
2696                                   assoc_group_id=rep.u.assoc_group_id,
2697                                   auth_info=auth_info)
2698         req_pdu = samba.ndr.ndr_pack(req)
2699
2700         auth_pad_ok = len(req_pdu)
2701         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
2702         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
2703         auth_pad_ok -= len(to_server)
2704         auth_info = self.generate_auth(auth_type=auth_type,
2705                                        auth_level=auth_level,
2706                                        auth_context_id=auth_context_id,
2707                                        auth_pad_length=auth_pad_ok,
2708                                        auth_blob=to_server)
2709         req = self.generate_alter(call_id=0,
2710                                   ctx_list=ctx_list,
2711                                   assoc_group_id=rep.u.assoc_group_id,
2712                                   auth_info=auth_info)
2713         self.send_pdu(req)
2714         rep = self.recv_pdu()
2715         self.verify_pdu(rep, dcerpc.DCERPC_PKT_ALTER_RESP, req.call_id)
2716         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2717         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2718         self.assertEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2719         self.assertEquals(rep.u.secondary_address_size, 0)
2720         self.assertEquals(len(rep.u._pad1), 2)
2721         # Windows sends garbage
2722         #self.assertEquals(rep.u._pad1, '\0' * 2)
2723         self.assertEquals(rep.u.num_results, 1)
2724         self.assertEquals(rep.u.ctx_list[0].result,
2725                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2726         self.assertEquals(rep.u.ctx_list[0].reason,
2727                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2728         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2729         self.assertNotEquals(len(rep.u.auth_info), 0)
2730         a = self.parse_auth(rep.u.auth_info)
2731
2732         from_server = a.credentials
2733         (finished, to_server) = g.update(from_server)
2734         self.assertTrue(finished)
2735
2736         # And now try a request without auth_info
2737         req = self.generate_request(call_id = 2,
2738                                     context_id=ctx1.context_id,
2739                                     opnum=0,
2740                                     stub="")
2741         self.send_pdu(req)
2742         rep = self.recv_pdu()
2743         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
2744                         auth_length=0)
2745         self.assertNotEquals(rep.u.alloc_hint, 0)
2746         self.assertEquals(rep.u.context_id, req.u.context_id)
2747         self.assertEquals(rep.u.cancel_count, 0)
2748         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
2749
2750         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
2751         auth_info = self.generate_auth(auth_type=auth_type,
2752                                        auth_level=auth_level,
2753                                        auth_context_id=auth_context_id,
2754                                        auth_blob="\x01"+"\x00"*15)
2755         req = self.generate_request(call_id = 3,
2756                                     context_id=ctx1.context_id,
2757                                     opnum=0,
2758                                     stub="",
2759                                     auth_info=auth_info)
2760         self.send_pdu(req)
2761         rep = self.recv_pdu()
2762         # We don't get an auth_info back
2763         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
2764                         auth_length=0)
2765         self.assertNotEquals(rep.u.alloc_hint, 0)
2766         self.assertEquals(rep.u.context_id, req.u.context_id)
2767         self.assertEquals(rep.u.cancel_count, 0)
2768         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
2769
2770         self._disconnect("disconnect")
2771         self.assertNotConnected()
2772
2773     def test_spnego_auth_pad_fail_bind(self):
2774         ndr32 = base.transfer_syntax_ndr()
2775
2776         tsf1_list = [ndr32]
2777         ctx1 = dcerpc.ctx_list()
2778         ctx1.context_id = 1
2779         ctx1.num_transfer_syntaxes = len(tsf1_list)
2780         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2781         ctx1.transfer_syntaxes = tsf1_list
2782         ctx_list = [ctx1]
2783
2784         c = Credentials()
2785         c.set_anonymous()
2786         g = gensec.Security.start_client(self.settings)
2787         g.set_credentials(c)
2788         g.want_feature(gensec.FEATURE_DCE_STYLE)
2789         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2790         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
2791         auth_context_id = 2
2792         g.start_mech_by_authtype(auth_type, auth_level)
2793         from_server = ""
2794         (finished, to_server) = g.update(from_server)
2795         self.assertFalse(finished)
2796
2797         auth_info = self.generate_auth(auth_type=auth_type,
2798                                        auth_level=auth_level,
2799                                        auth_context_id=auth_context_id,
2800                                        auth_blob=to_server)
2801
2802         req = self.generate_bind(call_id=0,
2803                                  ctx_list=ctx_list,
2804                                  auth_info=auth_info)
2805         req_pdu = samba.ndr.ndr_pack(req)
2806
2807         auth_pad_ok = len(req_pdu)
2808         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
2809         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
2810         auth_pad_ok -= len(to_server)
2811         auth_pad_bad = auth_pad_ok + 1
2812         auth_info = self.generate_auth(auth_type=auth_type,
2813                                        auth_level=auth_level,
2814                                        auth_context_id=auth_context_id,
2815                                        auth_pad_length=auth_pad_bad,
2816                                        auth_blob=to_server)
2817
2818         req = self.generate_bind(call_id=0,
2819                                  ctx_list=ctx_list,
2820                                  auth_info=auth_info)
2821         self.send_pdu(req)
2822         rep = self.recv_pdu()
2823         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_NAK, req.call_id,
2824                         auth_length=0)
2825         self.assertEquals(rep.u.reject_reason,
2826                 dcerpc.DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED)
2827         self.assertEquals(rep.u.num_versions, 1)
2828         self.assertEquals(rep.u.versions[0].rpc_vers, req.rpc_vers)
2829         self.assertEquals(rep.u.versions[0].rpc_vers_minor, req.rpc_vers_minor)
2830         self.assertEquals(len(rep.u._pad), 3)
2831         self.assertEquals(rep.u._pad, '\0' * 3)
2832
2833         # wait for a disconnect
2834         rep = self.recv_pdu()
2835         self.assertIsNone(rep)
2836         self.assertNotConnected()
2837
2838     def test_spnego_auth_pad_fail_alter(self):
2839         ndr32 = base.transfer_syntax_ndr()
2840
2841         tsf1_list = [ndr32]
2842         ctx1 = dcerpc.ctx_list()
2843         ctx1.context_id = 1
2844         ctx1.num_transfer_syntaxes = len(tsf1_list)
2845         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2846         ctx1.transfer_syntaxes = tsf1_list
2847         ctx_list = [ctx1]
2848
2849         c = Credentials()
2850         c.set_anonymous()
2851         g = gensec.Security.start_client(self.settings)
2852         g.set_credentials(c)
2853         g.want_feature(gensec.FEATURE_DCE_STYLE)
2854         auth_type = dcerpc.DCERPC_AUTH_TYPE_SPNEGO
2855         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
2856         auth_context_id = 2
2857         g.start_mech_by_authtype(auth_type, auth_level)
2858         from_server = ""
2859         (finished, to_server) = g.update(from_server)
2860         self.assertFalse(finished)
2861
2862         auth_info = self.generate_auth(auth_type=auth_type,
2863                                        auth_level=auth_level,
2864                                        auth_context_id=auth_context_id,
2865                                        auth_blob=to_server)
2866
2867         req = self.generate_bind(call_id=0,
2868                                  ctx_list=ctx_list,
2869                                  auth_info=auth_info)
2870         req_pdu = samba.ndr.ndr_pack(req)
2871
2872         auth_pad_ok = len(req_pdu)
2873         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
2874         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
2875         auth_pad_ok -= len(to_server)
2876
2877         auth_info = self.generate_auth(auth_type=auth_type,
2878                                        auth_level=auth_level,
2879                                        auth_context_id=auth_context_id,
2880                                        auth_pad_length=auth_pad_ok,
2881                                        auth_blob=to_server)
2882
2883         req = self.generate_bind(call_id=0,
2884                                  ctx_list=ctx_list,
2885                                  auth_info=auth_info)
2886         self.send_pdu(req)
2887         rep = self.recv_pdu()
2888         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
2889         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
2890         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
2891         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
2892         self.assertEquals(rep.u.secondary_address_size, 4)
2893         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
2894         self.assertEquals(len(rep.u._pad1), 2)
2895         #self.assertEquals(rep.u._pad1, '\0' * 2)
2896         self.assertEquals(rep.u.num_results, 1)
2897         self.assertEquals(rep.u.ctx_list[0].result,
2898                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
2899         self.assertEquals(rep.u.ctx_list[0].reason,
2900                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
2901         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
2902         self.assertNotEquals(len(rep.u.auth_info), 0)
2903         a = self.parse_auth(rep.u.auth_info)
2904
2905         from_server = a.credentials
2906         (finished, to_server) = g.update(from_server)
2907         self.assertFalse(finished)
2908
2909         auth_info = self.generate_auth(auth_type=auth_type,
2910                                        auth_level=auth_level,
2911                                        auth_context_id=auth_context_id,
2912                                        auth_blob=to_server)
2913         req = self.generate_alter(call_id=0,
2914                                   ctx_list=ctx_list,
2915                                   assoc_group_id=rep.u.assoc_group_id,
2916                                   auth_info=auth_info)
2917         req_pdu = samba.ndr.ndr_pack(req)
2918
2919         auth_pad_ok = len(req_pdu)
2920         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
2921         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
2922         auth_pad_ok -= len(to_server)
2923         auth_pad_bad = auth_pad_ok + 1
2924         auth_info = self.generate_auth(auth_type=auth_type,
2925                                        auth_level=auth_level,
2926                                        auth_context_id=auth_context_id,
2927                                        auth_pad_length=auth_pad_bad,
2928                                        auth_blob=to_server)
2929         req = self.generate_alter(call_id=0,
2930                                   ctx_list=ctx_list,
2931                                   assoc_group_id=rep.u.assoc_group_id,
2932                                   auth_info=auth_info)
2933         self.send_pdu(req)
2934         rep = self.recv_pdu()
2935         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
2936                         pfc_flags=req.pfc_flags |
2937                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
2938                         auth_length=0)
2939         self.assertNotEquals(rep.u.alloc_hint, 0)
2940         self.assertEquals(rep.u.context_id, 0)
2941         self.assertEquals(rep.u.cancel_count, 0)
2942         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_PROTO_ERROR)
2943         self.assertEquals(len(rep.u._pad), 4)
2944         self.assertEquals(rep.u._pad, '\0' * 4)
2945
2946         # wait for a disconnect
2947         rep = self.recv_pdu()
2948         self.assertIsNone(rep)
2949         self.assertNotConnected()
2950
2951     def test_ntlmssp_auth_pad_ok(self):
2952         ndr32 = base.transfer_syntax_ndr()
2953
2954         tsf1_list = [ndr32]
2955         ctx1 = dcerpc.ctx_list()
2956         ctx1.context_id = 1
2957         ctx1.num_transfer_syntaxes = len(tsf1_list)
2958         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
2959         ctx1.transfer_syntaxes = tsf1_list
2960         ctx_list = [ctx1]
2961
2962         c = Credentials()
2963         c.set_anonymous()
2964         g = gensec.Security.start_client(self.settings)
2965         g.set_credentials(c)
2966         g.want_feature(gensec.FEATURE_DCE_STYLE)
2967         auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
2968         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
2969         auth_context_id = 2
2970         g.start_mech_by_authtype(auth_type, auth_level)
2971         from_server = ""
2972         (finished, to_server) = g.update(from_server)
2973         self.assertFalse(finished)
2974
2975         auth_info = self.generate_auth(auth_type=auth_type,
2976                                        auth_level=auth_level,
2977                                        auth_context_id=auth_context_id,
2978                                        auth_blob=to_server)
2979
2980         req = self.generate_bind(call_id=0,
2981                                  ctx_list=ctx_list,
2982                                  auth_info=auth_info)
2983         req_pdu = samba.ndr.ndr_pack(req)
2984
2985         auth_pad_ok = len(req_pdu)
2986         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
2987         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
2988         auth_pad_ok -= len(to_server)
2989
2990         auth_info = self.generate_auth(auth_type=auth_type,
2991                                        auth_level=auth_level,
2992                                        auth_context_id=auth_context_id,
2993                                        auth_pad_length=auth_pad_ok,
2994                                        auth_blob=to_server)
2995
2996         req = self.generate_bind(call_id=0,
2997                                  ctx_list=ctx_list,
2998                                  auth_info=auth_info)
2999         self.send_pdu(req)
3000         rep = self.recv_pdu()
3001         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
3002         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
3003         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
3004         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
3005         self.assertEquals(rep.u.secondary_address_size, 4)
3006         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
3007         self.assertEquals(len(rep.u._pad1), 2)
3008         #self.assertEquals(rep.u._pad1, '\0' * 2)
3009         self.assertEquals(rep.u.num_results, 1)
3010         self.assertEquals(rep.u.ctx_list[0].result,
3011                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
3012         self.assertEquals(rep.u.ctx_list[0].reason,
3013                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
3014         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
3015         self.assertNotEquals(len(rep.u.auth_info), 0)
3016         a = self.parse_auth(rep.u.auth_info)
3017
3018         from_server = a.credentials
3019         (finished, to_server) = g.update(from_server)
3020         self.assertTrue(finished)
3021
3022         auth_pad_ok = 0
3023         auth_info = self.generate_auth(auth_type=auth_type,
3024                                        auth_level=auth_level,
3025                                        auth_context_id=auth_context_id,
3026                                        auth_pad_length=auth_pad_ok,
3027                                        auth_blob=to_server)
3028         req = self.generate_auth3(call_id=0,
3029                                   auth_info=auth_info)
3030         self.send_pdu(req)
3031         self.assertIsConnected()
3032
3033         # And now try a request without auth_info
3034         req = self.generate_request(call_id = 2,
3035                                     context_id=ctx1.context_id,
3036                                     opnum=0,
3037                                     stub="")
3038         self.send_pdu(req)
3039         rep = self.recv_pdu()
3040         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
3041                         auth_length=0)
3042         self.assertNotEquals(rep.u.alloc_hint, 0)
3043         self.assertEquals(rep.u.context_id, req.u.context_id)
3044         self.assertEquals(rep.u.cancel_count, 0)
3045         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
3046
3047         # Now a request with auth_info DCERPC_AUTH_LEVEL_CONNECT
3048         auth_info = self.generate_auth(auth_type=auth_type,
3049                                        auth_level=auth_level,
3050                                        auth_context_id=auth_context_id,
3051                                        auth_blob="\x01"+"\x00"*15)
3052         req = self.generate_request(call_id = 3,
3053                                     context_id=ctx1.context_id,
3054                                     opnum=0,
3055                                     stub="",
3056                                     auth_info=auth_info)
3057         self.send_pdu(req)
3058         rep = self.recv_pdu()
3059         # We don't get an auth_info back
3060         self.verify_pdu(rep, dcerpc.DCERPC_PKT_RESPONSE, req.call_id,
3061                         auth_length=0)
3062         self.assertNotEquals(rep.u.alloc_hint, 0)
3063         self.assertEquals(rep.u.context_id, req.u.context_id)
3064         self.assertEquals(rep.u.cancel_count, 0)
3065         self.assertGreaterEqual(len(rep.u.stub_and_verifier), rep.u.alloc_hint)
3066
3067         self._disconnect("disconnect")
3068         self.assertNotConnected()
3069
3070     def test_ntlmssp_auth_pad_fail_auth3(self):
3071         ndr32 = base.transfer_syntax_ndr()
3072
3073         tsf1_list = [ndr32]
3074         ctx1 = dcerpc.ctx_list()
3075         ctx1.context_id = 1
3076         ctx1.num_transfer_syntaxes = len(tsf1_list)
3077         ctx1.abstract_syntax = samba.dcerpc.mgmt.abstract_syntax()
3078         ctx1.transfer_syntaxes = tsf1_list
3079         ctx_list = [ctx1]
3080
3081         c = Credentials()
3082         c.set_anonymous()
3083         g = gensec.Security.start_client(self.settings)
3084         g.set_credentials(c)
3085         g.want_feature(gensec.FEATURE_DCE_STYLE)
3086         auth_type = dcerpc.DCERPC_AUTH_TYPE_NTLMSSP
3087         auth_level = dcerpc.DCERPC_AUTH_LEVEL_CONNECT
3088         auth_context_id = 2
3089         g.start_mech_by_authtype(auth_type, auth_level)
3090         from_server = ""
3091         (finished, to_server) = g.update(from_server)
3092         self.assertFalse(finished)
3093
3094         auth_info = self.generate_auth(auth_type=auth_type,
3095                                        auth_level=auth_level,
3096                                        auth_context_id=auth_context_id,
3097                                        auth_blob=to_server)
3098
3099         req = self.generate_bind(call_id=0,
3100                                  ctx_list=ctx_list,
3101                                  auth_info=auth_info)
3102         req_pdu = samba.ndr.ndr_pack(req)
3103
3104         auth_pad_ok = len(req_pdu)
3105         auth_pad_ok -= dcerpc.DCERPC_REQUEST_LENGTH
3106         auth_pad_ok -= dcerpc.DCERPC_AUTH_TRAILER_LENGTH
3107         auth_pad_ok -= len(to_server)
3108
3109         auth_info = self.generate_auth(auth_type=auth_type,
3110                                        auth_level=auth_level,
3111                                        auth_context_id=auth_context_id,
3112                                        auth_pad_length=auth_pad_ok,
3113                                        auth_blob=to_server)
3114
3115         req = self.generate_bind(call_id=0,
3116                                  ctx_list=ctx_list,
3117                                  auth_info=auth_info)
3118         self.send_pdu(req)
3119         rep = self.recv_pdu()
3120         self.verify_pdu(rep, dcerpc.DCERPC_PKT_BIND_ACK, req.call_id)
3121         self.assertEquals(rep.u.max_xmit_frag, req.u.max_xmit_frag)
3122         self.assertEquals(rep.u.max_recv_frag, req.u.max_recv_frag)
3123         self.assertNotEquals(rep.u.assoc_group_id, req.u.assoc_group_id)
3124         self.assertEquals(rep.u.secondary_address_size, 4)
3125         self.assertEquals(rep.u.secondary_address, "%d" % self.tcp_port)
3126         self.assertEquals(len(rep.u._pad1), 2)
3127         #self.assertEquals(rep.u._pad1, '\0' * 2)
3128         self.assertEquals(rep.u.num_results, 1)
3129         self.assertEquals(rep.u.ctx_list[0].result,
3130                 dcerpc.DCERPC_BIND_ACK_RESULT_ACCEPTANCE)
3131         self.assertEquals(rep.u.ctx_list[0].reason,
3132                 dcerpc.DCERPC_BIND_ACK_REASON_NOT_SPECIFIED)
3133         self.assertNDRSyntaxEquals(rep.u.ctx_list[0].syntax, ndr32)
3134         self.assertNotEquals(len(rep.u.auth_info), 0)
3135         a = self.parse_auth(rep.u.auth_info)
3136
3137         from_server = a.credentials
3138         (finished, to_server) = g.update(from_server)
3139         self.assertTrue(finished)
3140
3141         auth_pad_bad = 1
3142         auth_info = self.generate_auth(auth_type=auth_type,
3143                                        auth_level=auth_level,
3144                                        auth_context_id=auth_context_id,
3145                                        auth_pad_length=auth_pad_bad,
3146                                        auth_blob=to_server)
3147         req = self.generate_auth3(call_id=0,
3148                                   auth_info=auth_info)
3149         self.send_pdu(req)
3150         rep = self.recv_pdu()
3151         self.verify_pdu(rep, dcerpc.DCERPC_PKT_FAULT, req.call_id,
3152                         pfc_flags=req.pfc_flags |
3153                         dcerpc.DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
3154                         auth_length=0)
3155         self.assertNotEquals(rep.u.alloc_hint, 0)
3156         self.assertEquals(rep.u.context_id, 0)
3157         self.assertEquals(rep.u.cancel_count, 0)
3158         self.assertEquals(rep.u.status, dcerpc.DCERPC_NCA_S_FAULT_REMOTE_NO_MEMORY)
3159         self.assertEquals(len(rep.u._pad), 4)
3160         self.assertEquals(rep.u._pad, '\0' * 4)
3161
3162         # wait for a disconnect
3163         rep = self.recv_pdu()
3164         self.assertIsNone(rep)
3165         self.assertNotConnected()
3166
3167 if __name__ == "__main__":
3168     global_ndr_print = True
3169     global_hexdump = True
3170     import unittest
3171     unittest.main()