HEIMDAL: move code from source4/heimdal* to third_party/heimdal*
[samba.git] / third_party / heimdal / lib / ntlm / test_ntlm.c
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 static int dumpdata_flag;
45
46 static int
47 test_parse(void)
48 {
49     const char *user = "foo",
50         *domain = "mydomain",
51         *hostname = "myhostname",
52         *password = "digestpassword",
53         *target = "DOMAIN";
54     struct ntlm_type1 type1;
55     struct ntlm_type2 type2;
56     struct ntlm_type3 type3;
57     struct ntlm_buf data;
58     int ret, flags;
59
60     memset(&type1, 0, sizeof(type1));
61
62     type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|NTLM_NEG_VERSION;
63     type1.domain = rk_UNCONST(domain);
64     type1.hostname = rk_UNCONST(hostname);
65     type1.os[0] = 0;
66     type1.os[1] = 0;
67
68     ret = heim_ntlm_encode_type1(&type1, &data);
69     if (ret)
70         errx(1, "heim_ntlm_encode_type1");
71
72     memset(&type1, 0, sizeof(type1));
73
74     if (dumpdata_flag)
75         rk_dumpdata("ntlm-type1", data.data, data.length);
76
77     ret = heim_ntlm_decode_type1(&data, &type1);
78     free(data.data);
79     if (ret)
80         errx(1, "heim_ntlm_encode_type1");
81
82     if (strcmp(type1.domain, domain) != 0)
83         errx(1, "parser got domain wrong: %s", type1.domain);
84
85     if (strcmp(type1.hostname, hostname) != 0)
86         errx(1, "parser got hostname wrong: %s", type1.hostname);
87
88     heim_ntlm_free_type1(&type1);
89
90     /*
91      *
92      */
93
94     memset(&type2, 0, sizeof(type2));
95
96     flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN;
97     type2.flags = flags;
98
99     memset(type2.challenge, 0x7f, sizeof(type2.challenge));
100     type2.targetname = rk_UNCONST(target);
101     type2.targetinfo.data = NULL;
102     type2.targetinfo.length = 0;
103
104     ret = heim_ntlm_encode_type2(&type2, &data);
105     if (ret)
106         errx(1, "heim_ntlm_encode_type2");
107
108     memset(&type2, 0, sizeof(type2));
109
110     if (dumpdata_flag)
111         rk_dumpdata("ntlm-type2", data.data, data.length);
112
113     ret = heim_ntlm_decode_type2(&data, &type2);
114     free(data.data);
115     if (ret)
116         errx(1, "heim_ntlm_decode_type2");
117
118     heim_ntlm_free_type2(&type2);
119
120     /*
121      *
122      */
123
124     memset(&type3, 0, sizeof(type3));
125
126     type3.flags = flags;
127     type3.username = rk_UNCONST(user);
128     type3.targetname = rk_UNCONST(target);
129     type3.ws = rk_UNCONST("workstation");
130
131     {
132         struct ntlm_buf key;
133         heim_ntlm_nt_key(password, &key);
134
135         heim_ntlm_calculate_ntlm1(key.data, key.length,
136                                   type2.challenge,
137                                   &type3.ntlm);
138         free(key.data);
139     }
140
141     ret = heim_ntlm_encode_type3(&type3, &data, NULL);
142     if (ret)
143         errx(1, "heim_ntlm_encode_type3");
144
145     free(type3.ntlm.data);
146
147     memset(&type3, 0, sizeof(type3));
148
149     if (dumpdata_flag)
150         rk_dumpdata("ntlm-type3", data.data, data.length);
151
152     ret = heim_ntlm_decode_type3(&data, 1, &type3);
153     free(data.data);
154     if (ret)
155         errx(1, "heim_ntlm_decode_type3");
156
157     if (strcmp("workstation", type3.ws) != 0)
158         errx(1, "type3 ws wrong");
159
160     if (strcmp(target, type3.targetname) != 0)
161         errx(1, "type3 targetname wrong");
162
163     if (strcmp(user, type3.username) != 0)
164         errx(1, "type3 username wrong");
165
166
167     heim_ntlm_free_type3(&type3);
168
169     /*
170      * NTLMv2
171      */
172
173     memset(&type2, 0, sizeof(type2));
174
175     flags = NTLM_NEG_UNICODE | NTLM_NEG_NTLM | NTLM_TARGET_DOMAIN;
176     type2.flags = flags;
177
178     memset(type2.challenge, 0x7f, sizeof(type2.challenge));
179     type2.targetname = rk_UNCONST(target);
180     type2.targetinfo.data = "\x00\x00";
181     type2.targetinfo.length = 2;
182
183     ret = heim_ntlm_encode_type2(&type2, &data);
184     if (ret)
185         errx(1, "heim_ntlm_encode_type2");
186
187     memset(&type2, 0, sizeof(type2));
188
189     ret = heim_ntlm_decode_type2(&data, &type2);
190     free(data.data);
191     if (ret)
192         errx(1, "heim_ntlm_decode_type2");
193
194     heim_ntlm_free_type2(&type2);
195
196     return 0;
197 }
198
199 static int
200 test_keys(void)
201 {
202     const char
203         *username = "test",
204         *password = "test1234",
205         *target = "TESTNT";
206     const unsigned char
207         serverchallenge[8] = "\x67\x7f\x1c\x55\x7a\x5e\xe9\x6c";
208     struct ntlm_buf infotarget, infotarget2, answer, key;
209     unsigned char ntlmv2[16], ntlmv2_1[16];
210     int ret;
211
212     infotarget.length = 70;
213     infotarget.data =
214         "\x02\x00\x0c\x00\x54\x00\x45\x00\x53\x00\x54\x00\x4e\x00\x54\x00"
215         "\x01\x00\x0c\x00\x4d\x00\x45\x00\x4d\x00\x42\x00\x45\x00\x52\x00"
216         "\x03\x00\x1e\x00\x6d\x00\x65\x00\x6d\x00\x62\x00\x65\x00\x72\x00"
217             "\x2e\x00\x74\x00\x65\x00\x73\x00\x74\x00\x2e\x00\x63\x00\x6f"
218             "\x00\x6d\x00"
219         "\x00\x00\x00\x00";
220
221     answer.length = 0;
222     answer.data = NULL;
223
224     heim_ntlm_nt_key(password, &key);
225
226     ret = heim_ntlm_calculate_ntlm2(key.data,
227                                     key.length,
228                                     username,
229                                     target,
230                                     serverchallenge,
231                                     &infotarget,
232                                     ntlmv2,
233                                     &answer);
234     if (ret)
235         errx(1, "heim_ntlm_calculate_ntlm2");
236
237     ret = heim_ntlm_verify_ntlm2(key.data,
238                                  key.length,
239                                  username,
240                                  target,
241                                  0,
242                                  serverchallenge,
243                                  &answer,
244                                  &infotarget2,
245                                  ntlmv2_1);
246     if (ret)
247         errx(1, "heim_ntlm_verify_ntlm2");
248
249     if (memcmp(ntlmv2, ntlmv2_1, sizeof(ntlmv2)) != 0)
250         errx(1, "ntlm master key not same");
251
252     if (infotarget.length > infotarget2.length)
253         errx(1, "infotarget length");
254
255     if (memcmp(infotarget.data, infotarget2.data, infotarget.length) != 0)
256         errx(1, "infotarget not the same");
257
258     free(key.data);
259     free(answer.data);
260     free(infotarget2.data);
261
262     return 0;
263 }
264
265 static int
266 test_ntlm2_session_resp(void)
267 {
268     int ret;
269     struct ntlm_buf lm, ntlm;
270
271     const unsigned char lm_resp[24] =
272         "\xff\xff\xff\x00\x11\x22\x33\x44"
273         "\x00\x00\x00\x00\x00\x00\x00\x00"
274         "\x00\x00\x00\x00\x00\x00\x00\x00";
275     const unsigned char ntlm2_sess_resp[24] =
276         "\x10\xd5\x50\x83\x2d\x12\xb2\xcc"
277         "\xb7\x9d\x5a\xd1\xf4\xee\xd3\xdf"
278         "\x82\xac\xa4\xc3\x68\x1d\xd4\x55";
279
280     const unsigned char client_nonce[8] =
281         "\xff\xff\xff\x00\x11\x22\x33\x44";
282     const unsigned char server_challenge[8] =
283         "\x01\x23\x45\x67\x89\xab\xcd\xef";
284
285     const unsigned char ntlm_hash[16] =
286         "\xcd\x06\xca\x7c\x7e\x10\xc9\x9b"
287         "\x1d\x33\xb7\x48\x5a\x2e\xd8\x08";
288
289     ret = heim_ntlm_calculate_ntlm2_sess(client_nonce,
290                                          server_challenge,
291                                          ntlm_hash,
292                                          &lm,
293                                          &ntlm);
294     if (ret)
295         errx(1, "heim_ntlm_calculate_ntlm2_sess_resp");
296
297     if (lm.length != 24 || memcmp(lm.data, lm_resp, 24) != 0)
298         errx(1, "lm_resp wrong");
299     if (ntlm.length != 24 || memcmp(ntlm.data, ntlm2_sess_resp, 24) != 0)
300         errx(1, "ntlm2_sess_resp wrong");
301
302     free(lm.data);
303     free(ntlm.data);
304
305
306     return 0;
307 }
308
309 static int
310 test_ntlmv2(void)
311 {
312     unsigned char type3[413] = 
313         "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
314         "\x80\x00\x00\x00\x9e\x00\x9e\x00\x98\x00\x00\x00\x14\x00\x14\x00"
315         "\x48\x00\x00\x00\x10\x00\x10\x00\x5c\x00\x00\x00\x14\x00\x14\x00"
316         "\x6c\x00\x00\x00\x00\x00\x00\x00\x36\x01\x00\x00\x05\x82\x88\xa2"
317         "\x05\x01\x28\x0a\x00\x00\x00\x0f\x43\x00\x4f\x00\x4c\x00\x4c\x00"
318         "\x45\x00\x59\x00\x2d\x00\x58\x00\x50\x00\x34\x00\x54\x00\x45\x00"
319         "\x53\x00\x54\x00\x55\x00\x53\x00\x45\x00\x52\x00\x43\x00\x4f\x00"
320         "\x4c\x00\x4c\x00\x45\x00\x59\x00\x2d\x00\x58\x00\x50\x00\x34\x00"
321         "\x2f\x96\xec\x0a\xf7\x9f\x2e\x24\xba\x09\x48\x10\xa5\x22\xd4\xe1"
322         "\x16\x6a\xca\x58\x74\x9a\xc1\x4f\x54\x6f\xee\x40\x96\xce\x43\x6e"
323         "\xdf\x99\x20\x71\x6c\x9a\xda\x2a\x01\x01\x00\x00\x00\x00\x00\x00"
324         "\x8d\xc0\x57\xc9\x79\x5e\xcb\x01\x16\x6a\xca\x58\x74\x9a\xc1\x4f"
325         "\x00\x00\x00\x00\x02\x00\x14\x00\x4e\x00\x55\x00\x54\x00\x43\x00"
326         "\x52\x00\x41\x00\x43\x00\x4b\x00\x45\x00\x52\x00\x01\x00\x14\x00"
327         "\x4e\x00\x55\x00\x54\x00\x43\x00\x52\x00\x41\x00\x43\x00\x4b\x00"
328         "\x45\x00\x52\x00\x04\x00\x12\x00\x61\x00\x70\x00\x70\x00\x6c\x00"
329         "\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x03\x00\x20\x00\x68\x00"
330         "\x75\x00\x6d\x00\x6d\x00\x65\x00\x6c\x00\x2e\x00\x61\x00\x70\x00"
331         "\x70\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x00\x00"
332         "\x00\x00\x00\x00\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64\x00\x6f"
333         "\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32\x00\x20"
334         "\x00\x53\x00\x65\x00\x72\x00\x76\x00\x69\x00\x63\x00\x65\x00\x20"
335         "\x00\x50\x00\x61\x00\x63\x00\x6b\x00\x20\x00\x33\x00\x20\x00\x32"
336         "\x00\x36\x00\x30\x00\x30\x00\x00\x00\x57\x00\x69\x00\x6e\x00\x64"
337         "\x00\x6f\x00\x77\x00\x73\x00\x20\x00\x32\x00\x30\x00\x30\x00\x32"
338         "\x00\x20\x00\x35\x00\x2e\x00\x31\x00\x00\x00\x00\x00";
339     const unsigned char challenge[8] = 
340         "\xe4\x9c\x6a\x12\xe1\xbd\xde\x6a";
341     unsigned char sessionkey[16];
342
343     const char key[16] = "\xD1\x83\x98\x3E\xAE\xA7\xBE\x99\x59\xC8\xF4\xC1\x98\xED\x0E\x68";
344
345     struct ntlm_buf data;
346     struct ntlm_type3 t3;
347     int ret;
348
349     struct ntlm_targetinfo ti;
350
351     unsigned char timsg[114] = 
352         "\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";
353
354
355     data.data = type3;
356     data.length = sizeof(type3);
357
358     ret = heim_ntlm_decode_type3(&data, 1, &t3);
359     if (ret)
360         errx(1, "heim_ntlm_decode_type3");
361     
362     memset(&ti, 0, sizeof(ti));
363
364     data.data = timsg;
365     data.length = sizeof(timsg);
366
367     ret = heim_ntlm_decode_targetinfo(&data, 1, &ti);
368     if (ret)
369         return ret;
370
371     ret = heim_ntlm_verify_ntlm2(key, sizeof(key),
372                                  t3.username,
373                                  t3.targetname,
374                                  1285615547,
375                                  challenge,
376                                  &t3.ntlm,
377                                  &data,
378                                  sessionkey);
379     if (ret)
380         errx(1, "verify_ntlmv2");
381
382     if (sizeof(timsg) != data.length || memcmp(timsg, data.data, sizeof(timsg)) != 0)
383         errx(1, "target info wrong: %d != %d",
384              (int)sizeof(timsg), (int)data.length);
385
386     heim_ntlm_free_type3(&t3);
387     heim_ntlm_free_targetinfo(&ti);
388
389     return 0;
390 }
391
392 static int
393 test_targetinfo(void)
394 {
395     struct ntlm_targetinfo ti;
396     struct ntlm_buf buf;
397     const char *dnsservername = "dnsservername";
398     const char *targetname = "targetname";
399     const char z16[16] = { 0 };
400     int ret;
401
402     memset(&ti, 0, sizeof(ti));
403
404     ti.dnsservername = rk_UNCONST(dnsservername);
405     ti.avflags = 1;
406     ti.targetname = rk_UNCONST(targetname);
407     ti.channel_bindings.data = rk_UNCONST(z16);
408     ti.channel_bindings.length = sizeof(z16);
409
410     ret = heim_ntlm_encode_targetinfo(&ti, 1, &buf);
411     if (ret)
412         return ret;
413
414     memset(&ti, 0, sizeof(ti));
415
416     ret = heim_ntlm_decode_targetinfo(&buf, 1, &ti);
417     if (ret)
418         return ret;
419
420     if (ti.dnsservername == NULL ||
421         strcmp(ti.dnsservername, dnsservername) != 0)
422         errx(1, "ti.dnshostname != %s", dnsservername);
423     if (ti.avflags != 1)
424         errx(1, "ti.avflags != 1");
425     if (ti.targetname == NULL ||
426         strcmp(ti.targetname, targetname) != 0)
427         errx(1, "ti.targetname != %s", targetname);
428
429     if (ti.channel_bindings.length != sizeof(z16) ||
430         memcmp(ti.channel_bindings.data, z16, sizeof(z16)) != 0)
431         errx(1, "ti.channel_bindings != Z(16)");
432
433     heim_ntlm_free_targetinfo(&ti);
434
435     return 0;
436 }
437
438 static int
439 test_string2key(void)
440 {
441     const char *pw = "山田";
442     struct ntlm_buf buf;
443
444     unsigned char key[16] = {
445         0xc6, 0x5d, 0xc7, 0x61, 0xa1, 0x34, 0x17, 0xa1,
446         0x17, 0x08, 0x9c, 0x1b, 0xb0, 0x0d, 0x0f, 0x19
447     };
448
449     if (heim_ntlm_nt_key(pw, &buf) != 0)
450         errx(1, "heim_ntlmv_nt_key(jp)");
451
452     if (buf.length != 16 || memcmp(buf.data, key, 16) != 0)
453         errx(1, "compare failed");
454
455     heim_ntlm_free_buf(&buf);
456
457     return 0;
458 }
459
460 static int
461 test_jp(void)
462 {
463     char buf2[220] =
464         "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x06\x00\x06\x00"
465         "\x38\x00\x00\x00\x05\x02\x89\x62\x62\x94\xb1\xf3\x56\x80\xb0\xf9"
466         "\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x00\x9e\x00\x3e\x00\x00\x00"
467         "\x06\x01\xb0\x1d\x00\x00\x00\x0f\x43\x00\x4f\x00\x53\x00\x02\x00"
468         "\x06\x00\x43\x00\x4f\x00\x53\x00\x01\x00\x12\x00\x43\x00\x4f\x00"
469         "\x53\x00\x57\x00\x49\x00\x4e\x00\x37\x00\x4a\x00\x50\x00\x04\x00"
470         "\x1a\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00"
471         "\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x03\x00\x2e\x00"
472         "\x63\x00\x6f\x00\x73\x00\x77\x00\x69\x00\x6e\x00\x37\x00\x6a\x00"
473         "\x70\x00\x2e\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00"
474         "\x70\x00\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x05\x00"
475         "\x1a\x00\x63\x00\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00"
476         "\x6c\x00\x65\x00\x2e\x00\x63\x00\x6f\x00\x6d\x00\x07\x00\x08\x00"
477         "\x94\x51\xf0\xbd\xdc\x61\xcb\x01\x00\x00\x00\x00";
478
479     char buf3[362] =
480         "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
481         "\x74\x00\x00\x00\xce\x00\xce\x00\x8c\x00\x00\x00\x1a\x00\x1a\x00"
482         "\x40\x00\x00\x00\x04\x00\x04\x00\x5a\x00\x00\x00\x16\x00\x16\x00"
483         "\x5e\x00\x00\x00\x10\x00\x10\x00\x5a\x01\x00\x00\x05\x02\x89\x62"
484         "\x31\x00\x37\x00\x2e\x00\x32\x00\x30\x00\x31\x00\x2e\x00\x35\x00"
485         "\x37\x00\x2e\x00\x31\x00\x32\x00\x31\x00\x71\x5c\x30\x75\x77\x00"
486         "\x6f\x00\x72\x00\x6b\x00\x73\x00\x74\x00\x61\x00\x74\x00\x69\x00"
487         "\x6f\x00\x6e\x00\xab\xad\xeb\x72\x01\xd4\x5f\xdf\x59\x07\x5f\xa9"
488         "\xfd\x54\x98\x2d\xfa\x17\xbb\xf1\x3c\x8f\xf5\x20\xe6\x8f\xd7\x0a"
489         "\xc9\x19\x3e\x94\x61\x31\xdb\x0f\x55\xe8\xe2\x53\x01\x01\x00\x00"
490         "\x00\x00\x00\x00\x00\x06\x3e\x30\xe4\x61\xcb\x01\x71\x98\x10\x6b"
491         "\x4c\x82\xec\xb3\x00\x00\x00\x00\x02\x00\x06\x00\x43\x00\x4f\x00"
492         "\x53\x00\x01\x00\x12\x00\x43\x00\x4f\x00\x53\x00\x57\x00\x49\x00"
493         "\x4e\x00\x37\x00\x4a\x00\x50\x00\x04\x00\x1a\x00\x63\x00\x6f\x00"
494         "\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00\x2e\x00"
495         "\x63\x00\x6f\x00\x6d\x00\x03\x00\x2e\x00\x63\x00\x6f\x00\x73\x00"
496         "\x77\x00\x69\x00\x6e\x00\x37\x00\x6a\x00\x70\x00\x2e\x00\x63\x00"
497         "\x6f\x00\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00"
498         "\x2e\x00\x63\x00\x6f\x00\x6d\x00\x05\x00\x1a\x00\x63\x00\x6f\x00"
499         "\x73\x00\x2e\x00\x61\x00\x70\x00\x70\x00\x6c\x00\x65\x00\x2e\x00"
500         "\x63\x00\x6f\x00\x6d\x00\x07\x00\x08\x00\xab\xec\xcc\x30\xe4\x61"
501         "\xcb\x01\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x2e\xba\x3f\xd1\xb1"
502         "\xa7\x70\x00\x9d\x55\xa0\x59\x74\x2b\x78";
503
504
505     struct ntlm_type2 type2;
506     struct ntlm_type3 type3;
507     struct ntlm_buf data;
508     int ret;
509
510     data.length = sizeof(buf2);
511     data.data = buf2;
512
513     memset(&type2, 0, sizeof(type2));
514
515     ret = heim_ntlm_decode_type2(&data, &type2);
516     if (ret)
517         errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
518
519     data.data = NULL;
520     data.length = 0;
521
522     ret = heim_ntlm_encode_type2(&type2, &data);
523     if (ret)
524         errx(1, "heim_ntlm_encode_type2(jp): %d", ret);
525
526     heim_ntlm_free_type2(&type2);
527     heim_ntlm_free_buf(&data);
528
529     data.length = sizeof(buf3);
530     data.data = buf3;
531
532     memset(&type3, 0, sizeof(type3));
533
534     ret = heim_ntlm_decode_type3(&data, 1, &type3);
535     if (ret)
536         errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
537
538     data.data = NULL;
539     data.length = 0;
540
541     ret = heim_ntlm_encode_type3(&type3, &data, NULL);
542     if (ret)
543         errx(1, "heim_ntlm_decode_type2(jp): %d", ret);
544
545     heim_ntlm_free_type3(&type3);
546     heim_ntlm_free_buf(&data);
547
548     return 0;
549 }
550
551
552 static int verbose_flag = 0;
553 static int version_flag = 0;
554 static int help_flag    = 0;
555
556 static struct getargs args[] = {
557     {"verbose", 0,      arg_flag,       &verbose_flag, "verbose printing", NULL },
558     {"version", 0,      arg_flag,       &version_flag, "print version", NULL },
559     {"help",    0,      arg_flag,       &help_flag,  NULL, NULL }
560 };
561
562 static void
563 usage (int ret)
564 {
565     arg_printusage (args, sizeof(args)/sizeof(*args),
566                     NULL, "");
567     exit (ret);
568 }
569
570 int
571 main(int argc, char **argv)
572 {
573     int ret = 0, optidx = 0;
574
575     setprogname(argv[0]);
576
577     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
578         usage(1);
579
580     if (help_flag)
581         usage (0);
582
583     if(version_flag){
584         print_version(NULL);
585         exit(0);
586     }
587
588     if (verbose_flag)
589         printf("test_parse\n");
590     ret |= test_parse();
591
592     if (verbose_flag)
593         printf("test_keys\n");
594     ret |= test_keys();
595
596     if (verbose_flag)
597         printf("test_ntlm2_session_resp\n");
598     ret |= test_ntlm2_session_resp();
599
600     if (verbose_flag)
601         printf("test_targetinfo\n");
602     ret |= test_targetinfo();
603         
604     if (verbose_flag)
605         printf("test_ntlmv2\n");
606     ret |= test_ntlmv2();
607
608     if (verbose_flag)
609         printf("test_string2key\n");
610     ret |= test_string2key();
611
612     if (verbose_flag)
613         printf("test_jp\n");
614     ret |= test_jp();
615
616     return ret;
617 }