xref: /freebsd/crypto/heimdal/lib/gssapi/test_ntlm.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
1c19800e8SDoug Rabson /*
2*ae771770SStanislav Sedov  * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson  * are met:
9c19800e8SDoug Rabson  *
10c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson  *
13c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson  *
17c19800e8SDoug Rabson  * 3. Neither the name of KTH nor the names of its contributors may be
18c19800e8SDoug Rabson  *    used to endorse or promote products derived from this software without
19c19800e8SDoug Rabson  *    specific prior written permission.
20c19800e8SDoug Rabson  *
21c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22c19800e8SDoug Rabson  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24c19800e8SDoug Rabson  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25c19800e8SDoug Rabson  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26c19800e8SDoug Rabson  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27c19800e8SDoug Rabson  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28c19800e8SDoug Rabson  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29c19800e8SDoug Rabson  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30c19800e8SDoug Rabson  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31c19800e8SDoug Rabson  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33c19800e8SDoug Rabson 
34c19800e8SDoug Rabson #include "config.h"
35c19800e8SDoug Rabson 
36*ae771770SStanislav Sedov #include <roken.h>
37c19800e8SDoug Rabson #include <stdio.h>
38c19800e8SDoug Rabson #include <gssapi.h>
39c19800e8SDoug Rabson #include <err.h>
40c19800e8SDoug Rabson #include <getarg.h>
41c19800e8SDoug Rabson #include "test_common.h"
42c19800e8SDoug Rabson 
43c19800e8SDoug Rabson #include <krb5.h>
44c19800e8SDoug Rabson #include <heimntlm.h>
45c19800e8SDoug Rabson 
46c19800e8SDoug Rabson static int
test_libntlm_v1(int flags)47c19800e8SDoug Rabson test_libntlm_v1(int flags)
48c19800e8SDoug Rabson {
49c19800e8SDoug Rabson     const char *user = "foo",
50c19800e8SDoug Rabson 	*domain = "mydomain",
51c19800e8SDoug Rabson 	*password = "digestpassword";
52c19800e8SDoug Rabson     OM_uint32 maj_stat, min_stat;
53c19800e8SDoug Rabson     gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
54c19800e8SDoug Rabson     gss_buffer_desc input, output;
55c19800e8SDoug Rabson     struct ntlm_type1 type1;
56c19800e8SDoug Rabson     struct ntlm_type2 type2;
57c19800e8SDoug Rabson     struct ntlm_type3 type3;
58c19800e8SDoug Rabson     struct ntlm_buf data;
59c19800e8SDoug Rabson     krb5_error_code ret;
60c19800e8SDoug Rabson     gss_name_t src_name = GSS_C_NO_NAME;
61c19800e8SDoug Rabson 
62c19800e8SDoug Rabson     memset(&type1, 0, sizeof(type1));
63c19800e8SDoug Rabson     memset(&type2, 0, sizeof(type2));
64c19800e8SDoug Rabson     memset(&type3, 0, sizeof(type3));
65c19800e8SDoug Rabson 
66c19800e8SDoug Rabson     type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|flags;
67c19800e8SDoug Rabson     type1.domain = strdup(domain);
68c19800e8SDoug Rabson     type1.hostname = NULL;
69c19800e8SDoug Rabson     type1.os[0] = 0;
70c19800e8SDoug Rabson     type1.os[1] = 0;
71c19800e8SDoug Rabson 
72c19800e8SDoug Rabson     ret = heim_ntlm_encode_type1(&type1, &data);
73c19800e8SDoug Rabson     if (ret)
74c19800e8SDoug Rabson 	errx(1, "heim_ntlm_encode_type1");
75c19800e8SDoug Rabson 
76c19800e8SDoug Rabson     input.value = data.data;
77c19800e8SDoug Rabson     input.length = data.length;
78c19800e8SDoug Rabson 
79c19800e8SDoug Rabson     output.length = 0;
80c19800e8SDoug Rabson     output.value = NULL;
81c19800e8SDoug Rabson 
82c19800e8SDoug Rabson     maj_stat = gss_accept_sec_context(&min_stat,
83c19800e8SDoug Rabson 				      &ctx,
84c19800e8SDoug Rabson 				      GSS_C_NO_CREDENTIAL,
85c19800e8SDoug Rabson 				      &input,
86c19800e8SDoug Rabson 				      GSS_C_NO_CHANNEL_BINDINGS,
87c19800e8SDoug Rabson 				      NULL,
88c19800e8SDoug Rabson 				      NULL,
89c19800e8SDoug Rabson 				      &output,
90c19800e8SDoug Rabson 				      NULL,
91c19800e8SDoug Rabson 				      NULL,
92c19800e8SDoug Rabson 				      NULL);
93c19800e8SDoug Rabson     free(data.data);
94c19800e8SDoug Rabson     if (GSS_ERROR(maj_stat))
95c19800e8SDoug Rabson 	errx(1, "accept_sec_context v1: %s",
96c19800e8SDoug Rabson 	     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
97c19800e8SDoug Rabson 
98c19800e8SDoug Rabson     if (output.length == 0)
99c19800e8SDoug Rabson 	errx(1, "output.length == 0");
100c19800e8SDoug Rabson 
101c19800e8SDoug Rabson     data.data = output.value;
102c19800e8SDoug Rabson     data.length = output.length;
103c19800e8SDoug Rabson 
104c19800e8SDoug Rabson     ret = heim_ntlm_decode_type2(&data, &type2);
105c19800e8SDoug Rabson     if (ret)
106c19800e8SDoug Rabson 	errx(1, "heim_ntlm_decode_type2");
107c19800e8SDoug Rabson 
108c19800e8SDoug Rabson     gss_release_buffer(&min_stat, &output);
109c19800e8SDoug Rabson 
110c19800e8SDoug Rabson     type3.flags = type2.flags;
111c19800e8SDoug Rabson     type3.username = rk_UNCONST(user);
112c19800e8SDoug Rabson     type3.targetname = type2.targetname;
113c19800e8SDoug Rabson     type3.ws = rk_UNCONST("workstation");
114c19800e8SDoug Rabson 
115c19800e8SDoug Rabson     {
116c19800e8SDoug Rabson 	struct ntlm_buf key;
117c19800e8SDoug Rabson 
118c19800e8SDoug Rabson 	heim_ntlm_nt_key(password, &key);
119c19800e8SDoug Rabson 
120c19800e8SDoug Rabson 	heim_ntlm_calculate_ntlm1(key.data, key.length,
121*ae771770SStanislav Sedov 				  type2.challenge,
122c19800e8SDoug Rabson 				  &type3.ntlm);
123c19800e8SDoug Rabson 
124c19800e8SDoug Rabson 	if (flags & NTLM_NEG_KEYEX) {
125c19800e8SDoug Rabson 	    struct ntlm_buf sessionkey;
126c19800e8SDoug Rabson 	    heim_ntlm_build_ntlm1_master(key.data, key.length,
127c19800e8SDoug Rabson 					 &sessionkey,
128c19800e8SDoug Rabson 				     &type3.sessionkey);
129c19800e8SDoug Rabson 	    free(sessionkey.data);
130c19800e8SDoug Rabson 	}
131c19800e8SDoug Rabson 	free(key.data);
132c19800e8SDoug Rabson     }
133c19800e8SDoug Rabson 
134c19800e8SDoug Rabson     ret = heim_ntlm_encode_type3(&type3, &data);
135c19800e8SDoug Rabson     if (ret)
136c19800e8SDoug Rabson 	errx(1, "heim_ntlm_encode_type3");
137c19800e8SDoug Rabson 
138c19800e8SDoug Rabson     input.length = data.length;
139c19800e8SDoug Rabson     input.value = data.data;
140c19800e8SDoug Rabson 
141c19800e8SDoug Rabson     maj_stat = gss_accept_sec_context(&min_stat,
142c19800e8SDoug Rabson 				      &ctx,
143c19800e8SDoug Rabson 				      GSS_C_NO_CREDENTIAL,
144c19800e8SDoug Rabson 				      &input,
145c19800e8SDoug Rabson 				      GSS_C_NO_CHANNEL_BINDINGS,
146c19800e8SDoug Rabson 				      &src_name,
147c19800e8SDoug Rabson 				      NULL,
148c19800e8SDoug Rabson 				      &output,
149c19800e8SDoug Rabson 				      NULL,
150c19800e8SDoug Rabson 				      NULL,
151c19800e8SDoug Rabson 				      NULL);
152c19800e8SDoug Rabson     free(input.value);
153c19800e8SDoug Rabson     if (maj_stat != GSS_S_COMPLETE)
154c19800e8SDoug Rabson 	errx(1, "accept_sec_context v1 2 %s",
155c19800e8SDoug Rabson 	     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
156c19800e8SDoug Rabson 
157c19800e8SDoug Rabson     gss_release_buffer(&min_stat, &output);
158c19800e8SDoug Rabson     gss_delete_sec_context(&min_stat, &ctx, NULL);
159c19800e8SDoug Rabson 
160c19800e8SDoug Rabson     if (src_name == GSS_C_NO_NAME)
161c19800e8SDoug Rabson 	errx(1, "no source name!");
162c19800e8SDoug Rabson 
163c19800e8SDoug Rabson     gss_display_name(&min_stat, src_name, &output, NULL);
164c19800e8SDoug Rabson 
165c19800e8SDoug Rabson     printf("src_name: %.*s\n", (int)output.length, (char*)output.value);
166c19800e8SDoug Rabson 
167c19800e8SDoug Rabson     gss_release_name(&min_stat, &src_name);
168c19800e8SDoug Rabson     gss_release_buffer(&min_stat, &output);
169c19800e8SDoug Rabson 
170c19800e8SDoug Rabson     return 0;
171c19800e8SDoug Rabson }
172c19800e8SDoug Rabson 
173c19800e8SDoug Rabson static int
test_libntlm_v2(int flags)174c19800e8SDoug Rabson test_libntlm_v2(int flags)
175c19800e8SDoug Rabson {
176c19800e8SDoug Rabson     const char *user = "foo",
177c19800e8SDoug Rabson 	*domain = "mydomain",
178c19800e8SDoug Rabson 	*password = "digestpassword";
179c19800e8SDoug Rabson     OM_uint32 maj_stat, min_stat;
180c19800e8SDoug Rabson     gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
181c19800e8SDoug Rabson     gss_buffer_desc input, output;
182c19800e8SDoug Rabson     struct ntlm_type1 type1;
183c19800e8SDoug Rabson     struct ntlm_type2 type2;
184c19800e8SDoug Rabson     struct ntlm_type3 type3;
185c19800e8SDoug Rabson     struct ntlm_buf data;
186c19800e8SDoug Rabson     krb5_error_code ret;
187c19800e8SDoug Rabson 
188c19800e8SDoug Rabson     memset(&type1, 0, sizeof(type1));
189c19800e8SDoug Rabson     memset(&type2, 0, sizeof(type2));
190c19800e8SDoug Rabson     memset(&type3, 0, sizeof(type3));
191c19800e8SDoug Rabson 
192c19800e8SDoug Rabson     type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
193c19800e8SDoug Rabson     type1.domain = strdup(domain);
194c19800e8SDoug Rabson     type1.hostname = NULL;
195c19800e8SDoug Rabson     type1.os[0] = 0;
196c19800e8SDoug Rabson     type1.os[1] = 0;
197c19800e8SDoug Rabson 
198c19800e8SDoug Rabson     ret = heim_ntlm_encode_type1(&type1, &data);
199c19800e8SDoug Rabson     if (ret)
200c19800e8SDoug Rabson 	errx(1, "heim_ntlm_encode_type1");
201c19800e8SDoug Rabson 
202c19800e8SDoug Rabson     input.value = data.data;
203c19800e8SDoug Rabson     input.length = data.length;
204c19800e8SDoug Rabson 
205c19800e8SDoug Rabson     output.length = 0;
206c19800e8SDoug Rabson     output.value = NULL;
207c19800e8SDoug Rabson 
208c19800e8SDoug Rabson     maj_stat = gss_accept_sec_context(&min_stat,
209c19800e8SDoug Rabson 				      &ctx,
210c19800e8SDoug Rabson 				      GSS_C_NO_CREDENTIAL,
211c19800e8SDoug Rabson 				      &input,
212c19800e8SDoug Rabson 				      GSS_C_NO_CHANNEL_BINDINGS,
213c19800e8SDoug Rabson 				      NULL,
214c19800e8SDoug Rabson 				      NULL,
215c19800e8SDoug Rabson 				      &output,
216c19800e8SDoug Rabson 				      NULL,
217c19800e8SDoug Rabson 				      NULL,
218c19800e8SDoug Rabson 				      NULL);
219c19800e8SDoug Rabson     free(data.data);
220c19800e8SDoug Rabson     if (GSS_ERROR(maj_stat))
221c19800e8SDoug Rabson 	errx(1, "accept_sec_context v2 %s",
222c19800e8SDoug Rabson 	     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
223c19800e8SDoug Rabson 
224c19800e8SDoug Rabson     if (output.length == 0)
225c19800e8SDoug Rabson 	errx(1, "output.length == 0");
226c19800e8SDoug Rabson 
227c19800e8SDoug Rabson     data.data = output.value;
228c19800e8SDoug Rabson     data.length = output.length;
229c19800e8SDoug Rabson 
230c19800e8SDoug Rabson     ret = heim_ntlm_decode_type2(&data, &type2);
231c19800e8SDoug Rabson     if (ret)
232c19800e8SDoug Rabson 	errx(1, "heim_ntlm_decode_type2");
233c19800e8SDoug Rabson 
234c19800e8SDoug Rabson     type3.flags = type2.flags;
235c19800e8SDoug Rabson     type3.username = rk_UNCONST(user);
236c19800e8SDoug Rabson     type3.targetname = type2.targetname;
237c19800e8SDoug Rabson     type3.ws = rk_UNCONST("workstation");
238c19800e8SDoug Rabson 
239c19800e8SDoug Rabson     {
240c19800e8SDoug Rabson 	struct ntlm_buf key;
241c19800e8SDoug Rabson 	unsigned char ntlmv2[16];
242c19800e8SDoug Rabson 
243c19800e8SDoug Rabson 	heim_ntlm_nt_key(password, &key);
244c19800e8SDoug Rabson 
245c19800e8SDoug Rabson 	heim_ntlm_calculate_ntlm2(key.data, key.length,
246c19800e8SDoug Rabson 				  user,
247c19800e8SDoug Rabson 				  type2.targetname,
248*ae771770SStanislav Sedov 				  type2.challenge,
249c19800e8SDoug Rabson 				  &type2.targetinfo,
250c19800e8SDoug Rabson 				  ntlmv2,
251c19800e8SDoug Rabson 				  &type3.ntlm);
252c19800e8SDoug Rabson 	free(key.data);
253c19800e8SDoug Rabson 
254c19800e8SDoug Rabson 	if (flags & NTLM_NEG_KEYEX) {
255c19800e8SDoug Rabson 	    struct ntlm_buf sessionkey;
256c19800e8SDoug Rabson 	    heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
257c19800e8SDoug Rabson 					 &sessionkey,
258c19800e8SDoug Rabson 					 &type3.sessionkey);
259c19800e8SDoug Rabson 	    free(sessionkey.data);
260c19800e8SDoug Rabson 	}
261c19800e8SDoug Rabson     }
262c19800e8SDoug Rabson 
263c19800e8SDoug Rabson     ret = heim_ntlm_encode_type3(&type3, &data);
264c19800e8SDoug Rabson     if (ret)
265c19800e8SDoug Rabson 	errx(1, "heim_ntlm_encode_type3");
266c19800e8SDoug Rabson 
267c19800e8SDoug Rabson     input.length = data.length;
268c19800e8SDoug Rabson     input.value = data.data;
269c19800e8SDoug Rabson 
270c19800e8SDoug Rabson     maj_stat = gss_accept_sec_context(&min_stat,
271c19800e8SDoug Rabson 				      &ctx,
272c19800e8SDoug Rabson 				      GSS_C_NO_CREDENTIAL,
273c19800e8SDoug Rabson 				      &input,
274c19800e8SDoug Rabson 				      GSS_C_NO_CHANNEL_BINDINGS,
275c19800e8SDoug Rabson 				      NULL,
276c19800e8SDoug Rabson 				      NULL,
277c19800e8SDoug Rabson 				      &output,
278c19800e8SDoug Rabson 				      NULL,
279c19800e8SDoug Rabson 				      NULL,
280c19800e8SDoug Rabson 				      NULL);
281c19800e8SDoug Rabson     free(input.value);
282c19800e8SDoug Rabson     if (maj_stat != GSS_S_COMPLETE)
283c19800e8SDoug Rabson 	errx(1, "accept_sec_context v2 2 %s",
284c19800e8SDoug Rabson 	     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
285c19800e8SDoug Rabson 
286c19800e8SDoug Rabson     gss_delete_sec_context(&min_stat, &ctx, NULL);
287c19800e8SDoug Rabson 
288c19800e8SDoug Rabson     return 0;
289c19800e8SDoug Rabson }
290c19800e8SDoug Rabson 
291c19800e8SDoug Rabson 
292c19800e8SDoug Rabson 
293c19800e8SDoug Rabson static int version_flag = 0;
294c19800e8SDoug Rabson static int help_flag	= 0;
295c19800e8SDoug Rabson 
296c19800e8SDoug Rabson static struct getargs args[] = {
297c19800e8SDoug Rabson     {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
298c19800e8SDoug Rabson     {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
299c19800e8SDoug Rabson };
300c19800e8SDoug Rabson 
301c19800e8SDoug Rabson static void
usage(int ret)302c19800e8SDoug Rabson usage (int ret)
303c19800e8SDoug Rabson {
304c19800e8SDoug Rabson     arg_printusage (args, sizeof(args)/sizeof(*args),
305c19800e8SDoug Rabson 		    NULL, "");
306c19800e8SDoug Rabson     exit (ret);
307c19800e8SDoug Rabson }
308c19800e8SDoug Rabson 
309c19800e8SDoug Rabson int
main(int argc,char ** argv)310c19800e8SDoug Rabson main(int argc, char **argv)
311c19800e8SDoug Rabson {
312c19800e8SDoug Rabson     int ret = 0, optind = 0;
313c19800e8SDoug Rabson 
314c19800e8SDoug Rabson     setprogname(argv[0]);
315c19800e8SDoug Rabson 
316c19800e8SDoug Rabson     if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
317c19800e8SDoug Rabson 	usage(1);
318c19800e8SDoug Rabson 
319c19800e8SDoug Rabson     if (help_flag)
320c19800e8SDoug Rabson 	usage (0);
321c19800e8SDoug Rabson 
322c19800e8SDoug Rabson     if(version_flag){
323c19800e8SDoug Rabson 	print_version(NULL);
324c19800e8SDoug Rabson 	exit(0);
325c19800e8SDoug Rabson     }
326c19800e8SDoug Rabson 
327c19800e8SDoug Rabson     argc -= optind;
328c19800e8SDoug Rabson     argv += optind;
329c19800e8SDoug Rabson 
330c19800e8SDoug Rabson     ret += test_libntlm_v1(0);
331c19800e8SDoug Rabson     ret += test_libntlm_v1(NTLM_NEG_KEYEX);
332c19800e8SDoug Rabson 
333c19800e8SDoug Rabson     ret += test_libntlm_v2(0);
334c19800e8SDoug Rabson     ret += test_libntlm_v2(NTLM_NEG_KEYEX);
335c19800e8SDoug Rabson 
336c19800e8SDoug Rabson     return 0;
337c19800e8SDoug Rabson }
338