1/*	$NetBSD: test_names.c,v 1.1.1.1 2011/04/13 18:14:44 elric Exp $	*/
2
3/*
4 * Copyright (c) 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of KTH nor the names of its contributors may be
20 *    used to endorse or promote products derived from this software without
21 *    specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#ifdef HAVE_CONFIG_H
37#include <config.h>
38#endif
39
40#include <krb5/roken.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <stdarg.h>
45#include <gssapi/gssapi.h>
46#include <gssapi/gssapi_krb5.h>
47#include <gssapi/gssapi_spnego.h>
48#include <err.h>
49#include <krb5/getarg.h>
50
51static void
52gss_print_errors (int min_stat)
53{
54    OM_uint32 new_stat;
55    OM_uint32 msg_ctx = 0;
56    gss_buffer_desc status_string;
57    OM_uint32 ret;
58
59    do {
60	ret = gss_display_status (&new_stat,
61				  min_stat,
62				  GSS_C_MECH_CODE,
63				  GSS_C_NO_OID,
64				  &msg_ctx,
65				  &status_string);
66	if (!GSS_ERROR(ret)) {
67	    fprintf (stderr, "%.*s\n", (int)status_string.length,
68					(char *)status_string.value);
69	    gss_release_buffer (&new_stat, &status_string);
70	}
71    } while (!GSS_ERROR(ret) && msg_ctx != 0);
72}
73
74static void
75gss_err(int exitval, int status, const char *fmt, ...)
76{
77    va_list args;
78
79    va_start(args, fmt);
80    vwarnx (fmt, args);
81    gss_print_errors (status);
82    va_end(args);
83    exit (exitval);
84}
85
86static int version_flag = 0;
87static int help_flag	= 0;
88
89static struct getargs args[] = {
90    {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
91    {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
92};
93
94static void
95usage (int ret)
96{
97    arg_printusage (args, sizeof(args)/sizeof(*args),
98		    NULL, "service@host");
99    exit (ret);
100}
101
102
103int
104main(int argc, char **argv)
105{
106    gss_buffer_desc name_buffer;
107    OM_uint32 maj_stat, min_stat;
108    gss_name_t name, MNname, MNname2;
109    int optidx = 0;
110    char *str;
111    int len, equal;
112
113    setprogname(argv[0]);
114    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
115	usage(1);
116
117    if (help_flag)
118	usage (0);
119
120    if(version_flag){
121	print_version(NULL);
122	exit(0);
123    }
124
125    argc -= optidx;
126    argv += optidx;
127
128    gsskrb5_set_default_realm("MIT.EDU");
129
130    /*
131     * test import/export
132     */
133
134    str = NULL;
135    len = asprintf(&str, "ftp@freeze-arrow.mit.edu");
136    if (len < 0 || str == NULL)
137	errx(1, "asprintf");
138
139    name_buffer.value = str;
140    name_buffer.length = len;
141
142    maj_stat = gss_import_name(&min_stat, &name_buffer,
143			       GSS_C_NT_HOSTBASED_SERVICE,
144			       &name);
145    if (maj_stat != GSS_S_COMPLETE)
146	gss_err(1, min_stat, "import name error");
147    free(str);
148
149    maj_stat = gss_canonicalize_name (&min_stat,
150				      name,
151				      GSS_KRB5_MECHANISM,
152				      &MNname);
153    if (maj_stat != GSS_S_COMPLETE)
154	gss_err(1, min_stat, "canonicalize name error");
155
156    maj_stat = gss_export_name(&min_stat,
157			       MNname,
158			       &name_buffer);
159    if (maj_stat != GSS_S_COMPLETE)
160	gss_err(1, min_stat, "export name error (KRB5)");
161
162    /*
163     * Import the exported name and compare
164     */
165
166    maj_stat = gss_import_name(&min_stat, &name_buffer,
167			       GSS_C_NT_EXPORT_NAME,
168			       &MNname2);
169    if (maj_stat != GSS_S_COMPLETE)
170	gss_err(1, min_stat, "import name error (exported KRB5 name)");
171
172
173    maj_stat = gss_compare_name(&min_stat, MNname, MNname2, &equal);
174    if (maj_stat != GSS_S_COMPLETE)
175	errx(1, "gss_compare_name");
176    if (!equal)
177	errx(1, "names not equal");
178
179    gss_release_name(&min_stat, &MNname2);
180    gss_release_buffer(&min_stat, &name_buffer);
181    gss_release_name(&min_stat, &MNname);
182    gss_release_name(&min_stat, &name);
183
184    /*
185     * Import oid less name and compare to mech name.
186     * Dovecot SASL lib does this.
187     */
188
189    str = NULL;
190    len = asprintf(&str, "lha");
191    if (len < 0 || str == NULL)
192	errx(1, "asprintf");
193
194    name_buffer.value = str;
195    name_buffer.length = len;
196
197    maj_stat = gss_import_name(&min_stat, &name_buffer,
198			       GSS_C_NO_OID,
199			       &name);
200    if (maj_stat != GSS_S_COMPLETE)
201	gss_err(1, min_stat, "import (no oid) name error");
202
203    maj_stat = gss_import_name(&min_stat, &name_buffer,
204			       GSS_KRB5_NT_USER_NAME,
205			       &MNname);
206    if (maj_stat != GSS_S_COMPLETE)
207	gss_err(1, min_stat, "import (krb5 mn) name error");
208
209    free(str);
210
211    maj_stat = gss_compare_name(&min_stat, name, MNname, &equal);
212    if (maj_stat != GSS_S_COMPLETE)
213	errx(1, "gss_compare_name");
214    if (!equal)
215	errx(1, "names not equal");
216
217    gss_release_name(&min_stat, &MNname);
218    gss_release_name(&min_stat, &name);
219
220#if 0
221    maj_stat = gss_canonicalize_name (&min_stat,
222				      name,
223				      GSS_SPNEGO_MECHANISM,
224				      &MNname);
225    if (maj_stat != GSS_S_COMPLETE)
226	gss_err(1, min_stat, "canonicalize name error");
227
228
229    maj_stat = gss_export_name(&maj_stat,
230			       MNname,
231			       &name_buffer);
232    if (maj_stat != GSS_S_COMPLETE)
233	gss_err(1, min_stat, "export name error (SPNEGO)");
234
235    gss_release_name(&min_stat, &MNname);
236    gss_release_buffer(&min_stat, &name_buffer);
237#endif
238
239    return 0;
240}
241