1/*
2 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of KTH nor the names of its contributors may be
18 *    used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <stdio.h>
37#include <err.h>
38#include <roken.h>
39#include <getarg.h>
40
41#include <krb5-types.h> /* or <inttypes.h> */
42#include <heimntlm.h>
43
44#ifdef ENABLE_NTLM
45
46static int
47test_parse(void)
48{
49    const char *user = "foo",
50	*domain = "mydomain",
51	*password = "digestpassword",
52	*target = "DOMAIN";
53    struct ntlm_type1 type1;
54    struct ntlm_type2 type2;
55    struct ntlm_type3 type3;
56    struct ntlm_buf data;
57    int ret, flags;
58
59    memset(&type1, 0, sizeof(type1));
60
61    type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|NTLM_NEG_VERSION;
62    type1.domain = rk_UNCONST(domain);
63    type1.hostname = NULL;
64    type1.os[0] = 0;
65    type1.os[1] = 0;
66
67    ret = heim_ntlm_encode_type1(&type1, &data);
68    if (ret)
69	errx(1, "heim_ntlm_encode_type1");
70
71    memset(&type1, 0, sizeof(type1));
72
73    ret = heim_ntlm_decode_type1(&data, &type1);
74    free(data.data);
75    if (ret)
76	errx(1, "heim_ntlm_encode_type1");
77
78    heim_ntlm_free_type1(&type1);
79
80    /*
81     *
82     */
83
84    memset(&type2, 0, sizeof(type2));
85
86    flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN;
87    type2.flags = flags;
88
89    memset(type2.challenge, 0x7f, sizeof(type2.challenge));
90    type2.targetname = rk_UNCONST(target);
91    type2.targetinfo.data = NULL;
92    type2.targetinfo.length = 0;
93
94    ret = heim_ntlm_encode_type2(&type2, &data);
95    if (ret)
96	errx(1, "heim_ntlm_encode_type2");
97
98    memset(&type2, 0, sizeof(type2));
99
100    ret = heim_ntlm_decode_type2(&data, &type2);
101    free(data.data);
102    if (ret)
103	errx(1, "heim_ntlm_decode_type2");
104
105    heim_ntlm_free_type2(&type2);
106
107    /*
108     *
109     */
110
111    memset(&type3, 0, sizeof(type3));
112
113    type3.flags = flags;
114    type3.username = rk_UNCONST(user);
115    type3.targetname = rk_UNCONST(target);
116    type3.ws = rk_UNCONST("workstation");
117
118    {
119	struct ntlm_buf key;
120	heim_ntlm_nt_key(password, &key);
121
122	heim_ntlm_calculate_ntlm1(key.data, key.length,
123				  type2.challenge,
124				  &type3.ntlm);
125	free(key.data);
126    }
127
128    ret = heim_ntlm_encode_type3(&type3, &data, NULL);
129    if (ret)
130	errx(1, "heim_ntlm_encode_type3");
131
132    free(type3.ntlm.data);
133
134    memset(&type3, 0, sizeof(type3));
135
136    ret = heim_ntlm_decode_type3(&data, 1, &type3);
137    free(data.data);
138    if (ret)
139	errx(1, "heim_ntlm_decode_type3");
140
141    if (strcmp("workstation", type3.ws) != 0)
142	errx(1, "type3 ws wrong");
143
144    if (strcmp(target, type3.targetname) != 0)
145	errx(1, "type3 targetname wrong");
146
147    if (strcmp(user, type3.username) != 0)
148	errx(1, "type3 username wrong");
149
150
151    heim_ntlm_free_type3(&type3);
152
153    /*
154     * NTLMv2
155     */
156
157    memset(&type2, 0, sizeof(type2));
158
159    flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN;
160    type2.flags = flags;
161
162    memset(type2.challenge, 0x7f, sizeof(type2.challenge));
163    type2.targetname = rk_UNCONST(target);
164    type2.targetinfo.data = "\x00\x00";
165    type2.targetinfo.length = 2;
166
167    ret = heim_ntlm_encode_type2(&type2, &data);
168    if (ret)
169	errx(1, "heim_ntlm_encode_type2");
170
171    memset(&type2, 0, sizeof(type2));
172
173    ret = heim_ntlm_decode_type2(&data, &type2);
174    free(data.data);
175    if (ret)
176	errx(1, "heim_ntlm_decode_type2");
177
178    heim_ntlm_free_type2(&type2);
179
180    return 0;
181}
182
183static int
184test_keys(void)
185{
186    const char
187	*username = "test",
188	*password = "test1234",
189	*target = "TESTNT";
190    const unsigned char
191	serverchallenge[8] = "\x67\x7f\x1c\x55\x7a\x5e\xe9\x6c";
192    struct ntlm_buf infotarget, infotarget2, answer, key;
193    unsigned char ntlmv2[16], ntlmv2_1[16];
194    int ret;
195
196    infotarget.length = 70;
197    infotarget.data =
198	"\x02\x00\x0c\x00\x54\x00\x45\x00\x53\x00\x54\x00\x4e\x00\x54\x00"
199	"\x01\x00\x0c\x00\x4d\x00\x45\x00\x4d\x00\x42\x00\x45\x00\x52\x00"
200	"\x03\x00\x1e\x00\x6d\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00"
201	    "\x2e\x00\x74\x00\x65\x00\x73\x00\x74\x00\x2e\x00\x63\x00\x6f"
202	    "\x00\x6d\x00"
203	"\x00\x00\x00\x00";
204
205    answer.length = 0;
206    answer.data = NULL;
207
208    heim_ntlm_nt_key(password, &key);
209
210    ret = heim_ntlm_calculate_ntlm2(key.data,
211				    key.length,
212				    username,
213				    target,
214				    serverchallenge,
215				    &infotarget,
216				    ntlmv2,
217				    &answer);
218    if (ret)
219	errx(1, "heim_ntlm_calculate_ntlm2");
220
221    ret = heim_ntlm_verify_ntlm2(key.data,
222				 key.length,
223				 username,
224				 target,
225				 0,
226				 serverchallenge,
227				 &answer,
228				 &infotarget2,
229				 ntlmv2_1);
230    if (ret)
231	errx(1, "heim_ntlm_verify_ntlm2");
232
233    if (memcmp(ntlmv2, ntlmv2_1, sizeof(ntlmv2)) != 0)
234	errx(1, "ntlm master key not same");
235
236    if (infotarget.length > infotarget2.length)
237	errx(1, "infotarget length");
238
239    if (memcmp(infotarget.data, infotarget2.data, infotarget.length) != 0)
240	errx(1, "infotarget not the same");
241
242    free(key.data);
243    free(answer.data);
244    free(infotarget2.data);
245
246    return 0;
247}
248
249static int
250test_ntlm2_session_resp(void)
251{
252    int ret;
253    struct ntlm_buf lm, ntlm;
254
255    const unsigned char lm_resp[24] =
256	"\xff\xff\xff\x00\x11\x22\x33\x44"
257	"\x00\x00\x00\x00\x00\x00\x00\x00"
258	"\x00\x00\x00\x00\x00\x00\x00\x00";
259    const unsigned char ntlm2_sess_resp[24] =
260	"\x10\xd5\x50\x83\x2d\x12\xb2\xcc"
261	"\xb7\x9d\x5a\xd1\xf4\xee\xd3\xdf"
262	"\x82\xac\xa4\xc3\x68\x1d\xd4\x55";
263
264    const unsigned char client_nonce[8] =
265	"\xff\xff\xff\x00\x11\x22\x33\x44";
266    const unsigned char server_challenge[8] =
267	"\x01\x23\x45\x67\x89\xab\xcd\xef";
268
269    const unsigned char ntlm_hash[16] =
270	"\xcd\x06\xca\x7c\x7e\x10\xc9\x9b"
271	"\x1d\x33\xb7\x48\x5a\x2e\xd8\x08";
272
273    ret = heim_ntlm_calculate_ntlm2_sess(client_nonce,
274					 server_challenge,
275					 ntlm_hash,
276					 &lm,
277					 &ntlm);
278    if (ret)
279	errx(1, "heim_ntlm_calculate_ntlm2_sess_resp");
280
281    if (lm.length != 24 || memcmp(lm.data, lm_resp, 24) != 0)
282	errx(1, "lm_resp wrong");
283    if (ntlm.length != 24 || memcmp(ntlm.data, ntlm2_sess_resp, 24) != 0)
284	errx(1, "ntlm2_sess_resp wrong");
285
286    free(lm.data);
287    free(ntlm.data);
288
289
290    return 0;
291}
292
293static int
294test_ntlmv2(void)
295{
296    unsigned char type3[413] =
297	"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
298	"\x80\x00\x00\x00\x9e\x00\x9e\x00\x98\x00\x00\x00\x14\x00\x14\x00"
299	"\x48\x00\x00\x00\x10\x00\x10\x00\x5c\x00\x00\x00\x14\x00\x14\x00"
300	"\x6c\x00\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00\x05\x82\x88\xa2"
301	"\x05\x01\x28\x0a\x00\x00\x00\x0f\x43\x00\x4f\x00\x4c\x00\x4c\x00"
302	"\x45\x00\x59\x00\x2d\x00\x58\x00\x50\x00\x34\x00\x54\x00\x45\x00"
303	"\x53\x00\x54\x00\x55\x00\x53\x00\x45\x00\x52\x00\x43\x00\x4f\x00"
304	"\x4c\x00\x4c\x00\x45\x00\x59\x00\x2d\x00\x58\x00\x50\x00\x34\x00"
305	"\x2f\x96\xec\x0a\xf7\x9f\x2e\x24\xba\x09\x48\x10\xa5\x22\xd4\xe1"
306	"\x16\x6a\xca\x58\x74\x9a\xc1\x4f\x54\x6f\xee\x40\x96\xce\x43\x6e"
307	"\xdf\x99\x20\x71\x6c\x9a\xda\x2a\x01\x01\x00\x00\x00\x00\x00\x00"
308	"\x8d\xc0\x57\xc9\x79\x5e\xcb\x01\x16\x6a\xca\x58\x74\x9a\xc1\x4f"
309	"\x00\x00\x00\x00\x02\x00\x14\x00\x4e\x00\x55\x00\x54\x00\x43\x00"
310	"\x52\x00\x41\x00\x43\x00\x4b\x00\x45\x00\x52\x00\x01\x00\x14\x00"
311	"\x4e\x00\x55\x00\x54\x00\x43\x00\x52\x00\x41\x00\x43\x00\x4b\x00"
312	"\x45\x00\x52\x00\x04\x00\x12\x00\x61\x00\x70\x00\x70\x00\x6c\x00"
313	"\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x03\x00\x20\x00\x68\x00"
314	"\x75\x00\x6d\x00\x6d\x00\x65\x00\x6c\x00\x2e\x00\x61\x00\x70\x00"
315	"\x70\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x00\x00"
316	"\x00\x00\x00\x00\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f"
317	"\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20"
318	"\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20"
319	"\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32"
320	"\x00\x36\x00\x30\x00\x30\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64"
321	"\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32"
322	"\x00\x20\x00\x35\x00\x2e\x00\x31\x00\x00\x00\x00\x00";
323    const unsigned char challenge[8] =
324	"\xe4\x9c\x6a\x12\xe1\xbd\xde\x6a";
325    unsigned char sessionkey[16];
326
327    const char key[16] = "\xD1\x83\x98\x3E\xAE\xA7\xBE\x99\x59\xC8\xF4\xC1\x98\xED\x0E\x68";
328
329    struct ntlm_buf data;
330    struct ntlm_type3 t3;
331    int ret;
332
333    struct ntlm_targetinfo ti;
334
335    unsigned char timsg[114] =
336	"\002\000\024\000N\000U\000T\000C\000R\000A\000C\000K\000E\000R\000\001\000\024\000N\000U\000T\000C\000R\000A\000C\000K\000E\000R\000\004\000\022\000a\000p\000p\000l\000e\000.\000c\000o\000m\000\003\000 \000h\000u\000m\000m\000e\000l\000.\000a\000p\000p\000l\000e\000.\000c\000o\000m\000\000\000\000\000\000\000\000";
337
338
339    data.data = type3;
340    data.length = sizeof(type3);
341
342    ret = heim_ntlm_decode_type3(&data, 1, &t3);
343    if (ret)
344	errx(1, "heim_ntlm_decode_type3");
345
346    memset(&ti, 0, sizeof(ti));
347
348    data.data = timsg;
349    data.length = sizeof(timsg);
350
351    ret = heim_ntlm_decode_targetinfo(&data, 1, &ti);
352    if (ret)
353	return ret;
354
355    ret = heim_ntlm_verify_ntlm2(key, sizeof(key),
356				 t3.username,
357				 t3.targetname,
358				 1285615547,
359				 challenge,
360				 &t3.ntlm,
361				 &data,
362				 sessionkey);
363    if (ret)
364	errx(1, "verify_ntlmv2");
365
366    if (sizeof(timsg) != data.length || memcmp(timsg, data.data, sizeof(timsg)) != 0)
367	errx(1, "target info wrong: %d != %d",
368	     (int)sizeof(timsg), (int)data.length);
369
370    heim_ntlm_free_type3(&t3);
371    heim_ntlm_free_targetinfo(&ti);
372
373    return 0;
374}
375
376static int
377test_targetinfo(void)
378{
379    struct ntlm_targetinfo ti;
380    struct ntlm_buf buf;
381    const char *dnsservername = "dnsservername";
382    const char *targetname = "targetname";
383    const char z16[16] = { 0 };
384    int ret;
385
386    memset(&ti, 0, sizeof(ti));
387
388    ti.dnsservername = rk_UNCONST(dnsservername);
389    ti.avflags = 1;
390    ti.targetname = rk_UNCONST(targetname);
391    ti.channel_bindings.data = rk_UNCONST(z16);
392    ti.channel_bindings.length = sizeof(z16);
393
394    ret = heim_ntlm_encode_targetinfo(&ti, 1, &buf);
395    if (ret)
396	return ret;
397
398    memset(&ti, 0, sizeof(ti));
399
400    ret = heim_ntlm_decode_targetinfo(&buf, 1, &ti);
401    if (ret)
402	return ret;
403
404    if (ti.dnsservername == NULL ||
405	strcmp(ti.dnsservername, dnsservername) != 0)
406	errx(1, "ti.dnshostname != %s", dnsservername);
407    if (ti.avflags != 1)
408	errx(1, "ti.avflags != 1");
409    if (ti.targetname == NULL ||
410	strcmp(ti.targetname, targetname) != 0)
411	errx(1, "ti.targetname != %s", targetname);
412
413    if (ti.channel_bindings.length != sizeof(z16) ||
414	memcmp(ti.channel_bindings.data, z16, sizeof(z16)) != 0)
415	errx(1, "ti.channel_bindings != Z(16)");
416
417    heim_ntlm_free_targetinfo(&ti);
418
419    return 0;
420}
421
422static int
423test_string2key(void)
424{
425    const char *pw = "山田";
426    struct ntlm_buf buf;
427
428    unsigned char key[16] = {
429	0xc6, 0x5d, 0xc7, 0x61, 0xa1, 0x34, 0x17, 0xa1,
430	0x17, 0x08, 0x9c, 0x1b, 0xb0, 0x0d, 0x0f, 0x19
431    };
432
433    if (heim_ntlm_nt_key(pw, &buf) != 0)
434	errx(1, "heim_ntlmv_nt_key(jp)");
435
436    if (buf.length != 16 || memcmp(buf.data, key, 16) != 0)
437	errx(1, "compare failed");
438
439    heim_ntlm_free_buf(&buf);
440
441    return 0;
442}
443
444static int
445test_jp(void)
446{
447    char buf2[220] =
448	"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x06\x00\x06\x00"
449	"\x38\x00\x00\x00\x05\x02\x89\x62\x62\x94\xb1\xf3\x56\x80\xb0\xf9"
450	"\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x00\x9e\x00\x3e\x00\x00\x00"
451	"\x06\x01\xb0\x1d\x00\x00\x00\x0f\x43\x00\x4f\x00\x53\x00\x02\x00"
452	"\x06\x00\x43\x00\x4f\x00\x53\x00\x01\x00\x12\x00\x43\x00\x4f\x00"
453	"\x53\x00\x57\x00\x49\x00\x4e\x00\x37\x00\x4a\x00\x50\x00\x04\x00"
454	"\x1a\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00"
455	"\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x03\x00\x2e\x00"
456	"\x63\x00\x6f\x00\x73\x00\x77\x00\x69\x00\x6e\x00\x37\x00\x6a\x00"
457	"\x70\x00\x2e\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00"
458	"\x70\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x05\x00"
459	"\x1a\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00"
460	"\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x07\x00\x08\x00"
461	"\x94\x51\xf0\xbd\xdc\x61\xcb\x01\x00\x00\x00\x00";
462
463    char buf3[362] =
464	"\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
465	"\x74\x00\x00\x00\xce\x00\xce\x00\x8c\x00\x00\x00\x1a\x00\x1a\x00"
466	"\x40\x00\x00\x00\x04\x00\x04\x00\x5a\x00\x00\x00\x16\x00\x16\x00"
467	"\x5e\x00\x00\x00\x10\x00\x10\x00\x5a\x01\x00\x00\x05\x02\x89\x62"
468	"\x31\x00\x37\x00\x2e\x00\x32\x00\x30\x00\x31\x00\x2e\x00\x35\x00"
469	"\x37\x00\x2e\x00\x31\x00\x32\x00\x31\x00\x71\x5c\x30\x75\x77\x00"
470	"\x6f\x00\x72\x00\x6b\x00\x73\x00\x74\x00\x61\x00\x74\x00\x69\x00"
471	"\x6f\x00\x6e\x00\xab\xad\xeb\x72\x01\xd4\x5f\xdf\x59\x07\x5f\xa9"
472	"\xfd\x54\x98\x2d\xfa\x17\xbb\xf1\x3c\x8f\xf5\x20\xe6\x8f\xd7\x0a"
473	"\xc9\x19\x3e\x94\x61\x31\xdb\x0f\x55\xe8\xe2\x53\x01\x01\x00\x00"
474	"\x00\x00\x00\x00\x00\x06\x3e\x30\xe4\x61\xcb\x01\x71\x98\x10\x6b"
475	"\x4c\x82\xec\xb3\x00\x00\x00\x00\x02\x00\x06\x00\x43\x00\x4f\x00"
476	"\x53\x00\x01\x00\x12\x00\x43\x00\x4f\x00\x53\x00\x57\x00\x49\x00"
477	"\x4e\x00\x37\x00\x4a\x00\x50\x00\x04\x00\x1a\x00\x63\x00\x6f\x00"
478	"\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00\x2e\x00"
479	"\x63\x00\x6f\x00\x6d\x00\x03\x00\x2e\x00\x63\x00\x6f\x00\x73\x00"
480	"\x77\x00\x69\x00\x6e\x00\x37\x00\x6a\x00\x70\x00\x2e\x00\x63\x00"
481	"\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00"
482	"\x2e\x00\x63\x00\x6f\x00\x6d\x00\x05\x00\x1a\x00\x63\x00\x6f\x00"
483	"\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00\x2e\x00"
484	"\x63\x00\x6f\x00\x6d\x00\x07\x00\x08\x00\xab\xec\xcc\x30\xe4\x61"
485	"\xcb\x01\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x2e\xba\x3f\xd1\xb1"
486	"\xa7\x70\x00\x9d\x55\xa0\x59\x74\x2b\x78";
487
488
489    struct ntlm_type2 type2;
490    struct ntlm_type3 type3;
491    struct ntlm_buf data;
492    int ret;
493
494    data.length = sizeof(buf2);
495    data.data = buf2;
496
497    memset(&type2, 0, sizeof(type2));
498
499    ret = heim_ntlm_decode_type2(&data, &type2);
500    if (ret)
501	errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
502
503    data.data = NULL;
504    data.length = 0;
505
506    ret = heim_ntlm_encode_type2(&type2, &data);
507    if (ret)
508	errx(1, "heim_ntlm_encode_type2(jp): %d", ret);
509
510    heim_ntlm_free_type2(&type2);
511    heim_ntlm_free_buf(&data);
512
513    data.length = sizeof(buf3);
514    data.data = buf3;
515
516    memset(&type3, 0, sizeof(type3));
517
518    ret = heim_ntlm_decode_type3(&data, 1, &type3);
519    if (ret)
520	errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
521
522    data.data = NULL;
523    data.length = 0;
524
525    ret = heim_ntlm_encode_type3(&type3, &data, NULL);
526    if (ret)
527	errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
528
529    heim_ntlm_free_type3(&type3);
530    heim_ntlm_free_buf(&data);
531
532    return 0;
533}
534
535static int
536test_mppe(void)
537{
538    const char *password = "clientPass";
539    const uint8_t ntlmresponse[24] = {
540	0x82, 0x30, 0x9e, 0xcd, 0x8d, 0x70, 0x8b, 0x5e, 0xa0, 0x8f, 0xaa, 0x39, 0x81, 0xcd, 0x83, 0x54, 0x42, 0x33,
541	0x11, 0x4a, 0x3d, 0x85, 0xd6, 0xdf
542    };
543    const uint8_t sendkey_orig[16] = {
544	0x8B, 0x7C, 0xDC, 0x14, 0x9B, 0x99, 0x3A, 0x1B, 0xA1, 0x18, 0xCB, 0x15, 0x3F, 0x56, 0xDC, 0xCB
545    };
546    struct ntlm_buf pwbuf;
547    uint8_t sendkey[16], recvkey[16];
548
549    heim_ntlm_nt_key(password, &pwbuf);
550
551    heim_ntlm_mppe_getsessionkey(pwbuf.data, ntlmresponse, 1, 16, sendkey, recvkey);
552    heim_ntlm_free_buf(&pwbuf);
553
554    if (memcmp(sendkey, sendkey_orig, 16) != 0) {
555	warn("mppe: send key wrong");
556	return 1;
557    }
558
559    return 0;
560}
561
562#endif
563
564static int verbose_flag = 0;
565static int version_flag = 0;
566static int help_flag	= 0;
567
568static struct getargs args[] = {
569    {"verbose",	0,	arg_flag,	&verbose_flag, "verbose printing", NULL },
570    {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
571    {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
572};
573
574static void
575usage (int ret)
576{
577    arg_printusage (args, sizeof(args)/sizeof(*args),
578		    NULL, "");
579    exit (ret);
580}
581
582int
583main(int argc, char **argv)
584{
585    int ret = 0, optidx = 0;
586
587    setprogname(argv[0]);
588
589    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
590	usage(1);
591
592    if (help_flag)
593	usage (0);
594
595    if(version_flag){
596	print_version(NULL);
597	exit(0);
598    }
599
600#ifdef ENABLE_NTLM
601
602    if (verbose_flag)
603	printf("test_parse\n");
604    ret += test_parse();
605
606    if (verbose_flag)
607	printf("test_keys\n");
608    ret += test_keys();
609
610    if (verbose_flag)
611	printf("test_ntlm2_session_resp\n");
612    ret += test_ntlm2_session_resp();
613
614    if (verbose_flag)
615	printf("test_targetinfo\n");
616    ret += test_targetinfo();
617
618    if (verbose_flag)
619	printf("test_ntlmv2\n");
620    ret += test_ntlmv2();
621
622    if (verbose_flag)
623	printf("test_string2key\n");
624    ret += test_string2key();
625
626    if (verbose_flag)
627	printf("test_jp\n");
628    ret += test_jp();
629
630    if (verbose_flag)
631	printf("test_mppe\n");
632    ret += test_mppe();
633
634#endif
635    return ret;
636}
637