1226031Sstas/*
2226031Sstas * Copyright (c) 2006 Kungliga Tekniska H��gskolan
3226031Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4226031Sstas * All rights reserved.
5226031Sstas *
6226031Sstas * Portions Copyright (c) 2009 - 2010 Apple Inc. All rights reserved.
7226031Sstas *
8226031Sstas * Redistribution and use in source and binary forms, with or without
9226031Sstas * modification, are permitted provided that the following conditions
10226031Sstas * are met:
11226031Sstas *
12226031Sstas * 1. Redistributions of source code must retain the above copyright
13226031Sstas *    notice, this list of conditions and the following disclaimer.
14226031Sstas *
15226031Sstas * 2. Redistributions in binary form must reproduce the above copyright
16226031Sstas *    notice, this list of conditions and the following disclaimer in the
17226031Sstas *    documentation and/or other materials provided with the distribution.
18226031Sstas *
19226031Sstas * 3. Neither the name of KTH nor the names of its contributors may be
20226031Sstas *    used to endorse or promote products derived from this software without
21226031Sstas *    specific prior written permission.
22226031Sstas *
23226031Sstas * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
24226031Sstas * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26226031Sstas * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
27226031Sstas * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28226031Sstas * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29226031Sstas * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30226031Sstas * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31226031Sstas * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32226031Sstas * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
33226031Sstas * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34226031Sstas */
35226031Sstas
36226031Sstas#include <config.h>
37226031Sstas#include <roken.h>
38226031Sstas
39226031Sstas#include <stdio.h>
40226031Sstas#include <gssapi.h>
41226031Sstas#include <gssapi_krb5.h>
42226031Sstas#include <gssapi_spnego.h>
43226031Sstas#include <gssapi_ntlm.h>
44226031Sstas#include <err.h>
45226031Sstas#include <getarg.h>
46226031Sstas#include <rtbl.h>
47226031Sstas#include <gss-commands.h>
48226031Sstas
49226031Sstas
50226031Sstasstatic int version_flag = 0;
51226031Sstasstatic int help_flag	= 0;
52226031Sstas
53226031Sstasstatic struct getargs args[] = {
54226031Sstas    {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
55226031Sstas    {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
56226031Sstas};
57226031Sstas
58226031Sstasstatic void
59226031Sstasusage (int ret)
60226031Sstas{
61226031Sstas    arg_printusage (args, sizeof(args)/sizeof(*args),
62226031Sstas		    NULL, "service@host");
63226031Sstas    exit (ret);
64226031Sstas}
65226031Sstas
66226031Sstas#define COL_OID		"OID"
67226031Sstas#define COL_NAME	"Name"
68226031Sstas#define COL_DESC	"Description"
69226031Sstas#define COL_VALUE	"Value"
70226031Sstas#define COL_MECH	"Mech"
71226031Sstas#define COL_EXPIRE	"Expire"
72226031Sstas#define COL_SASL	"SASL"
73226031Sstas
74226031Sstasint
75226031Sstassupported_mechanisms(void *argptr, int argc, char **argv)
76226031Sstas{
77226031Sstas    OM_uint32 maj_stat, min_stat;
78226031Sstas    gss_OID_set mechs;
79226031Sstas    rtbl_t ct;
80226031Sstas    size_t i;
81226031Sstas
82226031Sstas    maj_stat = gss_indicate_mechs(&min_stat, &mechs);
83226031Sstas    if (maj_stat != GSS_S_COMPLETE)
84226031Sstas	errx(1, "gss_indicate_mechs failed");
85226031Sstas
86226031Sstas    printf("Supported mechanisms:\n");
87226031Sstas
88226031Sstas    ct = rtbl_create();
89226031Sstas    if (ct == NULL)
90226031Sstas	errx(1, "rtbl_create");
91226031Sstas
92226031Sstas    rtbl_set_separator(ct, "  ");
93226031Sstas    rtbl_add_column(ct, COL_OID, 0);
94226031Sstas    rtbl_add_column(ct, COL_NAME, 0);
95226031Sstas    rtbl_add_column(ct, COL_DESC, 0);
96226031Sstas    rtbl_add_column(ct, COL_SASL, 0);
97226031Sstas
98226031Sstas    for (i = 0; i < mechs->count; i++) {
99226031Sstas	gss_buffer_desc str, sasl_name, mech_name, mech_desc;
100226031Sstas
101226031Sstas	maj_stat = gss_oid_to_str(&min_stat, &mechs->elements[i], &str);
102226031Sstas	if (maj_stat != GSS_S_COMPLETE)
103226031Sstas	    errx(1, "gss_oid_to_str failed");
104226031Sstas
105226031Sstas	rtbl_add_column_entryv(ct, COL_OID, "%.*s",
106226031Sstas			       (int)str.length, (char *)str.value);
107226031Sstas	gss_release_buffer(&min_stat, &str);
108226031Sstas
109226031Sstas	(void)gss_inquire_saslname_for_mech(&min_stat,
110226031Sstas					    &mechs->elements[i],
111226031Sstas					    &sasl_name,
112226031Sstas					    &mech_name,
113226031Sstas					    &mech_desc);
114226031Sstas
115226031Sstas	rtbl_add_column_entryv(ct, COL_NAME, "%.*s",
116226031Sstas			       (int)mech_name.length, (char *)mech_name.value);
117226031Sstas	rtbl_add_column_entryv(ct, COL_DESC, "%.*s",
118226031Sstas			       (int)mech_desc.length, (char *)mech_desc.value);
119226031Sstas	rtbl_add_column_entryv(ct, COL_SASL, "%.*s",
120226031Sstas			       (int)sasl_name.length, (char *)sasl_name.value);
121226031Sstas
122226031Sstas	gss_release_buffer(&min_stat, &mech_name);
123226031Sstas	gss_release_buffer(&min_stat, &mech_desc);
124226031Sstas	gss_release_buffer(&min_stat, &sasl_name);
125226031Sstas
126226031Sstas    }
127226031Sstas    gss_release_oid_set(&min_stat, &mechs);
128226031Sstas
129226031Sstas    rtbl_format(ct, stdout);
130226031Sstas    rtbl_destroy(ct);
131226031Sstas
132226031Sstas    return 0;
133226031Sstas}
134226031Sstas
135226031Sstasstatic void
136226031Sstasprint_mech_attr(const char *mechname, gss_const_OID mech, gss_OID_set set)
137226031Sstas{
138226031Sstas    gss_buffer_desc name, desc;
139226031Sstas    OM_uint32 major, minor;
140226031Sstas    rtbl_t ct;
141226031Sstas    size_t n;
142226031Sstas
143226031Sstas    ct = rtbl_create();
144226031Sstas    if (ct == NULL)
145226031Sstas	errx(1, "rtbl_create");
146226031Sstas
147226031Sstas    rtbl_set_separator(ct, "  ");
148226031Sstas    rtbl_add_column(ct, COL_OID, 0);
149226031Sstas    rtbl_add_column(ct, COL_DESC, 0);
150226031Sstas    if (mech)
151226031Sstas	rtbl_add_column(ct, COL_VALUE, 0);
152226031Sstas
153226031Sstas    for (n = 0; n < set->count; n++) {
154226031Sstas	major = gss_display_mech_attr(&minor, &set->elements[n], &name, &desc, NULL);
155226031Sstas	if (major)
156226031Sstas	    continue;
157226031Sstas
158226031Sstas	rtbl_add_column_entryv(ct, COL_OID, "%.*s",
159226031Sstas			       (int)name.length, (char *)name.value);
160226031Sstas	rtbl_add_column_entryv(ct, COL_DESC, "%.*s",
161226031Sstas			       (int)desc.length, (char *)desc.value);
162226031Sstas	if (mech) {
163226031Sstas	    gss_buffer_desc value;
164226031Sstas
165226031Sstas	    if (gss_mo_get(mech, &set->elements[n], &value) != 0)
166226031Sstas		value.length = 0;
167226031Sstas
168226031Sstas	    if (value.length)
169226031Sstas		rtbl_add_column_entryv(ct, COL_VALUE, "%.*s",
170226031Sstas				       (int)value.length, (char *)value.value);
171226031Sstas	    else
172226031Sstas		rtbl_add_column_entryv(ct, COL_VALUE, "<>");
173226031Sstas	    gss_release_buffer(&minor, &value);
174226031Sstas	}
175226031Sstas
176226031Sstas	gss_release_buffer(&minor, &name);
177226031Sstas	gss_release_buffer(&minor, &desc);
178226031Sstas    }
179226031Sstas
180226031Sstas    printf("attributes for: %s\n", mechname);
181226031Sstas    rtbl_format(ct, stdout);
182226031Sstas    rtbl_destroy(ct);
183226031Sstas}
184226031Sstas
185226031Sstas
186226031Sstasint
187226031Sstasattrs_for_mech(struct attrs_for_mech_options *opt, int argc, char **argv)
188226031Sstas{
189226031Sstas    gss_OID_set mech_attr = NULL, known_mech_attrs = NULL;
190226031Sstas    gss_OID mech = GSS_C_NO_OID;
191226031Sstas    OM_uint32 major, minor;
192226031Sstas
193226031Sstas    if (opt->mech_string) {
194226031Sstas	mech = gss_name_to_oid(opt->mech_string);
195226031Sstas	if (mech == NULL)
196226031Sstas	    errx(1, "mech %s is unknown", opt->mech_string);
197226031Sstas    }
198226031Sstas
199226031Sstas    major = gss_inquire_attrs_for_mech(&minor, mech, &mech_attr, &known_mech_attrs);
200226031Sstas    if (major)
201226031Sstas	errx(1, "gss_inquire_attrs_for_mech");
202226031Sstas
203226031Sstas    if (mech) {
204226031Sstas	print_mech_attr(opt->mech_string, mech, mech_attr);
205226031Sstas    }
206226031Sstas
207226031Sstas    if (opt->all_flag) {
208226031Sstas	print_mech_attr("all mechs", NULL, known_mech_attrs);
209226031Sstas    }
210226031Sstas
211226031Sstas    gss_release_oid_set(&minor, &mech_attr);
212226031Sstas    gss_release_oid_set(&minor, &known_mech_attrs);
213226031Sstas
214226031Sstas    return 0;
215226031Sstas}
216226031Sstas
217226031Sstas
218226031Sstas/*
219226031Sstas *
220226031Sstas */
221226031Sstas
222226031Sstasint
223226031Sstashelp(void *opt, int argc, char **argv)
224226031Sstas{
225226031Sstas    sl_slc_help(commands, argc, argv);
226226031Sstas    return 0;
227226031Sstas}
228226031Sstas
229226031Sstasint
230226031Sstasmain(int argc, char **argv)
231226031Sstas{
232226031Sstas    int optidx = 0;
233226031Sstas
234226031Sstas    setprogname(argv[0]);
235226031Sstas    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
236226031Sstas	usage(1);
237226031Sstas
238226031Sstas    if (help_flag)
239226031Sstas	usage (0);
240226031Sstas
241226031Sstas    if(version_flag){
242226031Sstas	print_version(NULL);
243226031Sstas	exit(0);
244226031Sstas    }
245226031Sstas
246226031Sstas    argc -= optidx;
247226031Sstas    argv += optidx;
248226031Sstas
249226031Sstas    if (argc == 0) {
250226031Sstas	help(NULL, argc, argv);
251226031Sstas	return 1;
252226031Sstas    }
253226031Sstas
254226031Sstas    return sl_command (commands, argc, argv);
255226031Sstas}
256