RPCSEC_MANS = rpcsec_gss.3t rpc_gss_get_error.3t \
rpc_gss_get_mechanisms.3t rpc_gss_get_mech_info.3t \
rpc_gss_get_versions.3t rpc_gss_is_installed.3t \
- rpc_gss_mech_to_oid.3t rpc_gss_qop_to_num.3t
+ rpc_gss_mech_to_oid.3t rpc_gss_qop_to_num.3t \
+ rpc_gss_max_data_length.3t rpc_gss_seccreate.3t \
+ rpc_gss_set_defaults.3t
dist_man5_MANS = netconfig.5
dist_man3_MANS = $(LOOKUP_MANS) $(NETCONFIG_MANS) \
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_MAX_DATA_LENGTH 3
+.Os
+.Sh NAME
+.Nm rpc_gss_max_data_length
+.Nd "calculate maximum data size"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft int
+.Fn rpc_gss_max_data_length "AUTH *auth" "int max_tp_unit_len"
+.Sh DESCRIPTION
+Calculate the maximum message size that will fit into a packet of size
+.Fa max_tp_unit_len ,
+given the current service and QoP setting.
+.Sh PARAMETERS
+.Bl -tag -width ".It max_tp_unit_len"
+.It auth
+A handle to a RPCSEC_GSS security context
+.It max_tp_unit_len
+Maximum packet size of the underlying transport protocol
+.El
+.Sh RETURN VALUES
+The maximum message size that can be encoded
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_max_data_length
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_SECCREATE 3
+.Os
+.Sh NAME
+.Nm rpc_gss_seccreate
+.Nd "create a security context using the RPCSEC_GSS protocol"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft AUTH *
+.Fo rpc_gss_seccreate
+.Fa "CLIENT *clnt"
+.Fa "const char *principal"
+.Fa "const char *mechanism"
+.Fa "rpc_gss_service_t service"
+.Fa "const char *qop"
+.Fa "rpc_gss_options_req_t *options_req"
+.Fa "rpc_gss_options_ret_t *options_ret"
+.Fc
+.Sh DESCRIPTION
+This function is used to establish a security context between an
+application and a remote peer using the RPSEC_GSS protocol.
+.Sh PARAMETERS
+.Bl -tag -width "options_req"
+.It clnt
+An RPC handle which is connected to the remote peer
+.It principal
+The name of the service principal on the remote peer.
+For instance, a principal such as
+.Qq nfs@server.example.com
+might be used by an application which needs to contact an NFS server
+.It mechanism
+The desired mechanism for this security context.
+The value of mechanism should be the name of one of the security
+mechanisms listed in /etc/gss/mech.
+.It service
+Type of service requested.
+.Bl -tag -width "rpc_gss_svc_integrity"
+.It rpc_gss_svc_default
+The default - typically the same as
+.Dv rpc_gss_svc_none .
+.It rpc_gss_svc_none
+RPC headers only are integrity protected by a checksum.
+.It rpc_gss_svc_integrity
+RPC headers and data are integrity protected by a checksum.
+.It rpc_gss_svc_privacy
+RPC headers are integrity protected by a checksum and data is encrypted.
+.El
+.It qop
+Desired quality of protection or NULL for the default.
+Available values are listed in /etc/gss/qop
+.It options_req
+Extra security context options to be passed to the underlying GSS-API
+mechanism.
+Pass
+.Dv NULL
+to supply default values.
+.It options_ret
+Various values returned by the underlying GSS-API mechanism.
+Pass
+.Dv NULL
+if these values are not required.
+.El
+.Sh RETURN VALUES
+If the security context was created successfully, a pointer to an
+.Vt AUTH
+structure that represents the context is returned.
+To use this security context for subsequent RPC calls, set
+.Va clnt->cl_auth
+to this value.
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_seccreate
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr mech 5 ,
+.Xr qop 5 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_SET_DEFAULTS 3
+.Os
+.Sh NAME
+.Nm rpc_gss_set_defaults
+.Nd "set service and quality of protection"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft bool_t
+.Fo rpc_gss_set_defaults
+.Fa "AUTH *auth"
+.Fa "rpc_gss_service_t service"
+.Fa "const char *qop"
+.Fc
+.Sh DESCRIPTION
+Set the service and quality of protection to be used for RPC requests.
+The new values apply for the rest of the lifetime of the context
+(unless changed again with this function).
+.Sh PARAMETERS
+.Bl -tag -width ".It service"
+.It service
+The service type to use for subsequent RPC requests
+.It qop
+The quality of protection to use or NULL for the default
+.El
+.Sh RETURN VALUES
+Returns
+.Dv TRUE
+if the values were set
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_set_defaults
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
#include <rpc/xdr.h>
#include <rpc/auth.h>
#include <rpc/auth_gss.h>
+#include <rpc/rpcsec_gss.h>
#include <rpc/clnt.h>
#include <netinet/in.h>
-#include <gssapi/gssapi.h>
#include "debug.h"
static bool_t authgss_wrap(AUTH *, XDR *, xdrproc_t, caddr_t);
static bool_t authgss_unwrap(AUTH *, XDR *, xdrproc_t, caddr_t);
+void rpc_gss_set_error(int);
+void rpc_gss_clear_error(void);
+bool_t rpc_gss_oid_to_mech(rpc_gss_OID, char **);
/*
* from mit-krb5-1.2.1 mechglue/mglueP.h:
gd->ctx, gd->sec.qop,
gd->sec.svc, gd->gc.gc_seq));
}
+
+static AUTH *
+_rpc_gss_seccreate_error(int system_error)
+{
+ rpc_gss_set_error(system_error);
+ return NULL;
+}
+
+/*
+ * External API: Create a GSS security context for this "clnt"
+ *
+ * clnt: a valid RPC CLIENT structure
+ * principal: NUL-terminated C string containing GSS principal
+ * mechanism: NUL-terminated C string containing GSS mechanism name
+ * service: GSS security value to use
+ * qop: NUL-terminated C string containing QOP name
+ * req: pointer to additional request parameters, or NULL
+ * ret: pointer to additional results, or NULL
+ *
+ * Returns pointer to a filled in RPC AUTH structure or NULL.
+ * Caller must free returned structure with AUTH_DESTROY.
+ */
+AUTH *
+rpc_gss_seccreate(CLIENT *clnt, char *principal, char *mechanism,
+ rpc_gss_service_t service, char *qop,
+ rpc_gss_options_req_t *req, rpc_gss_options_ret_t *ret)
+{
+ rpc_gss_options_ret_t options_ret;
+ OM_uint32 maj_stat, min_stat;
+ struct rpc_gss_sec sec = {
+ .req_flags = GSS_C_MUTUAL_FLAG,
+ .cred = GSS_C_NO_CREDENTIAL,
+ };
+ struct rpc_gss_data *gd;
+ AUTH *auth, *save_auth;
+ gss_buffer_desc sname;
+
+ if (clnt == NULL || principal == NULL)
+ return _rpc_gss_seccreate_error(EINVAL);
+
+ if (rpc_gss_mech_to_oid(mechanism, &sec.mech) == FALSE)
+ return NULL;
+
+ sec.qop = GSS_C_QOP_DEFAULT;
+ if (qop != NULL) {
+ u_int qop_num;
+ if (rpc_gss_qop_to_num(qop, mechanism, &qop_num) == FALSE)
+ return NULL;
+ sec.qop = qop_num;
+ }
+
+ switch (service) {
+ case rpcsec_gss_svc_none:
+ sec.svc = RPCSEC_GSS_SVC_NONE;
+ break;
+ case rpcsec_gss_svc_integrity:
+ sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
+ break;
+ case rpcsec_gss_svc_privacy:
+ sec.svc = RPCSEC_GSS_SVC_PRIVACY;
+ break;
+ case rpcsec_gss_svc_default:
+ sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
+ break;
+ default:
+ return _rpc_gss_seccreate_error(ENOENT);
+ }
+
+ if (req != NULL) {
+ sec.req_flags = req->req_flags;
+ sec.cred = req->my_cred;
+ }
+
+ if (ret == NULL)
+ ret = &options_ret;
+ memset(ret, 0, sizeof(*ret));
+
+ auth = calloc(1, sizeof(*auth));
+ gd = calloc(1, sizeof(*gd));
+ if (auth == NULL || gd == NULL) {
+ free(gd);
+ free(auth);
+ return _rpc_gss_seccreate_error(ENOMEM);
+ }
+
+ sname.value = principal;
+ sname.length = strlen(principal);
+ maj_stat = gss_import_name(&min_stat, &sname,
+ (gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
+ &gd->name);
+ if (maj_stat != GSS_S_COMPLETE) {
+ ret->major_status = maj_stat;
+ ret->minor_status = min_stat;
+ free(gd);
+ free(auth);
+ return _rpc_gss_seccreate_error(ENOMEM);
+ }
+
+ gd->clnt = clnt;
+ gd->ctx = GSS_C_NO_CONTEXT;
+ gd->sec = sec;
+
+ gd->gc.gc_v = RPCSEC_GSS_VERSION;
+ gd->gc.gc_proc = RPCSEC_GSS_INIT;
+ gd->gc.gc_svc = sec.svc;
+
+ auth->ah_ops = &authgss_ops;
+ auth->ah_private = (caddr_t)gd;
+
+ save_auth = clnt->cl_auth;
+ clnt->cl_auth = auth;
+
+ if (authgss_refresh(auth, NULL) == FALSE) {
+ authgss_destroy(auth);
+ auth = NULL;
+ } else {
+ rpc_gss_clear_error();
+ auth_get(auth);
+ }
+
+ clnt->cl_auth = save_auth;
+
+ return auth;
+}
+
+/*
+ * External API: Modify an AUTH's service and QOP settings
+ *
+ * auth: a valid RPC AUTH structure
+ * service: GSS security value to use
+ * qop: NUL-terminated C string containing QOP name
+ *
+ * Returns TRUE if successful, otherwise FALSE is returned.
+ */
+bool_t
+rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service, char *qop)
+{
+ struct rpc_gss_data *gd;
+ char *mechanism;
+ u_int qop_num;
+
+ if (auth == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ gd = AUTH_PRIVATE(auth);
+ if (gd == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ if (rpc_gss_oid_to_mech(gd->sec.mech, &mechanism) == FALSE)
+ return FALSE;
+
+ qop_num = GSS_C_QOP_DEFAULT;
+ if (qop != NULL) {
+ if (rpc_gss_qop_to_num(qop, mechanism, &qop_num) == FALSE)
+ return FALSE;
+ }
+
+ switch (service) {
+ case rpcsec_gss_svc_none:
+ gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_NONE;
+ break;
+ case rpcsec_gss_svc_integrity:
+ gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
+ break;
+ case rpcsec_gss_svc_privacy:
+ gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_PRIVACY;
+ break;
+ case rpcsec_gss_svc_default:
+ gd->gc.gc_svc = gd->sec.svc = RPCSEC_GSS_SVC_INTEGRITY;
+ break;
+ default:
+ rpc_gss_set_error(ENOENT);
+ return FALSE;
+ }
+
+ gd->sec.qop = (gss_qop_t)qop_num;
+ rpc_gss_clear_error();
+ return TRUE;
+}
+
+/*
+ * External API: Return maximum data size for a security mechanism and transport
+ *
+ * auth: a valid RPC AUTH structure
+ * maxlen: transport's maximum data size, in bytes
+ *
+ * Returns maximum data size given transformations done by current
+ * security setting of "auth", in bytes, or zero if that value
+ * cannot be determined.
+ */
+int
+rpc_gss_max_data_length(AUTH *auth, int maxlen)
+{
+ OM_uint32 max_input_size, maj_stat, min_stat;
+ struct rpc_gss_data *gd;
+ int conf_req_flag;
+ int result;
+
+ if (auth == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return 0;
+ }
+
+ gd = AUTH_PRIVATE(auth);
+ if (gd == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return 0;
+ }
+
+ switch (gd->sec.svc) {
+ case RPCSEC_GSS_SVC_NONE:
+ rpc_gss_clear_error();
+ return maxlen;
+ case RPCSEC_GSS_SVC_INTEGRITY:
+ conf_req_flag = 0;
+ break;
+ case RPCSEC_GSS_SVC_PRIVACY:
+ conf_req_flag = 1;
+ break;
+ default:
+ rpc_gss_set_error(ENOENT);
+ return 0;
+ }
+
+ result = 0;
+ maj_stat = gss_wrap_size_limit(&min_stat, gd->ctx, conf_req_flag,
+ gd->sec.qop, maxlen, &max_input_size);
+ if (maj_stat == GSS_S_COMPLETE)
+ if ((int)max_input_size > 0)
+ result = (int)max_input_size;
+ rpc_gss_clear_error();
+ return result;
+}