libkafs: derivation from non-DES key (rxkad-kdf)
[heimdal.git] / lib / gssapi / test_ntlm.c
blob56f4814e6cc786141962a25f8560a46cd1ca8535
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 <roken.h>
37 #include <stdio.h>
38 #include <gssapi.h>
39 #include <err.h>
40 #include <getarg.h>
41 #include "test_common.h"
43 #include <krb5.h>
44 #include <heimntlm.h>
46 static int
47 test_libntlm_v1(int flags)
49 const char *user = "foo",
50 *domain = "mydomain",
51 *password = "digestpassword";
52 OM_uint32 maj_stat, min_stat;
53 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
54 gss_buffer_desc input, output;
55 struct ntlm_type1 type1;
56 struct ntlm_type2 type2;
57 struct ntlm_type3 type3;
58 struct ntlm_buf data;
59 krb5_error_code ret;
60 gss_name_t src_name = GSS_C_NO_NAME;
62 memset(&type1, 0, sizeof(type1));
63 memset(&type2, 0, sizeof(type2));
64 memset(&type3, 0, sizeof(type3));
66 type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_TARGET|NTLM_NEG_NTLM|flags;
67 type1.domain = strdup(domain);
68 type1.hostname = NULL;
69 type1.os[0] = 0;
70 type1.os[1] = 0;
72 ret = heim_ntlm_encode_type1(&type1, &data);
73 if (ret)
74 errx(1, "heim_ntlm_encode_type1");
76 input.value = data.data;
77 input.length = data.length;
79 output.length = 0;
80 output.value = NULL;
82 maj_stat = gss_accept_sec_context(&min_stat,
83 &ctx,
84 GSS_C_NO_CREDENTIAL,
85 &input,
86 GSS_C_NO_CHANNEL_BINDINGS,
87 NULL,
88 NULL,
89 &output,
90 NULL,
91 NULL,
92 NULL);
93 free(data.data);
94 if (GSS_ERROR(maj_stat))
95 errx(1, "accept_sec_context v1: %s",
96 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
98 if (output.length == 0)
99 errx(1, "output.length == 0");
101 data.data = output.value;
102 data.length = output.length;
104 ret = heim_ntlm_decode_type2(&data, &type2);
105 if (ret)
106 errx(1, "heim_ntlm_decode_type2");
108 gss_release_buffer(&min_stat, &output);
110 type3.flags = type2.flags;
111 type3.username = rk_UNCONST(user);
112 type3.targetname = type2.targetname;
113 type3.ws = rk_UNCONST("workstation");
116 struct ntlm_buf key;
118 heim_ntlm_nt_key(password, &key);
120 heim_ntlm_calculate_ntlm1(key.data, key.length,
121 type2.challenge,
122 &type3.ntlm);
124 if (flags & NTLM_NEG_KEYEX) {
125 struct ntlm_buf sessionkey;
126 heim_ntlm_build_ntlm1_master(key.data, key.length,
127 &sessionkey,
128 &type3.sessionkey);
129 free(sessionkey.data);
131 free(key.data);
134 ret = heim_ntlm_encode_type3(&type3, &data, NULL);
135 if (ret)
136 errx(1, "heim_ntlm_encode_type3");
138 input.length = data.length;
139 input.value = data.data;
141 maj_stat = gss_accept_sec_context(&min_stat,
142 &ctx,
143 GSS_C_NO_CREDENTIAL,
144 &input,
145 GSS_C_NO_CHANNEL_BINDINGS,
146 &src_name,
147 NULL,
148 &output,
149 NULL,
150 NULL,
151 NULL);
152 free(input.value);
153 if (maj_stat != GSS_S_COMPLETE)
154 errx(1, "accept_sec_context v1 2 %s",
155 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
157 gss_release_buffer(&min_stat, &output);
158 gss_delete_sec_context(&min_stat, &ctx, NULL);
160 if (src_name == GSS_C_NO_NAME)
161 errx(1, "no source name!");
163 gss_display_name(&min_stat, src_name, &output, NULL);
165 printf("src_name: %.*s\n", (int)output.length, (char*)output.value);
167 gss_release_name(&min_stat, &src_name);
168 gss_release_buffer(&min_stat, &output);
170 return 0;
173 static int
174 test_libntlm_v2(int flags)
176 const char *user = "foo",
177 *domain = "mydomain",
178 *password = "digestpassword";
179 OM_uint32 maj_stat, min_stat;
180 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
181 gss_buffer_desc input, output;
182 struct ntlm_type1 type1;
183 struct ntlm_type2 type2;
184 struct ntlm_type3 type3;
185 struct ntlm_buf data;
186 krb5_error_code ret;
188 memset(&type1, 0, sizeof(type1));
189 memset(&type2, 0, sizeof(type2));
190 memset(&type3, 0, sizeof(type3));
192 type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
193 type1.domain = strdup(domain);
194 type1.hostname = NULL;
195 type1.os[0] = 0;
196 type1.os[1] = 0;
198 ret = heim_ntlm_encode_type1(&type1, &data);
199 if (ret)
200 errx(1, "heim_ntlm_encode_type1");
202 input.value = data.data;
203 input.length = data.length;
205 output.length = 0;
206 output.value = NULL;
208 maj_stat = gss_accept_sec_context(&min_stat,
209 &ctx,
210 GSS_C_NO_CREDENTIAL,
211 &input,
212 GSS_C_NO_CHANNEL_BINDINGS,
213 NULL,
214 NULL,
215 &output,
216 NULL,
217 NULL,
218 NULL);
219 free(data.data);
220 if (GSS_ERROR(maj_stat))
221 errx(1, "accept_sec_context v2 %s",
222 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
224 if (output.length == 0)
225 errx(1, "output.length == 0");
227 data.data = output.value;
228 data.length = output.length;
230 ret = heim_ntlm_decode_type2(&data, &type2);
231 if (ret)
232 errx(1, "heim_ntlm_decode_type2");
234 type3.flags = type2.flags;
235 type3.username = rk_UNCONST(user);
236 type3.targetname = type2.targetname;
237 type3.ws = rk_UNCONST("workstation");
240 struct ntlm_buf key;
241 unsigned char ntlmv2[16];
243 heim_ntlm_nt_key(password, &key);
245 heim_ntlm_calculate_ntlm2(key.data, key.length,
246 user,
247 type2.targetname,
248 type2.challenge,
249 &type2.targetinfo,
250 ntlmv2,
251 &type3.ntlm);
252 free(key.data);
254 if (flags & NTLM_NEG_KEYEX) {
255 struct ntlm_buf sessionkey;
256 heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
257 &sessionkey,
258 &type3.sessionkey);
259 free(sessionkey.data);
263 ret = heim_ntlm_encode_type3(&type3, &data, NULL);
264 if (ret)
265 errx(1, "heim_ntlm_encode_type3");
267 input.length = data.length;
268 input.value = data.data;
270 maj_stat = gss_accept_sec_context(&min_stat,
271 &ctx,
272 GSS_C_NO_CREDENTIAL,
273 &input,
274 GSS_C_NO_CHANNEL_BINDINGS,
275 NULL,
276 NULL,
277 &output,
278 NULL,
279 NULL,
280 NULL);
281 free(input.value);
282 if (maj_stat != GSS_S_COMPLETE)
283 errx(1, "accept_sec_context v2 2 %s",
284 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
286 gss_delete_sec_context(&min_stat, &ctx, NULL);
288 return 0;
293 static int version_flag = 0;
294 static int help_flag = 0;
296 static struct getargs args[] = {
297 {"version", 0, arg_flag, &version_flag, "print version", NULL },
298 {"help", 0, arg_flag, &help_flag, NULL, NULL }
301 static void
302 usage (int ret)
304 arg_printusage (args, sizeof(args)/sizeof(*args),
305 NULL, "");
306 exit (ret);
310 main(int argc, char **argv)
312 int ret = 0, optidx = 0;
314 setprogname(argv[0]);
316 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
317 usage(1);
319 if (help_flag)
320 usage (0);
322 if(version_flag){
323 print_version(NULL);
324 exit(0);
327 argc -= optidx;
328 argv += optidx;
330 ret += test_libntlm_v1(0);
331 ret += test_libntlm_v1(NTLM_NEG_KEYEX);
333 ret += test_libntlm_v2(0);
334 ret += test_libntlm_v2(NTLM_NEG_KEYEX);
336 return 0;