1.3.0pre1
[heimdal.git] / lib / gssapi / test_ntlm.c
blob2282105fd93b3f01aa9843f49254e439e46630e0
1 /*
2 * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include "config.h"
36 #include <stdio.h>
37 #include <gssapi.h>
38 #include <err.h>
39 #include <roken.h>
40 #include <getarg.h>
41 #include "test_common.h"
43 RCSID("$Id$");
45 #include <krb5.h>
46 #include <heimntlm.h>
48 static int
49 test_libntlm_v1(int flags)
51 const char *user = "foo",
52 *domain = "mydomain",
53 *password = "digestpassword";
54 OM_uint32 maj_stat, min_stat;
55 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
56 gss_buffer_desc input, output;
57 struct ntlm_type1 type1;
58 struct ntlm_type2 type2;
59 struct ntlm_type3 type3;
60 struct ntlm_buf data;
61 krb5_error_code ret;
62 gss_name_t src_name = GSS_C_NO_NAME;
64 memset(&type1, 0, sizeof(type1));
65 memset(&type2, 0, sizeof(type2));
66 memset(&type3, 0, sizeof(type3));
68 type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|flags;
69 type1.domain = strdup(domain);
70 type1.hostname = NULL;
71 type1.os[0] = 0;
72 type1.os[1] = 0;
74 ret = heim_ntlm_encode_type1(&type1, &data);
75 if (ret)
76 errx(1, "heim_ntlm_encode_type1");
78 input.value = data.data;
79 input.length = data.length;
81 output.length = 0;
82 output.value = NULL;
84 maj_stat = gss_accept_sec_context(&min_stat,
85 &ctx,
86 GSS_C_NO_CREDENTIAL,
87 &input,
88 GSS_C_NO_CHANNEL_BINDINGS,
89 NULL,
90 NULL,
91 &output,
92 NULL,
93 NULL,
94 NULL);
95 free(data.data);
96 if (GSS_ERROR(maj_stat))
97 errx(1, "accept_sec_context v1: %s",
98 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
100 if (output.length == 0)
101 errx(1, "output.length == 0");
103 data.data = output.value;
104 data.length = output.length;
106 ret = heim_ntlm_decode_type2(&data, &type2);
107 if (ret)
108 errx(1, "heim_ntlm_decode_type2");
110 gss_release_buffer(&min_stat, &output);
112 type3.flags = type2.flags;
113 type3.username = rk_UNCONST(user);
114 type3.targetname = type2.targetname;
115 type3.ws = rk_UNCONST("workstation");
118 struct ntlm_buf key;
120 heim_ntlm_nt_key(password, &key);
122 heim_ntlm_calculate_ntlm1(key.data, key.length,
123 type2.challange,
124 &type3.ntlm);
126 if (flags & NTLM_NEG_KEYEX) {
127 struct ntlm_buf sessionkey;
128 heim_ntlm_build_ntlm1_master(key.data, key.length,
129 &sessionkey,
130 &type3.sessionkey);
131 free(sessionkey.data);
133 free(key.data);
136 ret = heim_ntlm_encode_type3(&type3, &data);
137 if (ret)
138 errx(1, "heim_ntlm_encode_type3");
140 input.length = data.length;
141 input.value = data.data;
143 maj_stat = gss_accept_sec_context(&min_stat,
144 &ctx,
145 GSS_C_NO_CREDENTIAL,
146 &input,
147 GSS_C_NO_CHANNEL_BINDINGS,
148 &src_name,
149 NULL,
150 &output,
151 NULL,
152 NULL,
153 NULL);
154 free(input.value);
155 if (maj_stat != GSS_S_COMPLETE)
156 errx(1, "accept_sec_context v1 2 %s",
157 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
159 gss_release_buffer(&min_stat, &output);
160 gss_delete_sec_context(&min_stat, &ctx, NULL);
162 if (src_name == GSS_C_NO_NAME)
163 errx(1, "no source name!");
165 gss_display_name(&min_stat, src_name, &output, NULL);
167 printf("src_name: %.*s\n", (int)output.length, (char*)output.value);
169 gss_release_name(&min_stat, &src_name);
170 gss_release_buffer(&min_stat, &output);
172 return 0;
175 static int
176 test_libntlm_v2(int flags)
178 const char *user = "foo",
179 *domain = "mydomain",
180 *password = "digestpassword";
181 OM_uint32 maj_stat, min_stat;
182 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
183 gss_buffer_desc input, output;
184 struct ntlm_type1 type1;
185 struct ntlm_type2 type2;
186 struct ntlm_type3 type3;
187 struct ntlm_buf data;
188 krb5_error_code ret;
190 memset(&type1, 0, sizeof(type1));
191 memset(&type2, 0, sizeof(type2));
192 memset(&type3, 0, sizeof(type3));
194 type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
195 type1.domain = strdup(domain);
196 type1.hostname = NULL;
197 type1.os[0] = 0;
198 type1.os[1] = 0;
200 ret = heim_ntlm_encode_type1(&type1, &data);
201 if (ret)
202 errx(1, "heim_ntlm_encode_type1");
204 input.value = data.data;
205 input.length = data.length;
207 output.length = 0;
208 output.value = NULL;
210 maj_stat = gss_accept_sec_context(&min_stat,
211 &ctx,
212 GSS_C_NO_CREDENTIAL,
213 &input,
214 GSS_C_NO_CHANNEL_BINDINGS,
215 NULL,
216 NULL,
217 &output,
218 NULL,
219 NULL,
220 NULL);
221 free(data.data);
222 if (GSS_ERROR(maj_stat))
223 errx(1, "accept_sec_context v2 %s",
224 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
226 if (output.length == 0)
227 errx(1, "output.length == 0");
229 data.data = output.value;
230 data.length = output.length;
232 ret = heim_ntlm_decode_type2(&data, &type2);
233 if (ret)
234 errx(1, "heim_ntlm_decode_type2");
236 type3.flags = type2.flags;
237 type3.username = rk_UNCONST(user);
238 type3.targetname = type2.targetname;
239 type3.ws = rk_UNCONST("workstation");
242 struct ntlm_buf key;
243 unsigned char ntlmv2[16];
245 heim_ntlm_nt_key(password, &key);
247 heim_ntlm_calculate_ntlm2(key.data, key.length,
248 user,
249 type2.targetname,
250 type2.challange,
251 &type2.targetinfo,
252 ntlmv2,
253 &type3.ntlm);
254 free(key.data);
256 if (flags & NTLM_NEG_KEYEX) {
257 struct ntlm_buf sessionkey;
258 heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
259 &sessionkey,
260 &type3.sessionkey);
261 free(sessionkey.data);
265 ret = heim_ntlm_encode_type3(&type3, &data);
266 if (ret)
267 errx(1, "heim_ntlm_encode_type3");
269 input.length = data.length;
270 input.value = data.data;
272 maj_stat = gss_accept_sec_context(&min_stat,
273 &ctx,
274 GSS_C_NO_CREDENTIAL,
275 &input,
276 GSS_C_NO_CHANNEL_BINDINGS,
277 NULL,
278 NULL,
279 &output,
280 NULL,
281 NULL,
282 NULL);
283 free(input.value);
284 if (maj_stat != GSS_S_COMPLETE)
285 errx(1, "accept_sec_context v2 2 %s",
286 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
288 gss_delete_sec_context(&min_stat, &ctx, NULL);
290 return 0;
295 static int version_flag = 0;
296 static int help_flag = 0;
298 static struct getargs args[] = {
299 {"version", 0, arg_flag, &version_flag, "print version", NULL },
300 {"help", 0, arg_flag, &help_flag, NULL, NULL }
303 static void
304 usage (int ret)
306 arg_printusage (args, sizeof(args)/sizeof(*args),
307 NULL, "");
308 exit (ret);
312 main(int argc, char **argv)
314 int ret = 0, optind = 0;
316 setprogname(argv[0]);
318 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
319 usage(1);
321 if (help_flag)
322 usage (0);
324 if(version_flag){
325 print_version(NULL);
326 exit(0);
329 argc -= optind;
330 argv += optind;
332 ret += test_libntlm_v1(0);
333 ret += test_libntlm_v1(NTLM_NEG_KEYEX);
335 ret += test_libntlm_v2(0);
336 ret += test_libntlm_v2(NTLM_NEG_KEYEX);
338 return 0;