Add an implementation of the RPCSEC_GSS authentication protocol for RPC. This

is based on an old implementation from the University of Michigan with lots of
changes and fixes by me and the addition of a Solaris-compatible API.

Sponsored by:	Isilon Systems
Reviewed by:	alfred
This commit is contained in:
Doug Rabson 2008-08-06 14:02:05 +00:00
parent 503765e486
commit 8f55a568f6
53 changed files with 5047 additions and 94 deletions

View File

@ -53,6 +53,7 @@
.ds doc-str-Lb-libmemstat Kernel Memory Allocator Statistics Library (libmemstat, \-lmemstat)
.ds doc-str-Lb-libnetgraph Netgraph User Library (libnetgraph, \-lnetgraph)
.ds doc-str-Lb-libpmc Performance Monitoring Counters Interface Library (libpmc, \-lpmc)
.ds doc-str-Lb-librpcsec_gss RPC GSS-API Authentication Library (librpcsec_gss, \-lrpcsec_gss)
.ds doc-str-Lb-librpcsvc RPC Service Library (librpcsvc, \-lrpcsvc)
.ds doc-str-Lb-libsdp Bluetooth Service Discovery Protocol User Library (libsdp, \-lsdp)
.ds doc-str-Lb-libthr 1:1 Threading Library (libthr, \-lthr)

View File

@ -837,6 +837,15 @@ OM_uint32 gss_pseudo_random
gss_buffer_t /* buffer for result */
);
#ifdef _UID_T_DECLARED
OM_uint32 gss_pname_to_uid
(OM_uint32 *, /* minor status */
const gss_name_t pname, /* principal name */
const gss_OID mech, /* mechanism to query */
uid_t *uidp /* pointer to UID for result */
);
#endif
__END_DECLS
#endif /* _GSSAPI_GSSAPI_H_ */

View File

@ -11,7 +11,7 @@ XFILES= rpcb_prot.x
HFILES= auth.h auth_unix.h clnt.h clnt_soc.h clnt_stat.h \
nettype.h pmap_clnt.h pmap_prot.h pmap_rmt.h raw.h \
rpc.h rpc_msg.h rpcb_clnt.h rpcent.h rpc_com.h \
rpc.h rpc_msg.h rpcb_clnt.h rpcent.h rpc_com.h rpcsec_gss.h \
svc.h svc_auth.h svc_soc.h svc_dg.h xdr.h
# Secure RPC

View File

@ -132,7 +132,7 @@ enum auth_stat {
* failed locally
*/
AUTH_INVALIDRESP=6, /* bogus response verifier */
AUTH_FAILED=7 /* some unknown reason */
AUTH_FAILED=7, /* some unknown reason */
#ifdef KERBEROS
/*
* kerberos errors
@ -142,8 +142,14 @@ enum auth_stat {
AUTH_TIMEEXPIRE = 9, /* time of credential expired */
AUTH_TKT_FILE = 10, /* something wrong with ticket file */
AUTH_DECODE = 11, /* can't decode authenticator */
AUTH_NET_ADDR = 12 /* wrong net address in ticket */
AUTH_NET_ADDR = 12, /* wrong net address in ticket */
#endif /* KERBEROS */
/*
* RPCSEC_GSS errors
*/
RPCSEC_GSS_CREDPROBLEM = 13,
RPCSEC_GSS_CTXPROBLEM = 14,
RPCSEC_GSS_NODISPATCH = 0x8000000
};
union des_block {
@ -352,5 +358,13 @@ __END_DECLS
#define AUTH_DH 3 /* for Diffie-Hellman mechanism */
#define AUTH_DES AUTH_DH /* for backward compatibility */
#define AUTH_KERB 4 /* kerberos style */
#define RPCSEC_GSS 6 /* RPCSEC_GSS */
/*
* Pseudo auth flavors for RPCSEC_GSS.
*/
#define RPCSEC_GSS_KRB5 390003
#define RPCSEC_GSS_KRB5I 390004
#define RPCSEC_GSS_KRB5P 390005
#endif /* !_RPC_AUTH_H */

179
include/rpc/rpcsec_gss.h Normal file
View File

@ -0,0 +1,179 @@
/*-
* Copyright (c) 2008 Doug Rabson
* All rights reserved.
*
* 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$
*/
#ifndef _RPCSEC_GSS_H
#define _RPCSEC_GSS_H
#include <gssapi/gssapi.h>
#ifndef MAX_GSS_MECH
#define MAX_GSS_MECH 64
#endif
/*
* Define the types of security service required for rpc_gss_seccreate().
*/
typedef enum {
rpc_gss_svc_default = 0,
rpc_gss_svc_none = 1,
rpc_gss_svc_integrity = 2,
rpc_gss_svc_privacy = 3
} rpc_gss_service_t;
/*
* Structure containing options for rpc_gss_seccreate().
*/
typedef struct {
int req_flags; /* GSS request bits */
int time_req; /* requested credential lifetime */
gss_cred_id_t my_cred; /* GSS credential */
gss_channel_bindings_t input_channel_bindings;
} rpc_gss_options_req_t;
/*
* Structure containing options returned by rpc_gss_seccreate().
*/
typedef struct {
int major_status;
int minor_status;
u_int rpcsec_version;
int ret_flags;
int time_req;
gss_ctx_id_t gss_context;
char actual_mechanism[MAX_GSS_MECH];
} rpc_gss_options_ret_t;
/*
* Client principal type. Used as an argument to
* rpc_gss_get_principal_name(). Also referenced by the
* rpc_gss_rawcred_t structure.
*/
typedef struct {
int len;
char name[1];
} *rpc_gss_principal_t;
/*
* Structure for raw credentials used by rpc_gss_getcred() and
* rpc_gss_set_callback().
*/
typedef struct {
u_int version; /* RPC version number */
const char *mechanism; /* security mechanism */
const char *qop; /* quality of protection */
rpc_gss_principal_t client_principal; /* client name */
const char *svc_principal; /* server name */
rpc_gss_service_t service; /* service type */
} rpc_gss_rawcred_t;
/*
* Unix credentials derived from raw credentials. Returned by
* rpc_gss_getcred().
*/
typedef struct {
uid_t uid; /* user ID */
gid_t gid; /* group ID */
short gidlen;
gid_t *gidlist; /* list of groups */
} rpc_gss_ucred_t;
/*
* Structure used to enforce a particular QOP and service.
*/
typedef struct {
bool_t locked;
rpc_gss_rawcred_t *raw_cred;
} rpc_gss_lock_t;
/*
* Callback structure used by rpc_gss_set_callback().
*/
typedef struct {
u_int program; /* RPC program number */
u_int version; /* RPC version number */
/* user defined callback */
bool_t (*callback)(struct svc_req *req,
gss_cred_id_t deleg,
gss_ctx_id_t gss_context,
rpc_gss_lock_t *lock,
void **cookie);
} rpc_gss_callback_t;
/*
* Structure used to return error information by rpc_gss_get_error()
*/
typedef struct {
int rpc_gss_error;
int system_error; /* same as errno */
} rpc_gss_error_t;
/*
* Values for rpc_gss_error
*/
#define RPC_GSS_ER_SUCCESS 0 /* no error */
#define RPC_GSS_ER_SYSTEMERROR 1 /* system error */
__BEGIN_DECLS
AUTH *rpc_gss_seccreate(CLIENT *clnt, const char *principal,
const char *mechanism, rpc_gss_service_t service, const char *qop,
rpc_gss_options_req_t *options_req, rpc_gss_options_ret_t *options_ret);
bool_t rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service,
const char *qop);
int rpc_gss_max_data_length(AUTH *handle, int max_tp_unit_len);
void rpc_gss_get_error(rpc_gss_error_t *error);
bool_t rpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret);
bool_t rpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret);
bool_t rpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret);
const char **rpc_gss_get_mechanisms(void);
const char **rpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service);
bool_t rpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo);
bool_t rpc_gss_is_installed(const char *mech);
bool_t rpc_gss_set_svc_name(const char *principal, const char *mechanism,
u_int req_time, u_int program, u_int version);
bool_t rpc_gss_getcred(struct svc_req *req, rpc_gss_rawcred_t **rcred,
rpc_gss_ucred_t **ucred, void **cookie);
bool_t rpc_gss_set_callback(rpc_gss_callback_t *cb);
bool_t rpc_gss_get_principal_name(rpc_gss_principal_t *principal,
const char *mech, const char *name, const char *node, const char *domain);
int rpc_gss_svc_max_data_length(struct svc_req *req, int max_tp_unit_len);
/*
* Internal interface from the RPC implementation.
*/
bool_t __rpc_gss_wrap(AUTH *auth, void *header, size_t headerlen,
XDR* xdrs, xdrproc_t xdr_args, void *args_ptr);
bool_t __rpc_gss_unwrap(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args,
void *args_ptr);
bool_t __rpc_gss_set_error(int rpc_gss_error, int system_error);
__END_DECLS
#endif /* !_RPCSEC_GSS_H */

View File

@ -126,6 +126,27 @@ typedef struct __rpc_svcxprt {
int xp_type; /* transport type */
} SVCXPRT;
/*
* Interface to server-side authentication flavors.
*/
typedef struct __rpc_svcauth {
struct svc_auth_ops {
int (*svc_ah_wrap)(struct __rpc_svcauth *, XDR *,
xdrproc_t, caddr_t);
int (*svc_ah_unwrap)(struct __rpc_svcauth *, XDR *,
xdrproc_t, caddr_t);
} *svc_ah_ops;
void *svc_ah_private;
} SVCAUTH;
/*
* Server transport extensions (accessed via xp_p3).
*/
typedef struct __rpc_svcxprt_ext {
int xp_flags; /* versquiet */
SVCAUTH xp_auth; /* interface to auth methods */
} SVCXPRT_EXT;
/*
* Service request
*/
@ -184,6 +205,20 @@ struct svc_req {
#define SVC_CONTROL(xprt, rq, in) \
(*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in))
#define SVC_EXT(xprt) \
((SVCXPRT_EXT *) xprt->xp_p3)
#define SVC_AUTH(xprt) \
(SVC_EXT(xprt)->xp_auth)
/*
* Operations defined on an SVCAUTH handle
*/
#define SVCAUTH_WRAP(auth, xdrs, xfunc, xwhere) \
((auth)->svc_ah_ops->svc_ah_wrap(auth, xdrs, xfunc, xwhere))
#define SVCAUTH_UNWRAP(auth, xdrs, xfunc, xwhere) \
((auth)->svc_ah_ops->svc_ah_unwrap(auth, xdrs, xfunc, xwhere))
/*
* Service registration
*
@ -297,6 +332,12 @@ extern fd_set svc_fdset;
extern int svc_fds;
#endif /* def FD_SETSIZE */
/*
* A set of null auth methods used by any authentication protocols
* that don't need to inspect or modify the message body.
*/
extern SVCAUTH _svc_auth_null;
/*
* a small program implemented by the svc_rpc implementation itself;
* also see clnt.h for protocol numbers.
@ -306,6 +347,8 @@ extern void rpctest_service(void);
__END_DECLS
__BEGIN_DECLS
extern SVCXPRT *svc_xprt_alloc(void);
extern void svc_xprt_free(SVCXPRT *);
extern void svc_getreq(int);
extern void svc_getreqset(fd_set *);
extern void svc_getreq_common(int);

View File

@ -46,6 +46,7 @@ SRCS= 8003.c \
inquire_mechs_for_name.c \
inquire_names_for_mech.c \
inquire_sec_context_by_oid.c \
pname_to_uid.c \
prefix.c \
prf.c \
process_context_token.c \

View File

@ -0,0 +1,59 @@
/*-
* 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$ */
#include <pwd.h>
#include "krb5/gsskrb5_locl.h"
OM_uint32
_gsskrb5_pname_to_uid(OM_uint32 *minor_status, const gss_name_t pname,
const gss_OID mech, uid_t *uidp)
{
krb5_context context;
krb5_const_principal name = (krb5_const_principal) pname;
krb5_error_code kret;
char lname[MAXLOGNAME + 1], buf[128];
struct passwd pwd, *pw;
GSSAPI_KRB5_INIT (&context);
kret = krb5_aname_to_localname(context, name, sizeof(lname), lname);
if (kret) {
*minor_status = kret;
return (GSS_S_FAILURE);
}
*minor_status = 0;
getpwnam_r(lname, &pwd, buf, sizeof(buf), &pw);
if (pw) {
*uidp = pw->pw_uid;
return (GSS_S_COMPLETE);
} else {
return (GSS_S_FAILURE);
}
}

View File

