1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2008 Doug Rabson
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/kobj.h>
35#include <sys/lock.h>
36#include <sys/malloc.h>
37#include <sys/mutex.h>
38
39#include <rpc/rpc.h>
40#include <rpc/rpcsec_gss.h>
41
42#include "rpcsec_gss_int.h"
43
44bool_t
45rpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret)
46{
47	gss_OID oid = kgss_find_mech_by_name(mech);
48
49	if (oid) {
50		*oid_ret = oid;
51		return (TRUE);
52	}
53	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
54	return (FALSE);
55}
56
57bool_t
58rpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret)
59{
60	const char *name = kgss_find_mech_by_oid(oid);
61
62	if (name) {
63		*mech_ret = name;
64		return (TRUE);
65	}
66	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
67	return (FALSE);
68}
69
70bool_t
71rpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret)
72{
73
74	if (!strcmp(qop, "default")) {
75		*num_ret = GSS_C_QOP_DEFAULT;
76		return (TRUE);
77	}
78	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
79	return (FALSE);
80}
81
82const char *
83_rpc_gss_num_to_qop(const char *mech, u_int num)
84{
85
86	if (num == GSS_C_QOP_DEFAULT)
87		return "default";
88
89	return (NULL);
90}
91
92const char **
93rpc_gss_get_mechanisms(void)
94{
95	static const char **mech_names = NULL;
96	struct kgss_mech *km;
97	int count;
98
99	if (mech_names)
100		return (mech_names);
101
102	count = 0;
103	LIST_FOREACH(km, &kgss_mechs, km_link) {
104		count++;
105	}
106	count++;
107
108	mech_names = malloc(count * sizeof(const char *), M_RPC, M_WAITOK);
109	count = 0;
110	LIST_FOREACH(km, &kgss_mechs, km_link) {
111		mech_names[count++] = km->km_mech_name;
112	}
113	mech_names[count++] = NULL;
114
115	return (mech_names);
116}
117
118#if 0
119const char **
120rpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service)
121{
122	struct mech_info *info;
123
124	_rpc_gss_load_mech();
125	_rpc_gss_load_qop();
126	SLIST_FOREACH(info, &mechs, link) {
127		if (!strcmp(mech, info->name)) {
128			/*
129			 * I'm not sure what to do with service
130			 * here. The Solaris manpages are not clear on
131			 * the subject and the OpenSolaris code just
132			 * sets it to rpc_gss_svc_privacy
133			 * unconditionally with a comment noting that
134			 * it is bogus.
135			 */
136			*service = rpc_gss_svc_privacy;
137			return info->qops;
138		}
139	}
140
141	_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
142	return (NULL);
143}
144#endif
145
146bool_t
147rpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo)
148{
149
150	*vers_hi = 1;
151	*vers_lo = 1;
152	return (TRUE);
153}
154
155bool_t
156rpc_gss_is_installed(const char *mech)
157{
158	gss_OID oid = kgss_find_mech_by_name(mech);
159
160	if (oid)
161		return (TRUE);
162	else
163		return (FALSE);
164}
165
166