1178825Sdfr/*
2178825Sdfr * Copyright (c) 2003-2004 Kungliga Tekniska H�gskolan
3178825Sdfr * (Royal Institute of Technology, Stockholm, Sweden).
4178825Sdfr * All rights reserved.
5178825Sdfr *
6178825Sdfr * Redistribution and use in source and binary forms, with or without
7178825Sdfr * modification, are permitted provided that the following conditions
8178825Sdfr * are met:
9178825Sdfr *
10178825Sdfr * 1. Redistributions of source code must retain the above copyright
11178825Sdfr *    notice, this list of conditions and the following disclaimer.
12178825Sdfr *
13178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright
14178825Sdfr *    notice, this list of conditions and the following disclaimer in the
15178825Sdfr *    documentation and/or other materials provided with the distribution.
16178825Sdfr *
17178825Sdfr * 3. Neither the name of KTH nor the names of its contributors may be
18178825Sdfr *    used to endorse or promote products derived from this software without
19178825Sdfr *    specific prior written permission.
20178825Sdfr *
21178825Sdfr * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22178825Sdfr * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24178825Sdfr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25178825Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26178825Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27178825Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28178825Sdfr * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29178825Sdfr * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30178825Sdfr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31178825Sdfr * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32178825Sdfr */
33178825Sdfr
34178825Sdfr#ifdef HAVE_CONFIG_H
35178825Sdfr#include <config.h>
36178825Sdfr#endif
37178825Sdfr
38178825Sdfr#include <stdio.h>
39178825Sdfr#include <stdlib.h>
40178825Sdfr#include <string.h>
41178825Sdfr#include <stdarg.h>
42178825Sdfr#include <gssapi.h>
43178825Sdfr#include <err.h>
44178825Sdfr#include <roken.h>
45178825Sdfr#include <getarg.h>
46178825Sdfr
47178825SdfrRCSID("$Id: test_cred.c 17750 2006-06-30 11:55:28Z lha $");
48178825Sdfr
49178825Sdfrstatic void
50178825Sdfrgss_print_errors (int min_stat)
51178825Sdfr{
52178825Sdfr    OM_uint32 new_stat;
53178825Sdfr    OM_uint32 msg_ctx = 0;
54178825Sdfr    gss_buffer_desc status_string;
55178825Sdfr    OM_uint32 ret;
56178825Sdfr
57178825Sdfr    do {
58178825Sdfr	ret = gss_display_status (&new_stat,
59178825Sdfr				  min_stat,
60178825Sdfr				  GSS_C_MECH_CODE,
61178825Sdfr				  GSS_C_NO_OID,
62178825Sdfr				  &msg_ctx,
63178825Sdfr				  &status_string);
64178825Sdfr	if (!GSS_ERROR(ret)) {
65178825Sdfr	    fprintf (stderr, "%s\n", (char *)status_string.value);
66178825Sdfr	    gss_release_buffer (&new_stat, &status_string);
67178825Sdfr	}
68178825Sdfr    } while (!GSS_ERROR(ret) && msg_ctx != 0);
69178825Sdfr}
70178825Sdfr
71178825Sdfrstatic void
72178825Sdfrgss_err(int exitval, int status, const char *fmt, ...)
73178825Sdfr{
74178825Sdfr    va_list args;
75178825Sdfr
76178825Sdfr    va_start(args, fmt);
77178825Sdfr    vwarnx (fmt, args);
78178825Sdfr    gss_print_errors (status);
79178825Sdfr    va_end(args);
80178825Sdfr    exit (exitval);
81178825Sdfr}
82178825Sdfr
83178825Sdfrstatic void
84178825Sdfracquire_release_loop(gss_name_t name, int counter, gss_cred_usage_t usage)
85178825Sdfr{
86178825Sdfr    OM_uint32 maj_stat, min_stat;
87178825Sdfr    gss_cred_id_t cred;
88178825Sdfr    int i;
89178825Sdfr
90178825Sdfr    for (i = 0; i < counter; i++) {
91178825Sdfr	maj_stat = gss_acquire_cred(&min_stat, name,
92178825Sdfr				    GSS_C_INDEFINITE,
93178825Sdfr				    GSS_C_NO_OID_SET,
94178825Sdfr				    usage,
95178825Sdfr				    &cred,
96178825Sdfr				    NULL,
97178825Sdfr				    NULL);
98178825Sdfr	if (maj_stat != GSS_S_COMPLETE)
99178825Sdfr	    gss_err(1, min_stat, "aquire %d %d != GSS_S_COMPLETE",
100178825Sdfr		    i, (int)maj_stat);
101178825Sdfr
102178825Sdfr	maj_stat = gss_release_cred(&min_stat, &cred);
103178825Sdfr	if (maj_stat != GSS_S_COMPLETE)
104178825Sdfr	    gss_err(1, min_stat, "release %d %d != GSS_S_COMPLETE",
105178825Sdfr		    i, (int)maj_stat);
106178825Sdfr    }
107178825Sdfr}
108178825Sdfr
109178825Sdfr
110178825Sdfrstatic void
111178825Sdfracquire_add_release_add(gss_name_t name, gss_cred_usage_t usage)
112178825Sdfr{
113178825Sdfr    OM_uint32 maj_stat, min_stat;
114178825Sdfr    gss_cred_id_t cred, cred2, cred3;
115178825Sdfr
116178825Sdfr    maj_stat = gss_acquire_cred(&min_stat, name,
117178825Sdfr				GSS_C_INDEFINITE,
118178825Sdfr				GSS_C_NO_OID_SET,
119178825Sdfr				usage,
120178825Sdfr				&cred,
121178825Sdfr				NULL,
122178825Sdfr				NULL);
123178825Sdfr    if (maj_stat != GSS_S_COMPLETE)
124178825Sdfr	gss_err(1, min_stat, "aquire %d != GSS_S_COMPLETE", (int)maj_stat);
125178825Sdfr
126178825Sdfr    maj_stat = gss_add_cred(&min_stat,
127178825Sdfr			    cred,
128178825Sdfr			    GSS_C_NO_NAME,
129178825Sdfr			    GSS_KRB5_MECHANISM,
130178825Sdfr			    usage,
131178825Sdfr			    GSS_C_INDEFINITE,
132178825Sdfr			    GSS_C_INDEFINITE,
133178825Sdfr			    &cred2,
134178825Sdfr			    NULL,
135178825Sdfr			    NULL,
136178825Sdfr			    NULL);
137178825Sdfr
138178825Sdfr    if (maj_stat != GSS_S_COMPLETE)
139178825Sdfr	gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat);
140178825Sdfr
141178825Sdfr    maj_stat = gss_release_cred(&min_stat, &cred);
142178825Sdfr    if (maj_stat != GSS_S_COMPLETE)
143178825Sdfr	gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat);
144178825Sdfr
145178825Sdfr    maj_stat = gss_add_cred(&min_stat,
146178825Sdfr			    cred2,
147178825Sdfr			    GSS_C_NO_NAME,
148178825Sdfr			    GSS_KRB5_MECHANISM,
149178825Sdfr			    GSS_C_BOTH,
150178825Sdfr			    GSS_C_INDEFINITE,
151178825Sdfr			    GSS_C_INDEFINITE,
152178825Sdfr			    &cred3,
153178825Sdfr			    NULL,
154178825Sdfr			    NULL,
155178825Sdfr			    NULL);
156178825Sdfr
157178825Sdfr    maj_stat = gss_release_cred(&min_stat, &cred2);
158178825Sdfr    if (maj_stat != GSS_S_COMPLETE)
159178825Sdfr	gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
160178825Sdfr
161178825Sdfr    maj_stat = gss_release_cred(&min_stat, &cred3);
162178825Sdfr    if (maj_stat != GSS_S_COMPLETE)
163178825Sdfr	gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
164178825Sdfr}
165178825Sdfr
166178825Sdfrstatic int version_flag = 0;
167178825Sdfrstatic int help_flag	= 0;
168178825Sdfr
169178825Sdfrstatic struct getargs args[] = {
170178825Sdfr    {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
171178825Sdfr    {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
172178825Sdfr};
173178825Sdfr
174178825Sdfrstatic void
175178825Sdfrusage (int ret)
176178825Sdfr{
177178825Sdfr    arg_printusage (args, sizeof(args)/sizeof(*args),
178178825Sdfr		    NULL, "service@host");
179178825Sdfr    exit (ret);
180178825Sdfr}
181178825Sdfr
182178825Sdfr
183178825Sdfrint
184178825Sdfrmain(int argc, char **argv)
185178825Sdfr{
186178825Sdfr    struct gss_buffer_desc_struct name_buffer;
187178825Sdfr    OM_uint32 maj_stat, min_stat;
188178825Sdfr    gss_name_t name;
189178825Sdfr    int optidx = 0;
190178825Sdfr
191178825Sdfr    setprogname(argv[0]);
192178825Sdfr    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
193178825Sdfr	usage(1);
194178825Sdfr
195178825Sdfr    if (help_flag)
196178825Sdfr	usage (0);
197178825Sdfr
198178825Sdfr    if(version_flag){
199178825Sdfr	print_version(NULL);
200178825Sdfr	exit(0);
201178825Sdfr    }
202178825Sdfr
203178825Sdfr    argc -= optidx;
204178825Sdfr    argv += optidx;
205178825Sdfr
206178825Sdfr    if (argc < 1)
207178825Sdfr	errx(1, "argc < 1");
208178825Sdfr
209178825Sdfr    name_buffer.value = argv[0];
210178825Sdfr    name_buffer.length = strlen(argv[0]);
211178825Sdfr
212178825Sdfr    maj_stat = gss_import_name(&min_stat, &name_buffer,
213178825Sdfr			       GSS_C_NT_HOSTBASED_SERVICE,
214178825Sdfr			       &name);
215178825Sdfr    if (maj_stat != GSS_S_COMPLETE)
216178825Sdfr	errx(1, "import name error");
217178825Sdfr
218178825Sdfr    acquire_release_loop(name, 100, GSS_C_ACCEPT);
219178825Sdfr    acquire_release_loop(name, 100, GSS_C_INITIATE);
220178825Sdfr    acquire_release_loop(name, 100, GSS_C_BOTH);
221178825Sdfr
222178825Sdfr    acquire_add_release_add(name, GSS_C_ACCEPT);
223178825Sdfr    acquire_add_release_add(name, GSS_C_INITIATE);
224178825Sdfr    acquire_add_release_add(name, GSS_C_BOTH);
225178825Sdfr
226178825Sdfr    gss_release_name(&min_stat, &name);
227178825Sdfr
228178825Sdfr    return 0;
229178825Sdfr}
230