@ -22,6 +22,7 @@
# libtacplus must be built before libpam.
# libutil must be built before libpam.
# libypclnt must be built before libpam.
# libgssapi must be built before librpcsec_gss
#
# Otherwise, the SUBDIR list should be in alphabetical order.
@ -31,7 +32,7 @@ SUBDIR= ${_csu} libc libbsm libcom_err libcrypt libelf libkvm msun libmd \
libbegemot ${_libbluetooth} libbsnmp libbz2 \
libcalendar libcam libcompat libdevinfo libdevstat libdisk \
libdwarf libedit libexpat libfetch libftpio libgeom ${_libgpib} \
${_libgssapi} libipsec \
${_libgssapi} ${_librpcsec_gss} libipsec \
${_libipx} libkiconv libmagic libmemstat ${_libmilter} ${_libmp} \
${_libncp} ${_libngatm} libopie libpam libpcap \
libpmc libproc librt ${_libsdp} ${_libsm} ${_libsmb} \
@ -62,6 +63,7 @@ _libsdp= libsdp
.if ${MK_GSSAPI} != "no"
_libgssapi= libgssapi
_librpcsec_gss= librpcsec_gss
.endif
.if ${MK_IPX} != "no"

View File

@ -8,8 +8,9 @@ SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \
svc_raw.c svc_run.c svc_simple.c svc_vc.c
rpcb_st_xdr.c rpcsec_gss_stub.c svc.c svc_auth.c svc_dg.c \
svc_auth_unix.c svc_generic.c svc_raw.c svc_run.c svc_simple.c \
svc_vc.c
# Secure-RPC
SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \

View File

@ -244,4 +244,8 @@ FBSDprivate_1.0 {
* Remove this hack if rpcinfo stops building with it.
*/
__svc_clean_idle;
__rpc_gss_unwrap;
__rpc_gss_unwrap_stub;
__rpc_gss_wrap;
__rpc_gss_wrap_stub;
};

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@ -113,6 +114,8 @@ static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory";
/* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */
#define MCALL_MSG_SIZE 24
/*
* Private data kept per client handle
*/
@ -127,6 +130,7 @@ struct cu_data {
XDR cu_outxdrs;
u_int cu_xdrpos;
u_int cu_sendsz; /* send size */
char cu_outhdr[MCALL_MSG_SIZE];
char *cu_outbuf;
u_int cu_recvsz; /* recv size */
int cu_async;
@ -253,13 +257,16 @@ clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz)
call_msg.rm_xid = __RPC_GETXID(&now);
call_msg.rm_call.cb_prog = program;
call_msg.rm_call.cb_vers = version;
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outhdr, MCALL_MSG_SIZE,
XDR_ENCODE);
if (! xdr_callhdr(&cu->cu_outxdrs, &call_msg)) {
rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */
rpc_createerr.cf_error.re_errno = 0;
goto err2;
}
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
XDR_DESTROY(&cu->cu_outxdrs);
xdrmem_create(&cu->cu_outxdrs, cu->cu_outbuf, sendsz, XDR_ENCODE);
/* XXX fvdl - do we still want this? */
#if 0
@ -312,6 +319,7 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
XDR reply_xdrs;
bool_t ok;
int nrefreshes = 2; /* number of times to refresh cred */
int nretries = 0; /* number of times we retransmitted */
struct timeval timeout;
struct timeval retransmit_time;
struct timeval next_sendtime, starttime, time_waited, tv;
@ -375,25 +383,37 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
kin_len = 1;
call_again:
xdrs = &(cu->cu_outxdrs);
if (cu->cu_async == TRUE && xargs == NULL)
goto get_reply;
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, cu->cu_xdrpos);
/*
* the transaction is the first thing in the out buffer
* XXX Yes, and it's in network byte order, so we should to
* be careful when we increment it, shouldn't we.
*/
xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf));
xid = ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr));
xid++;
*(u_int32_t *)(void *)(cu->cu_outbuf) = htonl(xid);
*(u_int32_t *)(void *)(cu->cu_outhdr) = htonl(xid);
call_again_same_xid:
xdrs = &(cu->cu_outxdrs);
if (cu->cu_async == TRUE && xargs == NULL)
goto get_reply;
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, 0);
if ((! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xargs)(xdrs, argsp))) {
cu->cu_error.re_status = RPC_CANTENCODEARGS;
goto out;
if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
if ((! XDR_PUTBYTES(xdrs, cu->cu_outhdr, cu->cu_xdrpos)) ||
(! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xargs)(xdrs, argsp))) {
cu->cu_error.re_status = RPC_CANTENCODEARGS;
goto out;
}
} else {
*(uint32_t *) &cu->cu_outhdr[cu->cu_xdrpos] = htonl(proc);
if (!__rpc_gss_wrap(cl->cl_auth, cu->cu_outhdr,
cu->cu_xdrpos + sizeof(uint32_t),
xdrs, xargs, argsp)) {
cu->cu_error.re_status = RPC_CANTENCODEARGS;
goto out;
}
}
outlen = (size_t)XDR_GETPOS(xdrs);
@ -420,8 +440,13 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
* (We assume that this is actually only executed once.)
*/
reply_msg.acpted_rply.ar_verf = _null_auth;
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
reply_msg.acpted_rply.ar_results.where = resultsp;
reply_msg.acpted_rply.ar_results.proc = xresults;
} else {
reply_msg.acpted_rply.ar_results.where = NULL;
reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
}
for (;;) {
/* Decide how long to wait. */
@ -483,7 +508,17 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
&retransmit_time);
timeradd(&next_sendtime, &retransmit_time,
&next_sendtime);
goto send_again;
nretries++;
/*
* When retransmitting a RPCSEC_GSS message,
* we must use a new sequence number (handled
* by __rpc_gss_wrap above).
*/
if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS)
goto send_again;
else
goto call_again_same_xid;
}
}
inlen = (socklen_t)recvlen;
@ -505,8 +540,37 @@ clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
if (cu->cu_error.re_status == RPC_SUCCESS) {
if (! AUTH_VALIDATE(cl->cl_auth,
&reply_msg.acpted_rply.ar_verf)) {
if (nretries &&
cl->cl_auth->ah_cred.oa_flavor
== RPCSEC_GSS)
/*
* If we retransmitted, its
* possible that we will
* receive a reply for one of
* the earlier transmissions
* (which will use an older
* RPCSEC_GSS sequence
* number). In this case, just
* go back and listen for a
* new reply. We could keep a
* record of all the seq
* numbers we have transmitted
* so far so that we could
* accept a reply for any of
* them here.
*/
goto get_reply;
cu->cu_error.re_status = RPC_AUTHERROR;
cu->cu_error.re_why = AUTH_INVALIDRESP;
} else {
if (cl->cl_auth->ah_cred.oa_flavor
== RPCSEC_GSS) {
if (!__rpc_gss_unwrap(cl->cl_auth,
&reply_xdrs, xresults,
resultsp))
cu->cu_error.re_status =
RPC_CANTDECODERES;
}
}
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
xdrs->x_op = XDR_FREE;
@ -670,12 +734,12 @@ clnt_dg_control(cl, request, info)
* This will get the xid of the PREVIOUS call
*/
*(u_int32_t *)info =
ntohl(*(u_int32_t *)(void *)cu->cu_outbuf);
ntohl(*(u_int32_t *)(void *)cu->cu_outhdr);
break;
case CLSET_XID:
/* This will set the xid of the NEXT call */
*(u_int32_t *)(void *)cu->cu_outbuf =
*(u_int32_t *)(void *)cu->cu_outhdr =
htonl(*(u_int32_t *)info - 1);
/* decrement by 1 as clnt_dg_call() increments once */
break;
@ -688,12 +752,12 @@ clnt_dg_control(cl, request, info)
* call_struct is changed
*/
*(u_int32_t *)info =
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr +
4 * BYTES_PER_XDR_UNIT));
break;
case CLSET_VERS:
*(u_int32_t *)(void *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
*(u_int32_t *)(void *)(cu->cu_outhdr + 4 * BYTES_PER_XDR_UNIT)
= htonl(*(u_int32_t *)info);
break;
@ -705,12 +769,12 @@ clnt_dg_control(cl, request, info)
* call_struct is changed
*/
*(u_int32_t *)info =
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
ntohl(*(u_int32_t *)(void *)(cu->cu_outhdr +
3 * BYTES_PER_XDR_UNIT));
break;
case CLSET_PROG:
*(u_int32_t *)(void *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
*(u_int32_t *)(void *)(cu->cu_outhdr + 3 * BYTES_PER_XDR_UNIT)
= htonl(*(u_int32_t *)info);
break;
case CLSET_ASYNC:

View File

@ -309,7 +309,14 @@ static const char *const auth_errlist[] = {
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
"Client credential too weak", /* 5 - AUTH_TOOWEAK */
"Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
"Failed (unspecified error)" /* 7 - AUTH_FAILED */
"Failed (unspecified error)", /* 7 - AUTH_FAILED */
"Kerberos generic error", /* 8 - AUTH_KERB_GENERIC*/
"Kerberos credential expired", /* 9 - AUTH_TIMEEXPIRE */
"Bad kerberos ticket file", /* 10 - AUTH_TKT_FILE */
"Can't decode kerberos authenticator", /* 11 - AUTH_DECODE */
"Address wrong in kerberos ticket", /* 12 - AUTH_NET_ADDR */
"GSS-API crediential problem", /* 13 - RPCSEC_GSS_CREDPROBLEM */
"GSS-API context problem" /* 14 - RPCSEC_GSS_CTXPROBLEM */
};
static char *

View File

@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <signal.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
#include "un-namespace.h"
#include "rpc_com.h"
#include "mt_misc.h"
@ -285,6 +286,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
}
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
XDR_DESTROY(&(ct->ct_xdrs));
assert(ct->ct_mpos + sizeof(uint32_t) <= MCALL_MSG_SIZE);
/*
* Create a client handle which uses xdrrec for serialization
@ -331,6 +333,7 @@ clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
int refreshes = 2;
sigset_t mask, newmask;
int rpc_lock_value;
bool_t reply_stat;
assert(cl != NULL);
@ -360,15 +363,28 @@ clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
ct->ct_error.re_status = RPC_SUCCESS;
x_id = ntohl(--(*msg_x_id));
if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
(! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xdr_args)(xdrs, args_ptr))) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
(! XDR_PUTINT32(xdrs, &proc)) ||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
(! (*xdr_args)(xdrs, args_ptr))) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
}
} else {
*(uint32_t *) &ct->ct_u.ct_mcallc[ct->ct_mpos] = htonl(proc);
if (! __rpc_gss_wrap(cl->cl_auth, ct->ct_u.ct_mcallc,
ct->ct_mpos + sizeof(uint32_t),
xdrs, xdr_args, args_ptr)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTENCODEARGS;
(void)xdrrec_endofrecord(xdrs, TRUE);
release_fd_lock(ct->ct_fd, mask);
return (ct->ct_error.re_status);
}
}
if (! xdrrec_endofrecord(xdrs, shipnow)) {
release_fd_lock(ct->ct_fd, mask);
@ -419,9 +435,18 @@ clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
&reply_msg.acpted_rply.ar_verf)) {
ct->ct_error.re_status = RPC_AUTHERROR;
ct->ct_error.re_why = AUTH_INVALIDRESP;
} else if (! (*xdr_results)(xdrs, results_ptr)) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status = RPC_CANTDECODERES;
} else {
if (cl->cl_auth->ah_cred.oa_flavor != RPCSEC_GSS) {
reply_stat = (*xdr_results)(xdrs, results_ptr);
} else {
reply_stat = __rpc_gss_unwrap(cl->cl_auth,
xdrs, xdr_results, results_ptr);
}
if (! reply_stat) {
if (ct->ct_error.re_status == RPC_SUCCESS)
ct->ct_error.re_status =
RPC_CANTDECODERES;
}
}
/* free verifier ... */
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {

View File

@ -0,0 +1,48 @@
/*-
* Copyright (c) 2006 Doug Rabson
* All rights reserved.
*
* 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$
*/
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
bool_t
__rpc_gss_wrap_stub(AUTH *auth, void *header, size_t headerlen, XDR* xdrs,
xdrproc_t xdr_args, void *args_ptr)
{
return (FALSE);
}
bool_t
__rpc_gss_unwrap_stub(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args, void *args_ptr)
{
return (FALSE);
}
__weak_reference(__rpc_gss_wrap_stub, __rpc_gss_wrap);
__weak_reference(__rpc_gss_unwrap_stub, __rpc_gss_unwrap);

View File

@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
#define RQCRED_SIZE 400 /* this size is excessive */
#define SVC_VERSQUIET 0x0001 /* keep quiet about vers mismatch */
#define version_keepquiet(xp) ((u_long)(xp)->xp_p3 & SVC_VERSQUIET)
#define version_keepquiet(xp) (SVC_EXT(xp)->xp_flags & SVC_VERSQUIET)
#define max(a, b) (a > b ? a : b)
@ -452,20 +452,16 @@ void
__svc_versquiet_on(xprt)
SVCXPRT *xprt;
{
u_long tmp;
tmp = ((u_long) xprt->xp_p3) | SVC_VERSQUIET;
xprt->xp_p3 = tmp;
SVC_EXT(xprt)->xp_flags |= SVC_VERSQUIET;
}
void
__svc_versquiet_off(xprt)
SVCXPRT *xprt;
{
u_long tmp;
tmp = ((u_long) xprt->xp_p3) & ~SVC_VERSQUIET;
xprt->xp_p3 = tmp;
SVC_EXT(xprt)->xp_flags &= ~SVC_VERSQUIET;
}
void
@ -479,7 +475,8 @@ int
__svc_versquiet_get(xprt)
SVCXPRT *xprt;
{
return ((int) xprt->xp_p3) & SVC_VERSQUIET;
return (SVC_EXT(xprt)->xp_flags & SVC_VERSQUIET);
}
#endif
@ -555,6 +552,39 @@ svcerr_progvers(xprt, low_vers, high_vers)
SVC_REPLY(xprt, &rply);
}
/*
* Allocate a new server transport structure. All fields are
* initialized to zero and xp_p3 is initialized to point at an
* extension structure to hold various flags and authentication
* parameters.
*/
SVCXPRT *
svc_xprt_alloc()
{
SVCXPRT *xprt;
SVCXPRT_EXT *ext;
xprt = mem_alloc(sizeof(SVCXPRT));
memset(xprt, 0, sizeof(SVCXPRT));
ext = mem_alloc(sizeof(SVCXPRT_EXT));
memset(ext, 0, sizeof(SVCXPRT_EXT));
xprt->xp_p3 = ext;
return (xprt);
}
/*
* Free a server transport structure.
*/
void
svc_xprt_free(xprt)
SVCXPRT *xprt;
{
mem_free(xprt->xp_p3, sizeof(SVCXPRT_EXT));
mem_free(xprt, sizeof(SVCXPRT));
}
/* ******************* SERVER INPUT STUFF ******************* */
/*
@ -643,7 +673,15 @@ svc_getreq_common(fd)
r.rq_cred = msg.rm_call.cb_cred;
/* first authenticate the message */
if ((why = _authenticate(&r, &msg)) != AUTH_OK) {
svcerr_auth(xprt, why);
/*
* RPCSEC_GSS uses this return code
* for requests that form part of its
* context establishment protocol and
* should not be dispatched to the
* application.
*/
if (why != RPCSEC_GSS_NODISPATCH)
svcerr_auth(xprt, why);
goto call_done;
}
/* now match message with a registered service*/
@ -670,7 +708,7 @@ svc_getreq_common(fd)
if (prog_found)
svcerr_progvers(xprt, low_vers, high_vers);
else
svcerr_noprog(xprt);
svcerr_noprog(xprt);
/* Fall through to ... */
}
/*

View File

@ -75,6 +75,8 @@ struct authsvc {
};
static struct authsvc *Auths = NULL;
static struct svc_auth_ops svc_auth_null_ops;
/*
* The call rpc message, msg has been obtained from the wire. The msg contains
* the raw form of credentials and verifiers. authenticate returns AUTH_OK
@ -105,6 +107,8 @@ _authenticate(rqst, msg)
/* VARIABLES PROTECTED BY authsvc_lock: asp, Auths */
rqst->rq_cred = msg->rm_call.cb_cred;
SVC_AUTH(rqst->rq_xprt).svc_ah_ops = &svc_auth_null_ops;
SVC_AUTH(rqst->rq_xprt).svc_ah_private = NULL;
rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
rqst->rq_xprt->xp_verf.oa_length = 0;
cred_flavor = rqst->rq_cred.oa_flavor;
@ -143,6 +147,26 @@ _authenticate(rqst, msg)
return (AUTH_REJECTEDCRED);
}
/*
* A set of null auth methods used by any authentication protocols
* that don't need to inspect or modify the message body.
*/
static bool_t
svcauth_null_wrap(auth, xdrs, xdr_func, xdr_ptr)
SVCAUTH *auth;
XDR *xdrs;
xdrproc_t xdr_func;
caddr_t xdr_ptr;
{
return (xdr_func(xdrs, xdr_ptr));
}
static struct svc_auth_ops svc_auth_null_ops = {
svcauth_null_wrap,
svcauth_null_wrap,
};
/*ARGSUSED*/
enum auth_stat
_svcauth_null(rqst, msg)

