x
[heimdal.git] / lib / gssapi / test_ntlm.c
blob8f25667b2bc3c1f765c5f4c140b6269ac2706f8a
1 /*
2 * Copyright (c) 2006 - 2007 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;
63 memset(&type1, 0, sizeof(type1));
64 memset(&type2, 0, sizeof(type2));
65 memset(&type3, 0, sizeof(type3));
67 type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
68 type1.domain = strdup(domain);
69 type1.hostname = NULL;
70 type1.os[0] = 0;
71 type1.os[1] = 0;
73 ret = heim_ntlm_encode_type1(&type1, &data);
74 if (ret)
75 errx(1, "heim_ntlm_encode_type1");
77 input.value = data.data;
78 input.length = data.length;
80 output.length = 0;
81 output.value = NULL;
83 maj_stat = gss_accept_sec_context(&min_stat,
84 &ctx,
85 GSS_C_NO_CREDENTIAL,
86 &input,
87 GSS_C_NO_CHANNEL_BINDINGS,
88 NULL,
89 NULL,
90 &output,
91 NULL,
92 NULL,
93 NULL);
94 free(data.data);
95 if (GSS_ERROR(maj_stat))
96 errx(1, "accept_sec_context v1: %s",
97 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
99 if (output.length == 0)
100 errx(1, "output.length == 0");
102 data.data = output.value;
103 data.length = output.length;
105 ret = heim_ntlm_decode_type2(&data, &type2);
106 if (ret)
107 errx(1, "heim_ntlm_decode_type2");
109 type3.flags = type2.flags;
110 type3.username = rk_UNCONST(user);
111 type3.targetname = type2.targetname;
112 type3.ws = rk_UNCONST("workstation");
115 struct ntlm_buf key;
117 heim_ntlm_nt_key(password, &key);
119 heim_ntlm_calculate_ntlm1(key.data, key.length,
120 type2.challange,
121 &type3.ntlm);
123 if (flags & NTLM_NEG_KEYEX) {
124 struct ntlm_buf sessionkey;
125 heim_ntlm_build_ntlm1_master(key.data, key.length,
126 &sessionkey,
127 &type3.sessionkey);
128 free(sessionkey.data);
130 free(key.data);
133 ret = heim_ntlm_encode_type3(&type3, &data);
134 if (ret)
135 errx(1, "heim_ntlm_encode_type3");
137 input.length = data.length;
138 input.value = data.data;
140 maj_stat = gss_accept_sec_context(&min_stat,
141 &ctx,
142 GSS_C_NO_CREDENTIAL,
143 &input,
144 GSS_C_NO_CHANNEL_BINDINGS,
145 NULL,
146 NULL,
147 &output,
148 NULL,
149 NULL,
150 NULL);
151 free(input.value);
152 if (maj_stat != GSS_S_COMPLETE)
153 errx(1, "accept_sec_context v1 2 %s",
154 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
156 gss_delete_sec_context(&min_stat, &ctx, NULL);
158 return 0;
161 static int
162 test_libntlm_v2(int flags)
164 const char *user = "foo",
165 *domain = "mydomain",
166 *password = "digestpassword";
167 OM_uint32 maj_stat, min_stat;
168 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
169 gss_buffer_desc input, output;
170 struct ntlm_type1 type1;
171 struct ntlm_type2 type2;
172 struct ntlm_type3 type3;
173 struct ntlm_buf data;
174 krb5_error_code ret;
176 memset(&type1, 0, sizeof(type1));
177 memset(&type2, 0, sizeof(type2));
178 memset(&type3, 0, sizeof(type3));
180 type1.flags = NTLM_NEG_UNICODE|NTLM_NEG_NTLM|flags;
181 type1.domain = strdup(domain);
182 type1.hostname = NULL;
183 type1.os[0] = 0;
184 type1.os[1] = 0;
186 ret = heim_ntlm_encode_type1(&type1, &data);
187 if (ret)
188 errx(1, "heim_ntlm_encode_type1");
190 input.value = data.data;
191 input.length = data.length;
193 output.length = 0;
194 output.value = NULL;
196 maj_stat = gss_accept_sec_context(&min_stat,
197 &ctx,
198 GSS_C_NO_CREDENTIAL,
199 &input,
200 GSS_C_NO_CHANNEL_BINDINGS,
201 NULL,
202 NULL,
203 &output,
204 NULL,
205 NULL,
206 NULL);
207 free(data.data);
208 if (GSS_ERROR(maj_stat))
209 errx(1, "accept_sec_context v2 %s",
210 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
212 if (output.length == 0)
213 errx(1, "output.length == 0");
215 data.data = output.value;
216 data.length = output.length;
218 ret = heim_ntlm_decode_type2(&data, &type2);
219 if (ret)
220 errx(1, "heim_ntlm_decode_type2");
222 type3.flags = type2.flags;
223 type3.username = rk_UNCONST(user);
224 type3.targetname = type2.targetname;
225 type3.ws = rk_UNCONST("workstation");
228 struct ntlm_buf key;
229 unsigned char ntlmv2[16];
231 heim_ntlm_nt_key(password, &key);
233 heim_ntlm_calculate_ntlm2(key.data, key.length,
234 user,
235 type2.targetname,
236 type2.challange,
237 &type2.targetinfo,
238 ntlmv2,
239 &type3.ntlm);
240 free(key.data);
242 if (flags & NTLM_NEG_KEYEX) {
243 struct ntlm_buf sessionkey;
244 heim_ntlm_build_ntlm1_master(ntlmv2, sizeof(ntlmv2),
245 &sessionkey,
246 &type3.sessionkey);
247 free(sessionkey.data);
251 ret = heim_ntlm_encode_type3(&type3, &data);
252 if (ret)
253 errx(1, "heim_ntlm_encode_type3");
255 input.length = data.length;
256 input.value = data.data;
258 maj_stat = gss_accept_sec_context(&min_stat,
259 &ctx,
260 GSS_C_NO_CREDENTIAL,
261 &input,
262 GSS_C_NO_CHANNEL_BINDINGS,
263 NULL,
264 NULL,
265 &output,
266 NULL,
267 NULL,
268 NULL);
269 free(input.value);
270 if (maj_stat != GSS_S_COMPLETE)
271 errx(1, "accept_sec_context v2 2 %s",
272 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
274 gss_delete_sec_context(&min_stat, &ctx, NULL);
276 return 0;
281 static int version_flag = 0;
282 static int help_flag = 0;
284 static struct getargs args[] = {
285 {"version", 0, arg_flag, &version_flag, "print version", NULL },
286 {"help", 0, arg_flag, &help_flag, NULL, NULL }
289 static void
290 usage (int ret)
292 arg_printusage (args, sizeof(args)/sizeof(*args),
293 NULL, "");
294 exit (ret);
298 main(int argc, char **argv)
300 int ret = 0, optind = 0;
302 setprogname(argv[0]);
304 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
305 usage(1);
307 if (help_flag)
308 usage (0);
310 if(version_flag){
311 print_version(NULL);
312 exit(0);
315 argc -= optind;
316 argv += optind;
318 ret += test_libntlm_v1(0);
319 ret += test_libntlm_v1(NTLM_NEG_KEYEX);
321 ret += test_libntlm_v2(0);
322 ret += test_libntlm_v2(NTLM_NEG_KEYEX);
324 return 0;