1184588Sdfr/*-
2184588Sdfr * Copyright (c) 2008 Doug Rabson
3184588Sdfr * All rights reserved.
4184588Sdfr *
5184588Sdfr * Redistribution and use in source and binary forms, with or without
6184588Sdfr * modification, are permitted provided that the following conditions
7184588Sdfr * are met:
8184588Sdfr * 1. Redistributions of source code must retain the above copyright
9184588Sdfr *    notice, this list of conditions and the following disclaimer.
10184588Sdfr * 2. Redistributions in binary form must reproduce the above copyright
11184588Sdfr *    notice, this list of conditions and the following disclaimer in the
12184588Sdfr *    documentation and/or other materials provided with the distribution.
13184588Sdfr *
14184588Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15184588Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16184588Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17184588Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18184588Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19184588Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20184588Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21184588Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22184588Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23184588Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24184588Sdfr * SUCH DAMAGE.
25184588Sdfr */
26184588Sdfr
27184588Sdfr#include <sys/cdefs.h>
28184588Sdfr__FBSDID("$FreeBSD$");
29184588Sdfr
30184588Sdfr#include <sys/param.h>
31184588Sdfr#include <sys/systm.h>
32184588Sdfr#include <sys/kobj.h>
33184588Sdfr#include <sys/lock.h>
34184588Sdfr#include <sys/malloc.h>
35184588Sdfr#include <sys/mutex.h>
36184588Sdfr
37184588Sdfr#include <rpc/rpc.h>
38184588Sdfr#include <rpc/rpcsec_gss.h>
39184588Sdfr
40184588Sdfr#include "rpcsec_gss_int.h"
41184588Sdfr
42184588Sdfrbool_t
43184588Sdfrrpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret)
44184588Sdfr{
45184588Sdfr	gss_OID oid = kgss_find_mech_by_name(mech);
46184588Sdfr
47184588Sdfr	if (oid) {
48184588Sdfr		*oid_ret = oid;
49184588Sdfr		return (TRUE);
50184588Sdfr	}
51184588Sdfr	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
52184588Sdfr	return (FALSE);
53184588Sdfr}
54184588Sdfr
55184588Sdfrbool_t
56184588Sdfrrpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret)
57184588Sdfr{
58184588Sdfr	const char *name = kgss_find_mech_by_oid(oid);
59184588Sdfr
60184588Sdfr	if (name) {
61184588Sdfr		*mech_ret = name;
62184588Sdfr		return (TRUE);
63184588Sdfr	}
64184588Sdfr	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
65184588Sdfr	return (FALSE);
66184588Sdfr}
67184588Sdfr
68184588Sdfrbool_t
69184588Sdfrrpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret)
70184588Sdfr{
71184588Sdfr
72184588Sdfr	if (!strcmp(qop, "default")) {
73184588Sdfr		*num_ret = GSS_C_QOP_DEFAULT;
74184588Sdfr		return (TRUE);
75184588Sdfr	}
76184588Sdfr	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
77184588Sdfr	return (FALSE);
78184588Sdfr}
79184588Sdfr
80184588Sdfrconst char *
81184588Sdfr_rpc_gss_num_to_qop(const char *mech, u_int num)
82184588Sdfr{
83184588Sdfr
84184588Sdfr	if (num == GSS_C_QOP_DEFAULT)
85184588Sdfr		return "default";
86184588Sdfr
87184588Sdfr	return (NULL);
88184588Sdfr}
89184588Sdfr
90184588Sdfrconst char **
91184588Sdfrrpc_gss_get_mechanisms(void)
92184588Sdfr{
93184588Sdfr	static const char **mech_names = NULL;
94184588Sdfr	struct kgss_mech *km;
95184588Sdfr	int count;
96184588Sdfr
97184588Sdfr	if (mech_names)
98184588Sdfr		return (mech_names);
99184588Sdfr
100184588Sdfr	count = 0;
101184588Sdfr	LIST_FOREACH(km, &kgss_mechs, km_link) {
102184588Sdfr		count++;
103184588Sdfr	}
104184588Sdfr	count++;
105184588Sdfr
106184588Sdfr	mech_names = malloc(count * sizeof(const char *), M_RPC, M_WAITOK);
107184588Sdfr	count = 0;
108184588Sdfr	LIST_FOREACH(km, &kgss_mechs, km_link) {
109184588Sdfr		mech_names[count++] = km->km_mech_name;
110184588Sdfr	}
111184588Sdfr	mech_names[count++] = NULL;
112184588Sdfr
113184588Sdfr	return (mech_names);
114184588Sdfr}
115184588Sdfr
116184588Sdfr#if 0
117184588Sdfrconst char **
118184588Sdfrrpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service)
119184588Sdfr{
120184588Sdfr	struct mech_info *info;
121184588Sdfr
122184588Sdfr	_rpc_gss_load_mech();
123184588Sdfr	_rpc_gss_load_qop();
124184588Sdfr	SLIST_FOREACH(info, &mechs, link) {
125184588Sdfr		if (!strcmp(mech, info->name)) {
126184588Sdfr			/*
127184588Sdfr			 * I'm not sure what to do with service
128184588Sdfr			 * here. The Solaris manpages are not clear on
129184588Sdfr			 * the subject and the OpenSolaris code just
130184588Sdfr			 * sets it to rpc_gss_svc_privacy
131184588Sdfr			 * unconditionally with a comment noting that
132184588Sdfr			 * it is bogus.
133184588Sdfr			 */
134184588Sdfr			*service = rpc_gss_svc_privacy;
135184588Sdfr			return info->qops;
136184588Sdfr		}
137184588Sdfr	}
138184588Sdfr
139184588Sdfr	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
140184588Sdfr	return (NULL);
141184588Sdfr}
142184588Sdfr#endif
143184588Sdfr
144184588Sdfrbool_t
145184588Sdfrrpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo)
146184588Sdfr{
147184588Sdfr
148184588Sdfr	*vers_hi = 1;
149184588Sdfr	*vers_lo = 1;
150184588Sdfr	return (TRUE);
151184588Sdfr}
152184588Sdfr
153184588Sdfrbool_t
154184588Sdfrrpc_gss_is_installed(const char *mech)
155184588Sdfr{
156184588Sdfr	gss_OID oid = kgss_find_mech_by_name(mech);
157184588Sdfr
158184588Sdfr	if (oid)
159184588Sdfr		return (TRUE);
160184588Sdfr	else
161184588Sdfr		return (FALSE);
162184588Sdfr}
163184588Sdfr
164