View File

@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <rpc/rpc.h>
#include <rpc/svc_dg.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@ -125,10 +126,9 @@ svc_dg_create(fd, sendsize, recvsize)
return (NULL);
}
xprt = mem_alloc(sizeof (SVCXPRT));
xprt = svc_xprt_alloc();
if (xprt == NULL)
goto freedata;
memset(xprt, 0, sizeof (SVCXPRT));
su = mem_alloc(sizeof (*su));
if (su == NULL)
@ -160,7 +160,7 @@ svc_dg_create(fd, sendsize, recvsize)
if (xprt) {
if (su)
(void) mem_free(su, sizeof (*su));
(void) mem_free(xprt, sizeof (SVCXPRT));
svc_xprt_free(xprt);
}
return (NULL);
}
@ -230,13 +230,28 @@ svc_dg_reply(xprt, msg)
{
struct svc_dg_data *su = su_data(xprt);
XDR *xdrs = &(su->su_xdrs);
bool_t stat = FALSE;
bool_t stat = TRUE;
size_t slen;
xdrproc_t xdr_proc;
caddr_t xdr_where;
xdrs->x_op = XDR_ENCODE;
XDR_SETPOS(xdrs, 0);
msg->rm_xid = su->su_xid;
if (xdr_replymsg(xdrs, msg)) {
if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
xdr_proc = msg->acpted_rply.ar_results.proc;
xdr_where = msg->acpted_rply.ar_results.where;
msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
msg->acpted_rply.ar_results.where = NULL;
if (!xdr_replymsg(xdrs, msg) ||
!SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where))
stat = FALSE;
} else {
stat = xdr_replymsg(xdrs, msg);
}
if (stat) {
slen = XDR_GETPOS(xdrs);
if (_sendto(xprt->xp_fd, rpc_buffer(xprt), slen, 0,
(struct sockaddr *)xprt->xp_rtaddr.buf,
@ -255,7 +270,12 @@ svc_dg_getargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args;
void *args_ptr;
{
return (*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr);
struct svc_dg_data *su;
assert(xprt != NULL);
su = su_data(xprt);
return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt),
&su->su_xdrs, xdr_args, args_ptr));
}
static bool_t
@ -288,7 +308,7 @@ svc_dg_destroy(xprt)
(void) mem_free(xprt->xp_ltaddr.buf, xprt->xp_ltaddr.maxlen);
if (xprt->xp_tp)
(void) free(xprt->xp_tp);
(void) mem_free(xprt, sizeof (SVCXPRT));
svc_xprt_free(xprt);
}
static bool_t

View File

@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$");
*/
static struct svc_raw_private {
char *raw_buf; /* should be shared with the cl handle */
SVCXPRT server;
SVCXPRT *server;
XDR xdr_stream;
char verf_body[MAX_AUTH_BYTES];
} *svc_raw_private;
@ -99,17 +99,17 @@ svc_raw_create()
if (__rpc_rawcombuf == NULL)
__rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
srp->server = svc_xprt_alloc();
svc_raw_private = srp;
}
srp->server.xp_fd = FD_SETSIZE;
srp->server.xp_port = 0;
srp->server.xp_p3 = NULL;
svc_raw_ops(&srp->server);
srp->server.xp_verf.oa_base = srp->verf_body;
srp->server->xp_fd = FD_SETSIZE;
srp->server->xp_port = 0;
svc_raw_ops(srp->server);
srp->server->xp_verf.oa_base = srp->verf_body;
xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
xprt_register(&srp->server);
xprt_register(srp->server);
mutex_unlock(&svcraw_lock);
return (&srp->server);
return (srp->server);
}
/*ARGSUSED*/
@ -154,6 +154,9 @@ svc_raw_reply(xprt, msg)
{
struct svc_raw_private *srp;
XDR *xdrs;
bool_t stat;
xdrproc_t xdr_proc;
caddr_t xdr_where;
mutex_lock(&svcraw_lock);
srp = svc_raw_private;
@ -166,7 +169,20 @@ svc_raw_reply(xprt, msg)
xdrs = &srp->xdr_stream;
xdrs->x_op = XDR_ENCODE;
(void) XDR_SETPOS(xdrs, 0);
if (! xdr_replymsg(xdrs, msg)) {
if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
xdr_proc = msg->acpted_rply.ar_results.proc;
xdr_where = msg->acpted_rply.ar_results.where;
msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
msg->acpted_rply.ar_results.where = NULL;
if (!xdr_replymsg(xdrs, msg) ||
!SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where))
stat = FALSE;
} else {
stat = xdr_replymsg(xdrs, msg);
}
if (!stat) {
return (FALSE);
}
(void) XDR_GETPOS(xdrs); /* called just for overhead */
@ -189,7 +205,9 @@ svc_raw_getargs(xprt, xdr_args, args_ptr)
return (FALSE);
}
mutex_unlock(&svcraw_lock);
return (*xdr_args)(&srp->xdr_stream, args_ptr);
return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream,
xdr_args, args_ptr));
}
/*ARGSUSED*/

View File

@ -146,15 +146,12 @@ svc_vc_create(fd, sendsize, recvsize)
r->sendsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsize);
r->recvsize = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsize);
r->maxrec = __svc_maxrec;
xprt = mem_alloc(sizeof(SVCXPRT));
xprt = svc_xprt_alloc();
if (xprt == NULL) {
warnx("svc_vc_create: out of memory");
goto cleanup_svc_vc_create;
}
xprt->xp_tp = NULL;
xprt->xp_p1 = r;
xprt->xp_p2 = NULL;
xprt->xp_p3 = NULL;
xprt->xp_verf = _null_auth;
svc_vc_rendezvous_ops(xprt);
xprt->xp_port = (u_short)-1; /* It is the rendezvouser */
@ -259,16 +256,15 @@ makefd_xprt(fd, sendsize, recvsize)
assert(fd != -1);
xprt = mem_alloc(sizeof(SVCXPRT));
xprt = svc_xprt_alloc();
if (xprt == NULL) {
warnx("svc_vc: makefd_xprt: out of memory");
goto done;
}
memset(xprt, 0, sizeof *xprt);
cd = mem_alloc(sizeof(struct cf_conn));
if (cd == NULL) {
warnx("svc_tcp: makefd_xprt: out of memory");
mem_free(xprt, sizeof(SVCXPRT));
svc_xprt_free(xprt);
xprt = NULL;
goto done;
}
@ -417,7 +413,7 @@ __svc_vc_dodestroy(xprt)
free(xprt->xp_tp);
if (xprt->xp_netid)
free(xprt->xp_netid);
mem_free(xprt, sizeof(SVCXPRT));
svc_xprt_free(xprt);
}
/*ARGSUSED*/
@ -623,11 +619,12 @@ svc_vc_getargs(xprt, xdr_args, args_ptr)
xdrproc_t xdr_args;
void *args_ptr;
{
struct cf_conn *cd;
assert(xprt != NULL);
/* args_ptr may be NULL */
return ((*xdr_args)(&(((struct cf_conn *)(xprt->xp_p1))->xdrs),
args_ptr));
cd = (struct cf_conn *)(xprt->xp_p1);
return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt),
&cd->xdrs, xdr_args, args_ptr));
}
static bool_t
@ -655,6 +652,9 @@ svc_vc_reply(xprt, msg)
struct cf_conn *cd;
XDR *xdrs;
bool_t rstat;
xdrproc_t xdr_proc;
caddr_t xdr_where;
u_int pos;
assert(xprt != NULL);
assert(msg != NULL);
@ -664,8 +664,27 @@ svc_vc_reply(xprt, msg)
xdrs->x_op = XDR_ENCODE;
msg->rm_xid = cd->x_id;
rstat = xdr_replymsg(xdrs, msg);
(void)xdrrec_endofrecord(xdrs, TRUE);
rstat = TRUE;
if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
xdr_proc = msg->acpted_rply.ar_results.proc;
xdr_where = msg->acpted_rply.ar_results.where;
msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
msg->acpted_rply.ar_results.where = NULL;
pos = XDR_GETPOS(xdrs);
if (!xdr_replymsg(xdrs, msg) ||
!SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where)) {
XDR_SETPOS(xdrs, pos);
rstat = FALSE;
}
} else {
rstat = xdr_replymsg(xdrs, msg);
}
if (rstat)
(void)xdrrec_endofrecord(xdrs, TRUE);
return (rstat);
}

View File

@ -338,21 +338,22 @@ xdrrec_getpos(xdrs)
off_t pos;
pos = lseek((int)(u_long)rstrm->tcp_handle, (off_t)0, 1);
if (pos != -1)
switch (xdrs->x_op) {
if (pos == -1)
pos = 0;
switch (xdrs->x_op) {
case XDR_ENCODE:
pos += rstrm->out_finger - rstrm->out_base;
break;
case XDR_ENCODE:
pos += rstrm->out_finger - rstrm->out_base;
break;
case XDR_DECODE:
pos -= rstrm->in_boundry - rstrm->in_finger;
break;
case XDR_DECODE:
pos -= rstrm->in_boundry - rstrm->in_finger;
break;
default:
pos = (off_t) -1;
break;
}
default:
pos = (off_t) -1;
break;
}
return ((u_int) pos);
}

View File

@ -40,6 +40,7 @@ SRCS+= gss_inquire_sec_context_by_oid.c
SRCS+= gss_mech_switch.c
SRCS+= gss_names.c
SRCS+= gss_oid_to_str.c
SRCS+= gss_pname_to_uid.c
SRCS+= gss_process_context_token.c
SRCS+= gss_pseudo_random.c
SRCS+= gss_release_buffer.c

View File

@ -47,6 +47,7 @@ FBSD_1.1 {
gss_inquire_sec_context_by_oid;
gss_oid_equal;
gss_oid_to_str;
gss_pname_to_uid;
gss_process_context_token;
gss_pseudo_random;
gss_release_buffer;
@ -67,3 +68,9 @@ FBSD_1.1 {
gss_wrap;
gss_wrap_size_limit;
};
FBSDprivate_1.0 {
_gss_copy_oid;
_gss_copy_buffer;
_gss_free_oid;
};

View File

@ -285,6 +285,7 @@ _gss_load_mech(void)
OPTSYM(set_sec_context_option);
OPTSYM(set_cred_option);
OPTSYM(pseudo_random);
OPTSYM(pname_to_uid);
SLIST_INSERT_HEAD(&_gss_mechs, m, gm_link);
count++;

View File

@ -0,0 +1,69 @@
/*-
* 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$ */
#include <unistd.h>
#include <gssapi/gssapi.h>
#include "mech_switch.h"
#include "name.h"
#include "utils.h"
OM_uint32
gss_pname_to_uid(OM_uint32 *minor_status, const gss_name_t pname,
const gss_OID mech, uid_t *uidp)
{
struct _gss_name *name = (struct _gss_name *) pname;
struct _gss_mech_switch *m;
struct _gss_mechanism_name *mn;
OM_uint32 major_status;
*minor_status = 0;
if (pname == GSS_C_NO_NAME)
return (GSS_S_BAD_NAME);
m = _gss_find_mech_switch(mech);
if (!m)
return (GSS_S_BAD_MECH);
if (m->gm_pname_to_uid == NULL)
return (GSS_S_UNAVAILABLE);
major_status = _gss_find_mn(minor_status, name, mech, &mn);
if (major_status != GSS_S_COMPLETE) {
_gss_mg_error(m, major_status, *minor_status);
return (major_status);
}
major_status = (*m->gm_pname_to_uid)(minor_status, mn->gmn_name,
mech, uidp);
if (major_status != GSS_S_COMPLETE)
_gss_mg_error(m, major_status, *minor_status);
return (major_status);
}

View File

@ -66,6 +66,18 @@ _gss_copy_oid(OM_uint32 *minor_status,
return (GSS_S_COMPLETE);
}
OM_uint32
_gss_free_oid(OM_uint32 *minor_status, gss_OID oid)
{
*minor_status = 0;
if (oid->elements) {
free(oid->elements);
oid->elements = NULL;
oid->length = 0;
}
return (GSS_S_COMPLETE);
}
OM_uint32
_gss_copy_buffer(OM_uint32 *minor_status,

View File

@ -304,6 +304,13 @@ typedef OM_uint32 _gss_pseudo_random
gss_buffer_t /* PRF output */
);
typedef OM_uint32 _gss_pname_to_uid
(OM_uint32 *, /* minor status */
gss_name_t pname, /* principal name */
gss_OID mech, /* mechanism to query */
uid_t *uidp /* pointer to UID for result */
);
struct _gss_mech_switch {
SLIST_ENTRY(_gss_mech_switch) gm_link;
const char *gm_name_prefix;
@ -343,6 +350,7 @@ struct _gss_mech_switch {
_gss_set_sec_context_option *gm_set_sec_context_option;
_gss_set_cred_option *gm_set_cred_option;
_gss_pseudo_random *gm_pseudo_random;
_gss_pname_to_uid *gm_pname_to_uid;
};
SLIST_HEAD(_gss_mech_switch_list, _gss_mech_switch);
extern struct _gss_mech_switch_list _gss_mechs;

View File

@ -30,5 +30,6 @@
do { (buffer)->value = NULL; (buffer)->length = 0; } while(0)
extern int _gss_oid_equal(const gss_OID, const gss_OID);
extern OM_uint32 _gss_copy_oid(OM_uint32 *, const gss_OID, gss_OID);
extern OM_uint32 _gss_free_oid(OM_uint32 *, gss_OID);
extern OM_uint32 _gss_copy_buffer(OM_uint32 *minor_status,
const gss_buffer_t from_buf, gss_buffer_t to_buf);

View File

@ -0,0 +1,39 @@
# $FreeBSD$
LIB= rpcsec_gss
SHLIB_MAJOR= 1
WARNS?= 6
SRCS+= rpcsec_gss.c rpcsec_gss_prot.c rpcsec_gss_conf.c rpcsec_gss_misc.c \
svc_rpcsec_gss.c
DPADD+= ${LIBGSSAPI}
LDADD+= -lgssapi
VERSION_DEF= ${.CURDIR}/../libc/Versions.def
SYMBOL_MAPS= ${.CURDIR}/Symbol.map
CFLAGS+= -I${.CURDIR}/../../include
CFLAGS+= -I${.CURDIR}/../../libc_rpc
NO_PROFILE=
MAN= rpcsec_gss.3
MAN+= rpc_gss_seccreate.3
MAN+= rpc_gss_set_defaults.3
MAN+= rpc_gss_max_data_length.3
MAN+= rpc_gss_get_error.3
MAN+= rpc_gss_mech_to_oid.3
MAN+= rpc_gss_oid_to_mech.3
MAN+= rpc_gss_qop_to_num.3
MAN+= rpc_gss_get_mechanisms.3
MAN+= rpc_gss_get_mech_info.3
MAN+= rpc_gss_get_versions.3
MAN+= rpc_gss_is_installed.3
MAN+= rpc_gss_set_svc_name.3
MAN+= rpc_gss_getcred.3
MAN+= rpc_gss_set_callback.3
MAN+= rpc_gss_get_principal_name.3
MAN+= rpc_gss_svc_max_data_length.3
.include <bsd.lib.mk>

View File

@ -0,0 +1,28 @@
/*
* $FreeBSD$
*/
FBSD_1.1 {
rpc_gss_seccreate;
rpc_gss_set_defaults;
rpc_gss_max_data_length;
rpc_gss_get_error;
rpc_gss_mesh_to_oid;
rpc_gss_oid_to_mech;
rpc_gss_qop_to_num;
rpc_gss_get_mechanisms;
rpc_gss_get_mech_info;
rpc_gss_get_versions;
rpc_gss_is_installed;
rpc_gss_set_svc_name;
rpc_gss_getcred;
rpc_gss_set_callback;
rpc_gss_get_principal_name;
rpc_gss_svc_max_data_length;
};
FBSDprivate_1.0 {
__rpc_gss_unwrap;
__rpc_gss_unwrap_stub;
__rpc_gss_wrap;
__rpc_gss_wrap_stub;
};

View File

@ -0,0 +1,58 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_GET_ERROR 3
.Os
.Sh NAME
.Nm rpc_gss_get_error
.Nd "Get error details"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft void
.Fn rpc_gss_get_error "rpc_gss_error_t *error"
.Sh DESCRIPTION
Get details of the last RPCSEC_GSS error.
.Sh PARAMETERS
.Bl -tag
.It error
A pointer to a structure where the error details will be returned
.El
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,68 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_GET_MECH_INFO 3
.Os
.Sh NAME
.Nm rpc_gss_get_mech_info
.Nd "Get extra information about a security mechanism"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft const char **
.Fn rpc_gss_get_mech_info "const char *mech" "rpc_gss_service_t *service"
.Sh DESCRIPTION
This function looks up a mechanism by name by reading the file
/etc/gss/mech and queries it for its capabilities.
.Sh PARAMETERS
.Bl -tag
.It mech
The mechanism to search for
.It service
If the mechanism is found, the maximum supported service type is
returned in
.Fa *service
.El
.Sh RETURN VALUES
If the mechanism is found,
a list of the supported qualities of protection is returned,
otherwise
.Dv NULL .
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,55 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_GET_MECHANISMS 3
.Os
.Sh NAME
.Nm rpc_gss_get_mechanisms
.Nd "Get installed mechanisms"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft const char **
.Fn rpc_gss_get_mechanisms "void"
.Sh DESCRIPTION
Return a
.Dv NULL
terminated list of installed security mechanisms.
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,82 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_GET_PRINCIPAL_NAME 3
.Os
.Sh NAME
.Nm rpc_gss_get_principal_name
.Nd "Get a principal name"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fo rpc_gss_get_principal_name
.Fa "rpc_gss_principal_t *principal"
.Fa "const char *mech"
.Fa "const char *name"
.Fa "const char *node"
.Fa "const char *domain"
.Fc
.Sh DESCRIPTION
This function can be used to generate a client principal name from
various strings.
.Sh PARAMETERS
.Bl -tag
.It principal
If the principal is created successfully,
.Fa *principal
will be set to point at the new principal in GSS-API exported name form
.It mech
The name of the mechanism for this principal
.It name
The name part of the principal
.It node
If non-null, the hostname or instance part of the principal
.It domain
If non-null, the domain or realm part of the principal
.El
.Sh RETURN VALUES
Returns
.Dv TRUE
if the principal was created or
.Dv FALSE
otherwise
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr gss_export_name 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,64 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_GET_VERSIONS 3
.Os
.Sh NAME
.Nm rpc_gss_get_versions
.Nd "Get supported protocol version"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fn rpc_gss_get_versions "u_int *vers_hi" "u_int *vers_lo"
.Sh DESCRIPTION
Return the highest and lowest supported versions of the RPCSEC_GSS protocol.
.Sh PARAMETERS
.Bl -tag
.It vers_hi
The value of
.Fa *vers_hi
is set to the highest suppored protocol version
.It vers_lo
The value of
.Fa *vers_lo
is set to the lowest suppored protocol version
.El
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,85 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_GETCRED 3
.Os
.Sh NAME
.Nm rpc_gss_getcred
.Nd "Get authorization information for an RPC request"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft AUTH *
.Fo rpc_gss_getcred
.Fa "struct svc_req *req"
.Fa "rpc_gss_rawcred_t **rcred"
.Fa "rpc_gss_ucred_t **ucred"
.Fa "void **cookie"
.Fc
.Sh DESCRIPTION
This function returns the RPCSEC_GSS authenticated credentials
associated with an RPC request.
.Sh PARAMETERS
.Bl -tag
.It req
The RPC request to query
.It rcred
If non-null,
.Fa *rcred
is set to point at the raw credentials for this request
.It ucred
.It rcred
If non-null,
.Fa *ucred
is set to point at the corresponding unix credentials
.It cookie
If non-null,
.Fa *cookie
is set to the cookie value returned by a callback function registered with
.Fn rpc_gss_set_callback
.El
.Sh RETURN VALUES
Returns
.Dv TRUE
if successful,
.Dv FALSE
otherwise.
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpc_gss_set_callback 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,65 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_IS_INSTALLED 3
.Os
.Sh NAME
.Nm rpc_gss_is_installed
.Nd "Query for the presence os a security mechanism"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fn rpc_gss_is_installed "const char *mech"
.Sh DESCRIPTION
This function looks up a mechanism by name by reading the file
/etc/gss/mech.
.Sh PARAMETERS
.Bl -tag
.It mech
The mechanism to search for
.El
.Sh RETURN VALUES
Returns
.Dv TRUE
if the mechanism is installed,
.Dv FALSE
otherwise.
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,64 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_MAX_DATA_LENGTH 3
.Os
.Sh NAME
.Nm rpc_gss_max_data_length
.Nd "calculate maximum data size"
.Sh LIBRARY
.Lb librpcsec_gss
.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
.It auth
A handle to a RPCSEC_GSS security ccontext
.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 SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,68 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_MECH_TO_OID 3
.Os
.Sh NAME
.Nm rpc_gss_mech_to_oid
.Nd "Convert a mechanism name to a GSS-API oid"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fn rpc_gss_mech_to_oid "const char *mech" "gss_OID *oid_ret"
.Sh DESCRIPTION
This function looks up a mechanism by name by reading the file
/etc/gss/mech.
.Sh PARAMETERS
.Bl -tag
.It mech
The mechanism name to search for
.It oid_ret
If the mechanism is found, the corresponding GSS-API oid is returned
in
.Fa *oid_ret
.El
.Sh RETURN VALUES
If the mechanism is found,
.Dv TRUE
is returned, otherwise
.Dv FALSE .
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,68 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_OID_TO_MECH 3
.Os
.Sh NAME
.Nm rpc_gss_oid_to_mech
.Nd "Convert a mechanism name to a GSS-API oid"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fn rpc_gss_oid_to_mech "gss_OID oid" "const char **mech_ret"
.Sh DESCRIPTION
This function looks up a mechanism by oid by reading the file
/etc/gss/mech.
.Sh PARAMETERS
.Bl -tag
.It oid
The mechanism oid to search for
.It mech_ret
If the mechanism is found, the corresponding mechanism name is returned
in
.Fa *mech_ret
.El
.Sh RETURN VALUES
If the mechanism is found,
.Dv TRUE
is returned, otherwise
.Dv FALSE .
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,70 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_QOP_TO_NUM 3
.Os
.Sh NAME
.Nm rpc_gss_qop_to_num
.Nd "Convert a quality of protection name to number"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fn rpc_gss_qop_to_num "const char *qop" "const char *mech" "u_int *num_ret"
.Sh DESCRIPTION
This function looks up a quality of protection by name by reading the file
/etc/gss/qop.
.Sh PARAMETERS
.Bl -tag
.It qop
The quality of protection to search for
.It mech
The mechanism name to search for
.It number_ret
If the quality of protection is found, the corresponding number is
returned in
.Fa *num_ret
.El
.Sh RETURN VALUES
If the value is found,
.Dv TRUE
is returned, otherwise
.Dv FALSE .
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,112 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_SECCREATE 3
.Os
.Sh NAME
.Nm rpc_gss_seccreate
.Nd "create a security context using the RPCSEC_GSS protocol"
.Sh LIBRARY
.Lb librpcsec_gss
.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
.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
.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 lised 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 SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr mech 5 ,
.Xr qop 5 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,115 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_SET_CALLBACK 3
.Os
.Sh NAME
.Nm rpc_gss_set_callback
.Nd "Register a security context creation callback"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fo (*callback)
.Fa "struct svc_req *req"
.Fa "gss_cred_id_t deleg"
.Fa "gss_ctx_id_t gss_context"
.Fa "rpc_gss_lock_t *lock"
.Fa "void **cookie"
.Fc
.Ft bool_t
.Fn rpc_gss_set_callback "rpc_gss_callback_t *cb"
.Sh DESCRIPTION
Register a function which will be called when new security contexts
are created on a server.
This function will be called on the first RPC request which uses that
context and has the opportunity of rejecting the request (for instance
after matching the request credentials to an access control list).
To accept the new security context, the callback should return
.Dv TRUE ,
otherwise
.Dv FALSE .
If the callback accepts a context, it becomes responsible for the
lifetime of the delegated client credentials (if any).
.Pp
It is also possible to 'lock' the values of service and quality of
protection used by the context.
If a context is locked, any subsequent requests which use different
values for service and quality of protection will be rejected.
.Sh PARAMETERS
.Bl -tag
.It cb
A structure containing the RPC program and version for this callback
and a function which will be called when new contexts are created for
ths given RPC program and version
.It req
The RPC request using the new context
.It deleg
GSS-APi delegated credentials (if any)
.It gss_context
The GSS-API context
.It lock
A structure used to enforce a particular QOP and service. Set
.Fa lock->locked
to
.Dv TRUE
to lock the service and QOP values
.It cookie
The callback function may set
.Fa *cookie
to any pointer sized value.
This value can be accessed during the lifetime of the context via
.Fn rpc_gss_getcred .
.El
.Sh RETURN VALUES
Returns
.Dv TRUE
if the callback was registered successfully or
.Dv FALSE
otherwise
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpc_gss_getcred 3
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .
.Sh BUGS
There is no mechanism for informing a server when a security context
has been deleted.
This makes it difficult to allocate resources (e.g. to return via the
callback's
.Fa cookie
argument).

View File

@ -0,0 +1,70 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_SET_DEFAULTS 3
.Os
.Sh NAME
.Nm rpc_gss_set_defaults
.Nd "set service and quality of protection"
.Sh LIBRARY
.Lb librpcsec_gss
.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
.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 SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,87 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_SET_SVC_NAME 3
.Os
.Sh NAME
.Nm rpc_gss_set_svc_name
.Nd "Associate a GSS-API service principal with an RPC service"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft bool_t
.Fo rpc_gss_set_svc_name
.Fa "const char *principal"
.Fa "const char *mechanism"
.Fa "u_int req_time"
.Fa "u_int program"
.Fa "u_int version"
.Fc
.Sh DESCRIPTION
This function registers a service principal which will be used to
authenticate RPCSEC_GSS security contexts for a given RPC program and
version.
.Sh PARAMETERS
.Bl -tag
.It principal
A string representing the service principal in the form
.Qq service@hostname
.It mechanim
The name of the security mechanism
.It req_time
The time in seconds that the service credentials should remain
valid.
See
.Xr gss_acquire_cred 3
for more details.
principal.
.It program
RPC program number for this service
.It version
RPC program version for this service
.El
.Sh RETURN VALUES
Returns
.Dv TRUE
if the service principal was registered or
.Dv FALSE
otherwise.
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr gss_acquire_cred 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,64 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_SVC_MAX_DATA_LENGTH 3
.Os
.Sh NAME
.Nm rpc_gss_svc_max_data_length
.Nd "calculate maximum data size"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Ft int
.Fn rpc_gss_svc_max_data_length "struct svc_req *req" "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
.It req
An RPC request
.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 SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,230 @@
.\" 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 July 4, 2008
.Dt RPC_GSS_SECCREATE 3
.Os
.Sh NAME
.Nm RPCSEC_GSS
.Nd "GSS-API based authentication for RPC"
.Sh LIBRARY
.Lb librpcsec_gss
.Sh SYNOPSIS
.In rpc/rpcsec_gss.h
.Sh DESCRIPTION
.Nm
is a security mechanism for the RPC protocol.
It uses the Generic Security Service API (GSS-API) to establish a
security context between a client and a server and to ensure that all
subsequent communication between client and server are properly
authenticated.
Optionally, extra protection can be applied to the connection.
The integrity service uses checksums to ensure that all data sent by
a peer is recieved without modification.
The privacy service uses encryption to ensure that no third party can
access the data for a connection.
.Pp
To use this system, an application must first use
.Fn rpc_gss_seccreate
to establish a security context.
.Sh DATA STRUCTURES
Data structures used by
.Nm
appear below.
.Bl -tag -width "MMMM"
.It Vt rpc_gss_service_t
This type defines the types of security service required for
.Fn rpc_gss_seccreate .
.Bd -literal
typedef enum {
rpc_gss_svc_default = 0,
rpc_gss_svc_none = 1,
rpc_gss_svc_integrity = 2,
rpc_gss_svc_privacy = 3
} rpc_gss_service_t;
.Ed
.It Vt rpc_gss_options_ret_t
This structure contains various optional values which are used while
creating a security contect.
.Bd -literal
typedef struct {
int req_flags; /* GSS request bits */
int time_req; /* requested lifetime */
gss_cred_id_t my_cred; /* GSS credential */
gss_channel_bindings_t input_channel_bindings;
} rpc_gss_options_req_t;
.Ed
.It Vt rpc_gss_options_ret_t
Various details of the created security context are returned using
this structure.
.Bd -literal
typedef struct {
int major_status;
int minor_status;
u_int rpcsec_version;
int ret_flags;
int time_req;
gss_ctx_id_t gss_context;
char actual_mechanism[MAX_GSS_MECH];
} rpc_gss_options_ret_t;
.Ed
.It Vt rpc_gss_principal_t
This type is used to refer to an client principal which is represented
in GSS-API exported name form
(see
.Xr gss_export_name 3
for more details).
Names in this format may be stored in access control lists or compared
with other names in exported name form.
This structure is returned by
.Fn rpc_gss_get_principal_name
and is also referenced by the
.Vt rpc_gss_rawcred_t
structure.
.Bd -literal
typedef struct {
int len;
char name[1];
} *rpc_gss_principal_t;
.Ed
.It Vt rpc_gss_rawcred_t
This structure is used to access the raw credentions associated with a
security context.
.Bd -literal
typedef struct {
u_int version; /* RPC version number */
const char *mechanism; /* security mechanism */
const char *qop; /* quality of protection */
rpc_gss_principal_t client_principal; /* client name */
const char *svc_principal; /* server name */
rpc_gss_service_t service; /* service type */
} rpc_gss_rawcred_t;
.Ed
.It Vt rpc_gss_ucred_t
Unix credentials which are derived form the raw credentials,
accessed via
.Fn rpc_gss_getcred .
.Bd -literal
typedef struct {
uid_t uid; /* user ID */
gid_t gid; /* group ID */
short gidlen;
gid_t *gidlist; /* list of groups */
} rpc_gss_ucred_t;
.Ed
.It Vt rpc_gss_lock_t
Structure used to enforce a particular QOP and service.
.Bd -literal
typedef struct {
bool_t locked;
rpc_gss_rawcred_t *raw_cred;
} rpc_gss_lock_t;
.Ed
.It Vt rpc_gss_callback_t
Callback structure used by
.Fn rpc_gss_set_callback .
.Bd -literal
typedef struct {
u_int program; /* RPC program number */
u_int version; /* RPC version number */
/* user defined callback */
bool_t (*callback)(struct svc_req *req,
gss_cred_id_t deleg,
gss_ctx_id_t gss_context,
rpc_gss_lock_t *lock,
void **cookie);
} rpc_gss_callback_t;
.Ed
.It Vt rpc_gss_error_t
Structure used to return error information by
.Fn rpc_gss_get_error .
.Bd -literal
typedef struct {
int rpc_gss_error;
int system_error; /* same as errno */
} rpc_gss_error_t;
/*
* Values for rpc_gss_error
*/
#define RPC_GSS_ER_SUCCESS 0 /* no error */
#define RPC_GSS_ER_SYSTEMERROR 1 /* system error */
.Ed
.Sh INDEX
.Bl -tag -width "MMMM"
.It Xr rpc_gss_seccreate 3
Create a new security context
.It Xr rpc_gss_set_defaults 3
Set service and quality of protection for a context
.It Xr rpc_gss_max_data_length 3
Calculate maximum client message sizes.
.It Xr rpc_gss_get_error 3
Get details of the last error
.It Xr rpc_gss_mech_to_oid 3
Convert a mechanism name to the corresponding GSS-API oid.
.It Xr rpc_gss_oid_to_mech 3
Convert a GSS-API oid to a mechanism name
.It Xr rpc_gss_qop_to_num 3
Convert a quality of protection name to the corresponding number
.It Xr rpc_gss_get_mechanisms 3
Get a list of security mechanisms.
.It Xr rpc_gss_get_mech_info 3
Return extra information about a security mechanism
.It Xr rpc_gss_get_versions 3
Return the maximum and minimum supported versions of the
.Nm
protocol
.It Xr rpc_gss_is_installed 3
Query for the presence of a particular security mechanism
.It Xr rpc_gss_set_svc_name 3
Set the name of a service principal which matches a given RPC program
plus version pair
.It Xr rpc_gss_getcred 3
Get credential details for the security context of an RPC request
.It Xr rpc_gss_set_callback 3
Install a callback routine which is called on the server when new
security contexts are created
.It Xr rpc_gss_get_principal_name 3
Create a client principal name from various strings
.It Xr rpc_gss_svc_max_data_length 3
Calculate maximum server message sizes.
.El
.Sh SEE ALSO
.Xr rpc 3 ,
.Xr gssapi 3 ,
.Xr gss_export_name 3 ,
.Xr mech 5 ,
.Xr qop 5 ,
.Xr rpcset_gss 3
.Sh HISTORY
The
.Nm
manual page example first appeared in
.Fx 8.0 .
.Sh AUTHORS
This
manual page was written by
.An Doug Rabson Aq dfr@FreeBSD.org .

View File

@ -0,0 +1,722 @@
/*-
* Copyright (c) 2008 Doug Rabson
* All rights reserved.
*
* 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$
*/
/*
auth_gss.c
RPCSEC_GSS client routines.
Copyright (c) 2000 The Regents of the University of Michigan.
All rights reserved.
Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
All rights reserved, all wrongs reversed.
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.
3. Neither the name of the University nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``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 REGENTS 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.
$Id: auth_gss.c,v 1.32 2002/01/15 15:43:00 andros Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
#include "rpcsec_gss_int.h"
static void rpc_gss_nextverf(AUTH*);
static bool_t rpc_gss_marshal(AUTH *, XDR *);
static bool_t rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret);
static bool_t rpc_gss_refresh(AUTH *, void *);
static bool_t rpc_gss_validate(AUTH *, struct opaque_auth *);
static void rpc_gss_destroy(AUTH *);
static void rpc_gss_destroy_context(AUTH *, bool_t);
static struct auth_ops rpc_gss_ops = {
rpc_gss_nextverf,
rpc_gss_marshal,
rpc_gss_validate,
rpc_gss_refresh,
rpc_gss_destroy
};
enum rpcsec_gss_state {
RPCSEC_GSS_START,
RPCSEC_GSS_CONTEXT,
RPCSEC_GSS_ESTABLISHED
};
struct rpc_gss_data {
rpc_gss_options_req_t gd_options; /* GSS context options */
enum rpcsec_gss_state gd_state; /* connection state */
gss_buffer_desc gd_verf; /* save GSS_S_COMPLETE
* NULL RPC verfier to
* process at end of
* context negotiation */
CLIENT *gd_clnt; /* client handle */
gss_name_t gd_name; /* service name */
gss_OID gd_mech; /* mechanism to use */
gss_qop_t gd_qop; /* quality of protection */
gss_ctx_id_t gd_ctx; /* context id */
struct rpc_gss_cred gd_cred; /* client credentials */
u_int gd_win; /* sequence window */
};
#define AUTH_PRIVATE(auth) ((struct rpc_gss_data *)auth->ah_private)
static struct timeval AUTH_TIMEOUT = { 25, 0 };
AUTH *
rpc_gss_seccreate(CLIENT *clnt, const char *principal,
const char *mechanism, rpc_gss_service_t service, const char *qop,
rpc_gss_options_req_t *options_req, rpc_gss_options_ret_t *options_ret)
{
AUTH *auth, *save_auth;
rpc_gss_options_ret_t options;
gss_OID oid;
u_int qop_num;
struct rpc_gss_data *gd;
OM_uint32 maj_stat = 0, min_stat = 0;
gss_buffer_desc principal_desc;
/*
* Bail out now if we don't know this mechanism.
*/
if (!rpc_gss_mech_to_oid(mechanism, &oid))
return (NULL);
if (qop) {
if (!rpc_gss_qop_to_num(qop, mechanism, &qop_num))
return (NULL);
} else {
qop_num = GSS_C_QOP_DEFAULT;
}
/*
* If the caller doesn't want the options, point at local
* storage to simplify the code below.
*/
if (!options_ret)
options_ret = &options;
/*
* Default service is integrity.
*/
if (service == rpc_gss_svc_default)
service = rpc_gss_svc_integrity;
memset(options_ret, 0, sizeof(*options_ret));
log_debug("in rpc_gss_seccreate()");
memset(&rpc_createerr, 0, sizeof(rpc_createerr));
auth = mem_alloc(sizeof(*auth));
if (auth == NULL) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = ENOMEM;
return (NULL);
}
gd = mem_alloc(sizeof(*gd));
if (gd == NULL) {
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
rpc_createerr.cf_error.re_errno = ENOMEM;
free(auth);
return (NULL);
}
auth->ah_ops = &rpc_gss_ops;
auth->ah_private = (caddr_t) gd;
auth->ah_cred.oa_flavor = RPCSEC_GSS;
principal_desc.value = (void *)(intptr_t) principal;
principal_desc.length = strlen(principal);
maj_stat = gss_import_name(&min_stat, &principal_desc,
GSS_C_NT_HOSTBASED_SERVICE, &gd->gd_name);
if (maj_stat != GSS_S_COMPLETE) {
options_ret->major_status = maj_stat;
options_ret->minor_status = min_stat;
goto bad;
}
if (options_req) {
gd->gd_options = *options_req;
} else {
gd->gd_options.req_flags = GSS_C_MUTUAL_FLAG;
gd->gd_options.time_req = 0;
gd->gd_options.my_cred = GSS_C_NO_CREDENTIAL;
gd->gd_options.input_channel_bindings = NULL;
}
gd->gd_clnt = clnt;
gd->gd_ctx = GSS_C_NO_CONTEXT;
gd->gd_mech = oid;
gd->gd_qop = qop_num;
gd->gd_cred.gc_version = RPCSEC_GSS_VERSION;
gd->gd_cred.gc_proc = RPCSEC_GSS_INIT;
gd->gd_cred.gc_seq = 0;
gd->gd_cred.gc_svc = service;
save_auth = clnt->cl_auth;
clnt->cl_auth = auth;
if (!rpc_gss_init(auth, options_ret)) {
clnt->cl_auth = save_auth;
goto bad;
}
clnt->cl_auth = save_auth;
return (auth);
bad:
AUTH_DESTROY(auth);
return (NULL);
}
bool_t
rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service, const char *qop)
{
struct rpc_gss_data *gd;
u_int qop_num;
const char *mechanism;
gd = AUTH_PRIVATE(auth);
if (!rpc_gss_oid_to_mech(gd->gd_mech, &mechanism)) {
return (FALSE);
}
if (qop) {
if (!rpc_gss_qop_to_num(qop, mechanism, &qop_num)) {
return (FALSE);
}
} else {
qop_num = GSS_C_QOP_DEFAULT;
}
gd->gd_cred.gc_svc = service;
gd->gd_qop = qop_num;
return (TRUE);
}
static void
rpc_gss_nextverf(__unused AUTH *auth)
{
/* not used */
}
static bool_t
rpc_gss_marshal(__unused AUTH *auth, __unused XDR *xdrs)
{
/* not used */
return (FALSE);
}
static bool_t
rpc_gss_validate(AUTH *auth, struct opaque_auth *verf)
{
struct rpc_gss_data *gd;
gss_qop_t qop_state;
uint32_t num;
gss_buffer_desc signbuf, checksum;
OM_uint32 maj_stat, min_stat;
log_debug("in rpc_gss_validate()");
gd = AUTH_PRIVATE(auth);
if (gd->gd_state == RPCSEC_GSS_CONTEXT) {
/*
* Save the on the wire verifier to validate last INIT
* phase packet after decode if the major status is
* GSS_S_COMPLETE.
*/
if (gd->gd_verf.value)
xdr_free((xdrproc_t) xdr_gss_buffer_desc,
(char *) &gd->gd_verf);
gd->gd_verf.value = mem_alloc(verf->oa_length);
if (gd->gd_verf.value == NULL) {
fprintf(stderr, "gss_validate: out of memory\n");
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
return (FALSE);
}
memcpy(gd->gd_verf.value, verf->oa_base, verf->oa_length);
gd->gd_verf.length = verf->oa_length;
return (TRUE);
}
num = htonl(gd->gd_cred.gc_seq);
signbuf.value = &num;
signbuf.length = sizeof(num);
checksum.value = verf->oa_base;
checksum.length = verf->oa_length;
maj_stat = gss_verify_mic(&min_stat, gd->gd_ctx, &signbuf,
&checksum, &qop_state);
if (maj_stat != GSS_S_COMPLETE || qop_state != gd->gd_qop) {
log_status("gss_verify_mic", gd->gd_mech, maj_stat, min_stat);
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
rpc_gss_destroy_context(auth, TRUE);
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, EPERM);
return (FALSE);
}
return (TRUE);
}
static bool_t
rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret)
{
struct rpc_gss_data *gd;
struct rpc_gss_init_res gr;
gss_buffer_desc *recv_tokenp, recv_token, send_token;
OM_uint32 maj_stat, min_stat, call_stat;
const char *mech;
log_debug("in rpc_gss_refresh()");
gd = AUTH_PRIVATE(auth);
if (gd->gd_state != RPCSEC_GSS_START)
return (TRUE);
/* GSS context establishment loop. */
gd->gd_state = RPCSEC_GSS_CONTEXT;
gd->gd_cred.gc_proc = RPCSEC_GSS_INIT;
gd->gd_cred.gc_seq = 0;
memset(&recv_token, 0, sizeof(recv_token));
memset(&gr, 0, sizeof(gr));
recv_tokenp = GSS_C_NO_BUFFER;
for (;;) {
maj_stat = gss_init_sec_context(&min_stat,
gd->gd_options.my_cred,
&gd->gd_ctx,
gd->gd_name,
gd->gd_mech,
gd->gd_options.req_flags,
gd->gd_options.time_req,
gd->gd_options.input_channel_bindings,
recv_tokenp,
&gd->gd_mech, /* used mech */
&send_token,
&options_ret->ret_flags,
&options_ret->time_req);
/*
* Free the token which we got from the server (if
* any). Remember that this was allocated by XDR, not
* GSS-API.
*/
if (recv_tokenp != GSS_C_NO_BUFFER) {
xdr_free((xdrproc_t) xdr_gss_buffer_desc,
(char *) &recv_token);
recv_tokenp = GSS_C_NO_BUFFER;
}
if (maj_stat != GSS_S_COMPLETE &&
maj_stat != GSS_S_CONTINUE_NEEDED) {
log_status("gss_init_sec_context", gd->gd_mech,
maj_stat, min_stat);
options_ret->major_status = maj_stat;
options_ret->minor_status = min_stat;
break;
}
if (send_token.length != 0) {
memset(&gr, 0, sizeof(gr));
call_stat = clnt_call(gd->gd_clnt, NULLPROC,
(xdrproc_t)xdr_gss_buffer_desc,
&send_token,
(xdrproc_t)xdr_rpc_gss_init_res,
(caddr_t)&gr, AUTH_TIMEOUT);
gss_release_buffer(&min_stat, &send_token);
if (call_stat != RPC_SUCCESS)
break;
if (gr.gr_major != GSS_S_COMPLETE &&
gr.gr_major != GSS_S_CONTINUE_NEEDED) {
log_status("server reply", gd->gd_mech,
gr.gr_major, gr.gr_minor);
options_ret->major_status = gr.gr_major;
options_ret->minor_status = gr.gr_minor;
break;
}
/*
* Save the server's gr_handle value, freeing
* what we have already (remember that this
* was allocated by XDR, not GSS-API).
*/
if (gr.gr_handle.length != 0) {
xdr_free((xdrproc_t) xdr_gss_buffer_desc,
(char *) &gd->gd_cred.gc_handle);
gd->gd_cred.gc_handle = gr.gr_handle;
}
/*
* Save the server's token as well.
*/
if (gr.gr_token.length != 0) {
recv_token = gr.gr_token;
recv_tokenp = &recv_token;
}
/*
* Since we have copied out all the bits of gr
* which XDR allocated for us, we don't need
* to free it.
*/
gd->gd_cred.gc_proc = RPCSEC_GSS_CONTINUE_INIT;
}
if (maj_stat == GSS_S_COMPLETE) {
gss_buffer_desc bufin;
u_int seq, qop_state = 0;
/*
* gss header verifier,
* usually checked in gss_validate
*/
seq = htonl(gr.gr_win);
bufin.value = (unsigned char *)&seq;
bufin.length = sizeof(seq);
maj_stat = gss_verify_mic(&min_stat, gd->gd_ctx,
&bufin, &gd->gd_verf, &qop_state);
if (maj_stat != GSS_S_COMPLETE ||
qop_state != gd->gd_qop) {
log_status("gss_verify_mic", gd->gd_mech,
maj_stat, min_stat);
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
rpc_gss_destroy_context(auth, TRUE);
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR,
EPERM);
options_ret->major_status = maj_stat;
options_ret->minor_status = min_stat;
return (FALSE);
}
options_ret->major_status = GSS_S_COMPLETE;
options_ret->minor_status = 0;
options_ret->rpcsec_version = gd->gd_cred.gc_version;
options_ret->gss_context = gd->gd_ctx;
if (rpc_gss_oid_to_mech(gd->gd_mech, &mech)) {
strlcpy(options_ret->actual_mechanism,
mech,
sizeof(options_ret->actual_mechanism));
}
gd->gd_state = RPCSEC_GSS_ESTABLISHED;
gd->gd_cred.gc_proc = RPCSEC_GSS_DATA;
gd->gd_cred.gc_seq = 0;
gd->gd_win = gr.gr_win;
break;
}
}
xdr_free((xdrproc_t) xdr_gss_buffer_desc,
(char *) &gd->gd_verf);
/* End context negotiation loop. */
if (gd->gd_cred.gc_proc != RPCSEC_GSS_DATA) {
rpc_createerr.cf_stat = RPC_AUTHERROR;
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, EPERM);
return (FALSE);
}
return (TRUE);
}
static bool_t
rpc_gss_refresh(AUTH *auth, void *msg)
{
struct rpc_msg *reply = (struct rpc_msg *) msg;
rpc_gss_options_ret_t options;
/*
* If the error was RPCSEC_GSS_CREDPROBLEM of
* RPCSEC_GSS_CTXPROBLEM we start again from scratch. All
* other errors are fatal.
*/
if (reply->rm_reply.rp_stat == MSG_DENIED
&& reply->rm_reply.rp_rjct.rj_stat == AUTH_ERROR
&& (reply->rm_reply.rp_rjct.rj_why == RPCSEC_GSS_CREDPROBLEM
|| reply->rm_reply.rp_rjct.rj_why == RPCSEC_GSS_CTXPROBLEM)) {
rpc_gss_destroy_context(auth, FALSE);
memset(&options, 0, sizeof(options));
return (rpc_gss_init(auth, &options));
}
return (FALSE);
}
static void
rpc_gss_destroy_context(AUTH *auth, bool_t send_destroy)
{
struct rpc_gss_data *gd;
OM_uint32 min_stat;
log_debug("in rpc_gss_destroy_context()");
gd = AUTH_PRIVATE(auth);
if (gd->gd_state == RPCSEC_GSS_ESTABLISHED && send_destroy) {
gd->gd_cred.gc_proc = RPCSEC_GSS_DESTROY;
clnt_call(gd->gd_clnt, NULLPROC,
(xdrproc_t)xdr_void, NULL,
(xdrproc_t)xdr_void, NULL, AUTH_TIMEOUT);
}
/*
* Free the context token. Remember that this was
* allocated by XDR, not GSS-API.
*/
xdr_free((xdrproc_t) xdr_gss_buffer_desc,
(char *) &gd->gd_cred.gc_handle);
gd->gd_cred.gc_handle.length = 0;
if (gd->gd_ctx != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&min_stat, &gd->gd_ctx, NULL);
gd->gd_state = RPCSEC_GSS_START;
}
static void
rpc_gss_destroy(AUTH *auth)
{
struct rpc_gss_data *gd;
OM_uint32 min_stat;
log_debug("in rpc_gss_destroy()");
gd = AUTH_PRIVATE(auth);
rpc_gss_destroy_context(auth, TRUE);
if (gd->gd_name != GSS_C_NO_NAME)
gss_release_name(&min_stat, &gd->gd_name);
if (gd->gd_verf.value)
xdr_free((xdrproc_t) xdr_gss_buffer_desc,
(char *) &gd->gd_verf);
mem_free(gd, sizeof(*gd));
mem_free(auth, sizeof(*auth));
}
bool_t
__rpc_gss_wrap(AUTH *auth, void *header, size_t headerlen,
XDR* xdrs, xdrproc_t xdr_args, void *args_ptr)
{
XDR tmpxdrs;
char credbuf[MAX_AUTH_BYTES];
char tmpheader[MAX_AUTH_BYTES];
struct opaque_auth creds, verf;
struct rpc_gss_data *gd;
gss_buffer_desc rpcbuf, checksum;
OM_uint32 maj_stat, min_stat;
bool_t xdr_stat;
log_debug("in rpc_gss_wrap()");
gd = AUTH_PRIVATE(auth);
if (gd->gd_state == RPCSEC_GSS_ESTABLISHED)
gd->gd_cred.gc_seq++;
/*
* We need to encode our creds and then put the header and
* creds together in a buffer so that we can create a checksum
* for the verf.
*/
xdrmem_create(&tmpxdrs, credbuf, sizeof(credbuf), XDR_ENCODE);
if (!xdr_rpc_gss_cred(&tmpxdrs, &gd->gd_cred)) {
XDR_DESTROY(&tmpxdrs);
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
return (FALSE);
}
creds.oa_flavor = RPCSEC_GSS;
creds.oa_base = credbuf;
creds.oa_length = XDR_GETPOS(&tmpxdrs);
XDR_DESTROY(&tmpxdrs);
xdrmem_create(&tmpxdrs, tmpheader, sizeof(tmpheader), XDR_ENCODE);
if (!XDR_PUTBYTES(&tmpxdrs, header, headerlen) ||
!xdr_opaque_auth(&tmpxdrs, &creds)) {
XDR_DESTROY(&tmpxdrs);
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
return (FALSE);
}
headerlen = XDR_GETPOS(&tmpxdrs);
XDR_DESTROY(&tmpxdrs);
if (!XDR_PUTBYTES(xdrs, tmpheader, headerlen)) {
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
return (FALSE);
}
if (gd->gd_cred.gc_proc == RPCSEC_GSS_INIT ||
gd->gd_cred.gc_proc == RPCSEC_GSS_CONTINUE_INIT) {
if (!xdr_opaque_auth(xdrs, &_null_auth)) {
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
return (FALSE);
}
} else {
/*
* Checksum serialized RPC header, up to and including
* credential.
*/
rpcbuf.length = headerlen;
rpcbuf.value = tmpheader;
maj_stat = gss_get_mic(&min_stat, gd->gd_ctx, gd->gd_qop,
&rpcbuf, &checksum);
if (maj_stat != GSS_S_COMPLETE) {
log_status("gss_get_mic", gd->gd_mech,
maj_stat, min_stat);
if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
rpc_gss_destroy_context(auth, TRUE);
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, EPERM);
return (FALSE);
}
verf.oa_flavor = RPCSEC_GSS;
verf.oa_base = checksum.value;
verf.oa_length = checksum.length;
xdr_stat = xdr_opaque_auth(xdrs, &verf);
gss_release_buffer(&min_stat, &checksum);
if (!xdr_stat) {
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOMEM);
return (FALSE);
}
}
if (gd->gd_state != RPCSEC_GSS_ESTABLISHED ||
gd->gd_cred.gc_svc == rpc_gss_svc_none) {
return (xdr_args(xdrs, args_ptr));
}
return (xdr_rpc_gss_wrap_data(xdrs, xdr_args, args_ptr,
gd->gd_ctx, gd->gd_qop, gd->gd_cred.gc_svc,
gd->gd_cred.gc_seq));
}
bool_t
__rpc_gss_unwrap(AUTH *auth, XDR *xdrs, xdrproc_t xdr_func, void *xdr_ptr)
{
struct rpc_gss_data *gd;
log_debug("in rpc_gss_unwrap()");
gd = AUTH_PRIVATE(auth);
if (gd->gd_state != RPCSEC_GSS_ESTABLISHED ||
gd->gd_cred.gc_svc == rpc_gss_svc_none) {
return (xdr_func(xdrs, xdr_ptr));
}
return (xdr_rpc_gss_unwrap_data(xdrs, xdr_func, xdr_ptr,
gd->gd_ctx, gd->gd_qop, gd->gd_cred.gc_svc,
gd->gd_cred.gc_seq));
}
int
rpc_gss_max_data_length(AUTH *auth, int max_tp_unit_len)
{
struct rpc_gss_data *gd;
int want_conf;
OM_uint32 max;
OM_uint32 maj_stat, min_stat;
int result;
gd = AUTH_PRIVATE(auth);
switch (gd->gd_cred.gc_svc) {
case rpc_gss_svc_none:
return (max_tp_unit_len);
break;
case rpc_gss_svc_default:
case rpc_gss_svc_integrity:
want_conf = FALSE;
break;
case rpc_gss_svc_privacy:
want_conf = TRUE;
break;
default:
return (0);
}
maj_stat = gss_wrap_size_limit(&min_stat, gd->gd_ctx, want_conf,
gd->gd_qop, max_tp_unit_len, &max);
if (maj_stat == GSS_S_COMPLETE) {
result = (int) max;
if (result < 0)
result = 0;
return (result);
} else {
log_status("gss_wrap_size_limit", gd->gd_mech,
maj_stat, min_stat);
return (0);
}
}

View File

@ -0,0 +1,417 @@
/*-
* Copyright (c) 2008 Doug Rabson
* All rights reserved.
*
* 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$
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/queue.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
#include "rpcsec_gss_int.h"
#ifndef _PATH_GSS_MECH
#define _PATH_GSS_MECH "/etc/gss/mech"
#endif
#ifndef _PATH_GSS_QOP
#define _PATH_GSS_QOP "/etc/gss/qop"
#endif
struct mech_info {
SLIST_ENTRY(mech_info) link;
char *name;
gss_OID_desc oid;
const char **qops;
char *lib;
char *kobj;
};
SLIST_HEAD(mech_info_list, mech_info);
static struct mech_info_list mechs = SLIST_HEAD_INITIALIZER(&mechs);
static const char **mech_names;
struct qop_info {
SLIST_ENTRY(qop_info) link;
char *name;
char* mech;
u_int qop;
};
SLIST_HEAD(qop_info_list, qop_info);
static struct qop_info_list qops = SLIST_HEAD_INITIALIZER(&qops);
static int
_rpc_gss_string_to_oid(const char* s, gss_OID oid)
{
int number_count, i, j;
int byte_count;
const char *p, *q;
char *res;
/*
* First figure out how many numbers in the oid, then
* calculate the compiled oid size.
*/
number_count = 0;
for (p = s; p; p = q) {
q = strchr(p, '.');
if (q) q = q + 1;
number_count++;
}
/*
* The first two numbers are in the first byte and each
* subsequent number is encoded in a variable byte sequence.
*/
if (number_count < 2)
return (EINVAL);
/*
* We do this in two passes. The first pass, we just figure
* out the size. Second time around, we actually encode the
* number.
*/
res = 0;
for (i = 0; i < 2; i++) {
byte_count = 0;
for (p = s, j = 0; p; p = q, j++) {
u_int number = 0;
/*
* Find the end of this number.
*/
q = strchr(p, '.');
if (q) q = q + 1;
/*
* Read the number of of the string. Don't
* bother with anything except base ten.
*/
while (*p && *p != '.') {
number = 10 * number + (*p - '0');
p++;
}
/*
* Encode the number. The first two numbers
* are packed into the first byte. Subsequent
* numbers are encoded in bytes seven bits at
* a time with the last byte having the high
* bit set.
*/
if (j == 0) {
if (res)
*res = number * 40;
} else if (j == 1) {
if (res) {
*res += number;
res++;
}
byte_count++;
} else if (j >= 2) {
/*
* The number is encoded in seven bit chunks.
*/
u_int t;
int bytes;
bytes = 0;
for (t = number; t; t >>= 7)
bytes++;
if (bytes == 0) bytes = 1;
while (bytes) {
if (res) {
int bit = 7*(bytes-1);
*res = (number >> bit) & 0x7f;
if (bytes != 1)
*res |= 0x80;
res++;
}
byte_count++;
bytes--;
}
}
}
if (!res) {
res = malloc(byte_count);
if (!res)
return (ENOMEM);
oid->length = byte_count;
oid->elements = res;
}
}
return (0);
}
static void
_rpc_gss_load_mech(void)
{
FILE *fp;
char buf[256];
char *p;
char *name, *oid, *lib, *kobj;
struct mech_info *info;
int count;
const char **pp;
if (SLIST_FIRST(&mechs))
return;
fp = fopen(_PATH_GSS_MECH, "r");
if (!fp)
return;
count = 0;
while (fgets(buf, sizeof(buf), fp)) {
if (*buf == '#')
continue;
p = buf;
name = strsep(&p, "\t\n ");
if (p) while (isspace(*p)) p++;
oid = strsep(&p, "\t\n ");
if (p) while (isspace(*p)) p++;
lib = strsep(&p, "\t\n ");
if (p) while (isspace(*p)) p++;
kobj = strsep(&p, "\t\n ");
if (!name || !oid || !lib || !kobj)
continue;
info = malloc(sizeof(struct mech_info));
if (!info)
break;
if (_rpc_gss_string_to_oid(oid, &info->oid)) {
free(info);
continue;
}
info->name = strdup(name);
info->qops = NULL;
info->lib = strdup(lib);
info->kobj = strdup(kobj);
SLIST_INSERT_HEAD(&mechs, info, link);
count++;
}
fclose(fp);
mech_names = malloc((count + 1) * sizeof(char*));
pp = mech_names;
SLIST_FOREACH(info, &mechs, link) {
*pp++ = info->name;
}
*pp = NULL;
}
static void
_rpc_gss_load_qop(void)
{
FILE *fp;
char buf[256];
char *p;
char *name, *num, *mech;
struct mech_info *minfo;
struct qop_info *info;
int count;
const char **mech_qops;
const char **pp;
if (SLIST_FIRST(&qops))
return;
fp = fopen(_PATH_GSS_QOP, "r");
if (!fp)
return;
while (fgets(buf, sizeof(buf), fp)) {
if (*buf == '#')
continue;
p = buf;
name = strsep(&p, "\t\n ");
if (p) while (isspace(*p)) p++;
num = strsep(&p, "\t\n ");
if (p) while (isspace(*p)) p++;
mech = strsep(&p, "\t\n ");
if (!name || !num || !mech)
continue;
info = malloc(sizeof(struct qop_info));
if (!info)
break;
info->name = strdup(name);
info->qop = strtoul(name, 0, 0);
info->mech = strdup(mech);
SLIST_INSERT_HEAD(&qops, info, link);
}
fclose(fp);
/*
* Compile lists of qops for each mechanism.
*/
SLIST_FOREACH(minfo, &mechs, link) {
count = 0;
SLIST_FOREACH(info, &qops, link) {
if (strcmp(info->mech, minfo->name) == 0)
count++;
}
mech_qops = malloc((count + 1) * sizeof(char*));
pp = mech_qops;
SLIST_FOREACH(info, &qops, link) {
if (strcmp(info->mech, minfo->name) == 0)
*pp++ = info->name;
}
*pp = NULL;
minfo->qops = mech_qops;
}
}
bool_t
rpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret)
{
struct mech_info *info;
_rpc_gss_load_mech();
SLIST_FOREACH(info, &mechs, link) {
if (!strcmp(info->name, mech)) {
*oid_ret = &info->oid;
return (TRUE);
}
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
return (FALSE);
}
bool_t
rpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret)
{
struct mech_info *info;
_rpc_gss_load_mech();
SLIST_FOREACH(info, &mechs, link) {
if (oid->length == info->oid.length
&& !memcmp(oid->elements, info->oid.elements,
oid->length)) {
*mech_ret = info->name;
return (TRUE);
}
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
return (FALSE);
}
bool_t
rpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret)
{
struct qop_info *info;
_rpc_gss_load_qop();
SLIST_FOREACH(info, &qops, link) {
if (strcmp(info->name, qop) == 0
&& strcmp(info->mech, mech) == 0) {
*num_ret = info->qop;
return (TRUE);
}
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
return (FALSE);
}
const char *
_rpc_gss_num_to_qop(const char *mech, u_int num)
{
struct qop_info *info;
if (num == GSS_C_QOP_DEFAULT)
return "default";
_rpc_gss_load_qop();
SLIST_FOREACH(info, &qops, link) {
if (info->qop == num && strcmp(info->mech, mech) == 0) {
return (info->name);
}
}
return (NULL);
}
const char **
rpc_gss_get_mechanisms(void)
{
_rpc_gss_load_mech();
return (mech_names);
}
const char **
rpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service)
{
struct mech_info *info;
_rpc_gss_load_mech();
_rpc_gss_load_qop();
SLIST_FOREACH(info, &mechs, link) {
if (!strcmp(mech, info->name)) {
/*
* I'm not sure what to do with service
* here. The Solaris manpages are not clear on
* the subject and the OpenSolaris code just
* sets it to rpc_gss_svc_privacy
* unconditionally with a comment noting that
* it is bogus.
*/
*service = rpc_gss_svc_privacy;
return info->qops;
}
}
_rpc_gss_set_error(RPC_GSS_ER_SYSTEMERROR, ENOENT);
return (NULL);
}
bool_t
rpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo)
{
*vers_hi = 1;
*vers_lo = 1;
return (TRUE);
}
bool_t
rpc_gss_is_installed(const char *mech)
{
struct mech_info *info;
_rpc_gss_load_mech();
SLIST_FOREACH(info, &mechs, link)
if (!strcmp(mech, info->name))
return (TRUE);
return (FALSE);
}

View File

@ -0,0 +1,95 @@
/*
rpcsec_gss.h
Copyright (c) 2000 The Regents of the University of Michigan.
All rights reserved.
Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
All rights reserved, all wrongs reversed.
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.
3. Neither the name of the University nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``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 REGENTS 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.
$Id: auth_gss.h,v 1.12 2001/04/30 19:44:47 andros Exp $
*/
/* $FreeBSD$ */
#ifndef _RPCSEC_GSS_INT_H
#define _RPCSEC_GSS_INT_H
/* RPCSEC_GSS control procedures. */
typedef enum {
RPCSEC_GSS_DATA = 0,
RPCSEC_GSS_INIT = 1,
RPCSEC_GSS_CONTINUE_INIT = 2,
RPCSEC_GSS_DESTROY = 3
} rpc_gss_proc_t;
#define RPCSEC_GSS_VERSION 1
/* Credentials. */
struct rpc_gss_cred {
u_int gc_version; /* version */
rpc_gss_proc_t gc_proc; /* control procedure */
u_int gc_seq; /* sequence number */
rpc_gss_service_t gc_svc; /* service */
gss_buffer_desc gc_handle; /* handle to server-side context */
};
/* Context creation response. */
struct rpc_gss_init_res {
gss_buffer_desc gr_handle; /* handle to server-side context */
u_int gr_major; /* major status */
u_int gr_minor; /* minor status */
u_int gr_win; /* sequence window */
gss_buffer_desc gr_token; /* token */
};
/* Maximum sequence number value. */
#define MAXSEQ 0x80000000
/* Prototypes. */
__BEGIN_DECLS
bool_t xdr_gss_buffer_desc(XDR *xdrs, gss_buffer_desc *p);
bool_t xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p);
bool_t xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p);
bool_t xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func,
caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_service_t svc,
u_int seq);
bool_t xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func,
caddr_t xdr_ptr, gss_ctx_id_t ctx, gss_qop_t qop, rpc_gss_service_t svc,
u_int seq);
const char *_rpc_gss_num_to_qop(const char *mech, u_int num);
void _rpc_gss_set_error(int rpc_gss_error, int system_error);
void log_debug(const char *fmt, ...);
void log_status(const char *m, gss_OID mech, OM_uint32 major,
OM_uint32 minor);
void log_hexdump(const u_char *buf, int len, int offset);
__END_DECLS
#endif /* !_RPCSEC_GSS_INT_H */

View File

@ -0,0 +1,49 @@
/*-
* Copyright (c) 2008 Doug Rabson
* All rights reserved.
*
* 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$
*/
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
#include "rpcsec_gss_int.h"
static rpc_gss_error_t _rpc_gss_error;
void
_rpc_gss_set_error(int rpc_gss_error, int system_error)
{
_rpc_gss_error.rpc_gss_error = rpc_gss_error;
_rpc_gss_error.system_error = system_error;
}
void
rpc_gss_get_error(rpc_gss_error_t *error)
{
*error = _rpc_gss_error;
}

View File

@ -0,0 +1,288 @@
/*
rpcsec_gss_prot.c
Copyright (c) 2000 The Regents of the University of Michigan.
All rights reserved.
Copyright (c) 2000 Dug Song <dugsong@UMICH.EDU>.
All rights reserved, all wrongs reversed.
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.
3. Neither the name of the University nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED ``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 REGENTS 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.
$Id: authgss_prot.c,v 1.18 2000/09/01 04:14:03 dugsong Exp $
*/
/* $FreeBSD$ */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <rpc/rpc.h>
#include <rpc/rpcsec_gss.h>
#include "rpcsec_gss_int.h"
#define MAX_GSS_SIZE 10240 /* XXX */
bool_t
xdr_gss_buffer_desc(XDR *xdrs, gss_buffer_desc *p)
{
char *val;
u_int len;
bool_t ret;
val = p->value;
len = p->length;
ret = xdr_bytes(xdrs, &val, &len, MAX_GSS_SIZE);
p->value = val;
p->length = len;
return (ret);
}
bool_t
xdr_rpc_gss_cred(XDR *xdrs, struct rpc_gss_cred *p)
{
enum_t proc, svc;
bool_t ret;
proc = p->gc_proc;
svc = p->gc_svc;
ret = (xdr_u_int(xdrs, &p->gc_version) &&
xdr_enum(xdrs, &proc) &&
xdr_u_int(xdrs, &p->gc_seq) &&
xdr_enum(xdrs, &svc) &&
xdr_gss_buffer_desc(xdrs, &p->gc_handle));
p->gc_proc = proc;
p->gc_svc = svc;
return (ret);
}
bool_t
xdr_rpc_gss_init_res(XDR *xdrs, struct rpc_gss_init_res *p)
{
return (xdr_gss_buffer_desc(xdrs, &p->gr_handle) &&
xdr_u_int(xdrs, &p->gr_major) &&
xdr_u_int(xdrs, &p->gr_minor) &&
xdr_u_int(xdrs, &p->gr_win) &&
xdr_gss_buffer_desc(xdrs, &p->gr_token));
}
bool_t
xdr_rpc_gss_wrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
gss_ctx_id_t ctx, gss_qop_t qop,
rpc_gss_service_t svc, u_int seq)
{
gss_buffer_desc databuf, wrapbuf;
OM_uint32 maj_stat, min_stat;
int start, end, conf_state;
bool_t xdr_stat;
/* Skip databody length. */
start = XDR_GETPOS(xdrs);
XDR_SETPOS(xdrs, start + 4);
/* Marshal rpc_gss_data_t (sequence number + arguments). */
if (!xdr_u_int(xdrs, &seq) || !xdr_func(xdrs, xdr_ptr))
return (FALSE);
end = XDR_GETPOS(xdrs);
/* Set databuf to marshalled rpc_gss_data_t. */
databuf.length = end - start - 4;
XDR_SETPOS(xdrs, start + 4);
databuf.value = XDR_INLINE(xdrs, databuf.length);
xdr_stat = FALSE;
if (svc == rpc_gss_svc_integrity) {
/* Marshal databody_integ length. */
XDR_SETPOS(xdrs, start);
if (!xdr_u_int(xdrs, &databuf.length))
return (FALSE);
/* Checksum rpc_gss_data_t. */
maj_stat = gss_get_mic(&min_stat, ctx, qop,
&databuf, &wrapbuf);
if (maj_stat != GSS_S_COMPLETE) {
log_debug("gss_get_mic failed");
return (FALSE);
}
/* Marshal checksum. */
XDR_SETPOS(xdrs, end);
xdr_stat = xdr_gss_buffer_desc(xdrs, &wrapbuf);
gss_release_buffer(&min_stat, &wrapbuf);
}
else if (svc == rpc_gss_svc_privacy) {
/* Encrypt rpc_gss_data_t. */
maj_stat = gss_wrap(&min_stat, ctx, TRUE, qop, &databuf,
&conf_state, &wrapbuf);
if (maj_stat != GSS_S_COMPLETE) {
log_status("gss_wrap", NULL, maj_stat, min_stat);
return (FALSE);
}
/* Marshal databody_priv. */
XDR_SETPOS(xdrs, start);
xdr_stat = xdr_gss_buffer_desc(xdrs, &wrapbuf);
gss_release_buffer(&min_stat, &wrapbuf);
}
return (xdr_stat);
}
bool_t
xdr_rpc_gss_unwrap_data(XDR *xdrs, xdrproc_t xdr_func, caddr_t xdr_ptr,
gss_ctx_id_t ctx, gss_qop_t qop,
rpc_gss_service_t svc, u_int seq)
{
XDR tmpxdrs;
gss_buffer_desc databuf, wrapbuf;
OM_uint32 maj_stat, min_stat;
u_int seq_num, conf_state, qop_state;
bool_t xdr_stat;
if (xdr_func == (xdrproc_t) xdr_void || xdr_ptr == NULL)
return (TRUE);
memset(&databuf, 0, sizeof(databuf));
memset(&wrapbuf, 0, sizeof(wrapbuf));
if (svc == rpc_gss_svc_integrity) {
/* Decode databody_integ. */
if (!xdr_gss_buffer_desc(xdrs, &databuf)) {
log_debug("xdr decode databody_integ failed");
return (FALSE);
}
/* Decode checksum. */
if (!xdr_gss_buffer_desc(xdrs, &wrapbuf)) {
mem_free(databuf.value, databuf.length);
log_debug("xdr decode checksum failed");
return (FALSE);
}
/* Verify checksum and QOP. */
maj_stat = gss_verify_mic(&min_stat, ctx, &databuf,
&wrapbuf, &qop_state);
mem_free(wrapbuf.value, wrapbuf.length);
if (maj_stat != GSS_S_COMPLETE || qop_state != qop) {
mem_free(databuf.value, databuf.length);
log_status("gss_verify_mic", NULL, maj_stat, min_stat);
return (FALSE);
}
} else if (svc == rpc_gss_svc_privacy) {
/* Decode databody_priv. */
if (!xdr_gss_buffer_desc(xdrs, &wrapbuf)) {
log_debug("xdr decode databody_priv failed");
return (FALSE);
}
/* Decrypt databody. */
maj_stat = gss_unwrap(&min_stat, ctx, &wrapbuf, &databuf,
&conf_state, &qop_state);
mem_free(wrapbuf.value, wrapbuf.length);
/* Verify encryption and QOP. */
if (maj_stat != GSS_S_COMPLETE || qop_state != qop ||
conf_state != TRUE) {
gss_release_buffer(&min_stat, &databuf);
log_status("gss_unwrap", NULL, maj_stat, min_stat);
return (FALSE);
}
}
/* Decode rpc_gss_data_t (sequence number + arguments). */
xdrmem_create(&tmpxdrs, databuf.value, databuf.length, XDR_DECODE);
xdr_stat = (xdr_u_int(&tmpxdrs, &seq_num) &&
xdr_func(&tmpxdrs, xdr_ptr));
XDR_DESTROY(&tmpxdrs);
/*
* Integrity service allocates databuf via XDR so free it the
* same way.
*/
if (svc == rpc_gss_svc_integrity) {
xdr_free((xdrproc_t) xdr_gss_buffer_desc, (char *) &databuf);
} else {
gss_release_buffer(&min_stat, &databuf);
}
/* Verify sequence number. */
if (xdr_stat == TRUE && seq_num != seq) {
log_debug("wrong sequence number in databody");
return (FALSE);
}
return (xdr_stat);
}
#ifdef DEBUG
#include <ctype.h>
void
log_debug(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "rpcsec_gss: ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
void
log_status(const char *m, gss_OID mech, OM_uint32 maj_stat, OM_uint32 min_stat)
{
OM_uint32 min;
gss_buffer_desc msg;
int msg_ctx = 0;
fprintf(stderr, "rpcsec_gss: %s: ", m);
gss_display_status(&min, maj_stat, GSS_C_GSS_CODE, GSS_C_NULL_OID,
&msg_ctx, &msg);
fprintf(stderr, "%s - ", (char *)msg.value);
gss_release_buffer(&min, &msg);
gss_display_status(&min, min_stat, GSS_C_MECH_CODE, mech,
&msg_ctx, &msg);
fprintf(stderr, "%s\n", (char *)msg.value);
gss_release_buffer(&min, &msg);
}
#else
void
log_debug(__unused const char *fmt, ...)
{
}
void
log_status(__unused const char *m, __unused gss_OID mech,
__unused OM_uint32 maj_stat, __unused OM_uint32 min_stat)
{
}
#endif

File diff suppressed because it is too large Load Diff