aboutsummaryrefslogtreecommitdiff
path: root/crypto/krb5/doc/rpc/design.tex
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/krb5/doc/rpc/design.tex')
-rw-r--r--crypto/krb5/doc/rpc/design.tex1037
1 files changed, 0 insertions, 1037 deletions
diff --git a/crypto/krb5/doc/rpc/design.tex b/crypto/krb5/doc/rpc/design.tex
deleted file mode 100644
index 801034b0f800..000000000000
--- a/crypto/krb5/doc/rpc/design.tex
+++ /dev/null
@@ -1,1037 +0,0 @@
-\documentstyle[fullpage,12pt]{article}
-
-\title{GSS-API Extensions to Sun RPC}
-\date{Draft---\today}
-\author{Barry Jaspan}
-
-\setlength{\parskip}{.7\baselineskip}
-\setlength{\parindent}{0pt}
-
-\makeatletter
-\newcount\savecnt\savecnt=0
-\def\saveenum#1{\global\savecnt=\csname c@enum#1\endcsname}
-\def\restoreenum#1{\csname c@enum#1\endcsname=\savecnt}
-\makeatother
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% Make _ actually generate an _, and allow line-breaking after it.
-\let\underscore=\_
-\catcode`_=13
-\def_{\underscore\penalty75\relax}
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-\begin{document}
-
-
-{\setlength{\parskip}{0pt}\maketitle\tableofcontents}
-
-\section{Introduction}
-
-This document describes the integration of GSS-API authentication and
-security with Sun RPC.
-
-\section{Requirements}
-
-The requirements of the GSS-API authentication system for Sun RPC are:
-
-\begin{enumerate}
-\item It must provide mutual authentication between RPC clients and
-servers.
-
-\item It must provide for integrity checking and encryption of all
-procedure arguments and results passed over the network.
-\saveenum{i}
-\end{enumerate}
-
-The following features are desired, but not mandatory:
-
-\begin{enumerate}
-\restoreenum{i}
-\item It should provide for integrity checking and encryption of all
-``header information'' that specifies the program and procedure being
-called.
-
-\item It should obey the Sun RPC protocol so that clients using
-it can interoperate with existing servers. In this case,
-``interoperate'' means that existing servers will return an error code
-indicating that they do not understand the authentication flavor, but
-not that they do not understand the request at all.
-
-\item It should require minimal or no changes to the standard Sun RPC
-programming paradigm for either clients or servers so that existing
-code can use it with little or no effort.
-
-\item It should operate correctly with all the standard Sun RPC
-transport mechansims (e.g. UDP and TCP).
-\saveenum{i}
-\end{enumerate}
-
-\section{Functional Specification}
-
-This section describes the programmer's interface to the GSS-API
-authentication flavor. Knowledge of standard Sun RPC programming is
-assumed.
-
-\subsection{Client Side}
-
-A RPC client can select the GSS-API authentication flavor in the same
-way it can select any other authentication flavor, by setting the
-cl_auth field of the CLIENT structure to the appropriate value:
-
-\begin{verbatim}
- clnt = clnt_create(server_host, PROG_NUM, PROG_VERS, protocol);
- clnt->cl_auth = auth_gssapi_create(clnt, ...);
-\end{verbatim}
-
-There are two functions that create GSS-API authentication flavor
-structures for the cl_auth field, auth_gssapi_create and
-auth_gssapi_create_default.
-
-\begin{verbatim}
-AUTH *auth_gssapi_create(CLIENT *clnt,
- OM_uint32 *major_status,
- OM_uint32 *minor_status,
- gss_cred_id_t claimant_cred_handle,
- gss_name_t target_name,
- gss_OID mech_type,
- int req_flags,
- int time_req,
- gss_OID *actual_mech_type,
- int *ret_flags,
- OM_uint32 *time_rec);
-\end{verbatim}
-
-auth_gssapi_create creates a GSS-API authentication structure and
-provides most of the flexibility of gss_init_sec_context. The
-arguments have the same interpretation as those of
-gss_init_sec_context with the same name, except:
-
-\begin{description}
-\item[clnt] The CLIENT structure returned by client_create or one of
-its relatives. It is not modified.
-\end{description}
-
-auth_gssapi_create calls gss_init_sec_context as needed, passing each
-generated token to and processing each token returned from the RPC
-server specified by the RPC handle clnt. On return, if major_status
-is GSS_S_COMPLETE, the context has been established, the returned AUTH
-structure is valid, and all of the arguments filled in by
-gss_init_sec_context have the correct values. If major_status is not
-GSS_S_COMPLETE then it and minor_status contain error codes that can
-be passed to gss_display_status and the returned value is NULL.
-
-\begin{verbatim}
-AUTH *auth_gssapi_create_default(CLIENT *clnt, char *service_name);
-\end{verbatim}
-
-auth_gssapi_create_default is a shorthand for auth_gssapi_create that
-attempts to create a context that provides procedure call and result
-integrity, using the default credentials and GSS-API mechanism.
-service_name is parsed as a GSS-API ``service'' name and used as the
-target name. The other arguments to auth_gssapi_create are as follows:
-
-\begin{verbatim}
-auth_gssapi_create(clnt,
- &dummy,
- &dummy,
- GSS_C_NO_CREDENTIAL,
- target_name,
- GSS_C_NULL_OID,
- GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
- 0,
- NULL,
- NULL,
- NULL);
-\end{verbatim}
-
-Note that if the underlying default mechanism does not support data
-integrity (e.g. the trust mechanism), this function will fail.
-
-The GSS-API major and minor status codes can be interpreted with
-auth_gssapi_display_status:
-
-\begin{verbatim}
-void auth_gssapi_display_status(char *msg, OM_uint32 major,
- OM_uint32 minor);
-\end{verbatim}
-
-All of the error messages associated with the major and minor status
-are displated on the standard error output, preceeded by the message
-``GSS-API authentication error $<$msg$>$:''.
-
-\subsection{Server Side}
-
-\subsubsection{Service Name Registration}
-
-An application server must register the service name(s) that it will
-use for GSS-API connections before any AUTH_GSSAPI requests will
-succeed.
-
-\begin{verbatim}
-typedef struct _auth_gssapi_name {
- char *name;
- gss_OID type;
-} auth_gssapi_name;
-
-bool_t _svcauth_gssapi_set_names(auth_gssapi_name *names, int num);
-\end{verbatim}
-
-names is an array of name specifications, each of which consists of a
-null-terminated ASCII representation of a name and the GSS-API name
-type that should be used to import it with gss_import_name. The
-name type ``gss_nt_service_name'' is recommended.
-
-\subsubsection{Calling Client and Service Identification}
-
-Each application server's dispatch function is passed two arguments,
-the transport mechanism (transp) and the RPC service request (rqstp).
-If the service request's credential flavor (rq_cred.oa_flavor) is
-AUTH_GSSAPI (300001)\footnote{The value 4 was originally used, but
-300001 has been officially assigned by the IETF.}, then the call has
-been authenticated. The rq_clntcred field of transp contains the
-gss_name_t of the authenticated caller and can be passed to
-gss_display_name to obtain a string represtation or gss_compare_name
-to compare it with other names. The rq_svccred field of transp
-contains the GSS-API context established with the caller and can be
-passed to gss_inquire_context.
-
-\subsubsection{Error Logging}
-
-An application server can register a function to be called when a
-failure occurs during GSS-API context establishment with
-_svcauth_set_log_badauth_func.
-
-\begin{verbatim}
-typedef void (*auth_gssapi_log_badauth_func)(OM_uint32 major,
- OM_uint32 minor,
- struct sockaddr_in *raddr,
- caddr_t data);
-
-void _svcauth_set_log_badauth_func(auth_gssapi_log_badauth_func func,
- caddr_t data);
-\end{verbatim}
-
-The function func is called each time gss_accept_sec_context fails.
-The major and minor arguments indicate the GSS-API major and minor
-status codes returned. The raddr field contains the INET socket that
-the request came from, and the data field contains the data argument
-of _svcauth_gssapi_set_log_badauth_func.
-
-An application server can register a function to be called when an RPC
-request with an invalid verifier arrives with
-_svcauth_set_log_badverf_func.
-
-\begin{verbatim}
-typedef void (*auth_gssapi_log_badverf_func)(gss_name_t client,
- gss_name_t server,
- struct svc_req *rqst,
- struct rpc_msg *msg,
- caddr_t data);
-
-void _svcauth_set_log_badverf_func(auth_gssapi_log_badverf_func func,
- caddr_t data);
-\end{verbatim}
-
-The function specified in func is called each time an invalid verifier
-is received. The client and server fields identify the (falsely
-claimed) originating client and the server it originally authenticated
-to. The raddr and addrlen fields contain the INET socket that the
-request (claims to have) come from, and data contains the data
-argument of _svcauth_set_log_badverf_func.
-
-\section{Modifications to Sun RPC}
-
-The Sun RPC extensible authentication mechanism is designed to allow
-different authentication systems to be integrated into Sun RPC easily.
-Unfortunately, it has two drawbacks. First, the existing system has a
-number of non-general design properties that are intended specifically
-for Sun's Secure RPC, and second, the existing system has no concept
-of or ability to perform authentication-flavor-specific operations on
-function arguments and results passed over the wire. The first
-problem merely makes the system confusing, since a number of features
-touted as ``general'' do not make any sense for arbitrary
-authentication systems. The second problem is more substantial, and
-can only be corrected by modifications to Sun RPC internals.
-
-The following sections describe the necessary modifications to Sun
-RPC.
-
-\subsection{Client Side Authentication, AUTH Structure}
-
-The AUTH structure (figure \ref{fig:auth}) encapsulates the data and
-function pointers for an authentication flavor instance. It has been
-changed in two ways.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-typedef struct {
- struct opaque_auth ah_cred;
- struct opaque_auth ah_verf;
- union des_block ah_key;
- struct auth_ops {
- void (*ah_nextverf)();
- int (*ah_marshal)(); /* nextverf & serialize */
- int (*ah_validate)(); /* validate varifier */
- int (*ah_refresh)(); /* refresh credentials */
- int (*ah_wrap)(); /* encode data for wire */
- int (*ah_unwrap)(); /* decode data from wire */
- void (*ah_destroy)(); /* destroy this structure */
- } *ah_ops;
- caddr_t ah_private;
-} AUTH;
-\end{verbatim}
-\caption{The AUTH structure, with the new function pointers ah_wrap
-and ah_unwrap.}
-\label{fig:auth}
-\end{figure}
-
-First, the new functions ah_wrap and ah_unwrap prepare function
-arguments and results for transmission over the wire. The
-authentication mechanism can use them to sign, encrypt, or perform any
-other operation on the data. Their prototype is:
-
-\begin{verbatim}
-bool_t ah_wrap(AUTH *auth, XDR *out_xdrs, xdrproc_t func, caddr_t ptr);
-bool_t ah_unwrap(AUTH *auth, XDR *in_xdrs, xdrproc_t func, caddr_t ptr);
-\end{verbatim}
-
-ah_wrap encodes function arguments for transmission. func and ptr are
-the XDR procedure and pointer that serialize the arguments, and
-out_xdrs is the xdr stream that the encoded arguments should be
-written to. ah_unwrap decodes function arguments received from the
-network. Its arguments are the converse of those to ah_wrap.
-
-It is the responsibility of RPC transport mechanisms to call an
-authorization flavor's ah_wrap and ah_unwrap functions when function
-arguments or results would normally be written to or read from the
-wire. Authorization flavors that do not need to perform any encoding
-or decoding can use the provided function authany_wrap for ah_wrap
-and ah_unwrap; it consists of the single statement ``return
-(*func)(out_xdrs, ptr)'' (or in_xdrs, as appropriate).
-
-Second, the function ah_refresh has been changed to take the RPC error
-message that resulted in its being called as an argument. This is
-necessary since the contents of the error message may dictate how
-ah_refresh should go about correcting the authentication failure.
-
-\subsection{Client Side Transport Mechanisms}
-
-Each client side transport mechanism must be modified to call the
-ah_wrap and ah_unwrap functions from the cl_auth field of the CLIENT
-structure during the call and reply process. The modification is
-fairly simple. For example, the UDP transport mechanism used to
-encode procedure calls like this:
-
-\begin{verbatim}
- if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
- (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
- (! (*xargs)(xdrs, argsp)))
- return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
-\end{verbatim}
-
-The last function call in the conditional serializes the arguments
-onto the xdr stream. This must be replaced with a call to the
-appropriate ah_wrap function:
-
-\begin{verbatim}
- if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
- (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
- (! AUTH_WRAP(cl->cl_auth, xdrs, xargs, argsp)))
- return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
-\end{verbatim}
-
-AUTH_WRAP is a macro that takes the four arguments for an ah_wrap
-function and extracts and calls the function pointer from the cl_auth
-structure with the specified arguments.
-
-Similarly, the transport mechanism must unwrap procedure results.
-Again, the UDP mechanism will be instructive. It used to deserialize
-function results like this:
-
-\begin{verbatim}
- reply_msg.acpted_rply.ar_results.where = resultsp;
- reply_msg.acpted_rply.ar_results.proc = xresults;
-
- ok = xdr_replymsg(&reply_xdrs, &reply_msg);
-\end{verbatim}
-
-The problem here is that xdr_replymsg deserializes an entire reply
-message, including the results. Since xresults and resultsp are the
-function and pointer to decode the results, they will be automatically
-deserialized {\it without} ah_unwrap being invoked. The simplest
-solution (which is also the normal method used by the TCP mechanism)
-is to arrange to deserialize the function results explicitly:
-
-\begin{verbatim}
- reply_msg.acpted_rply.ar_results.where = NULL;
- reply_msg.acpted_rply.ar_results.proc = xdr_void;
-
- if ((! xdr_replymsg(&reply_xdrs, &reply_msg)) ||
- (! AUTH_UNWRAP(cl->cl_auth, reply_xdrs, xresults,
- resultsp))) {
- return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
- }
-\end{verbatim}
-
-Since xdr_void does not read any data from the XDR stream, the
-function results are still available when AUTH_UNWRAP is called. Note
-that AUTH_UNWRAP should only be called on {\it successful} calls; if
-the reply message status is not RPC_SUCCESS there are no arguments to
-read.
-
-Currently, the UDP and TCP transport mechanisms has been
-converted.\footnote{The ``raw'' mechanism, for direct connections, has
-not been.}
-
-\subsection{Service Side Authentication, SVCAUTH and XPRT}
-
-Standard Sun RPC service-side authentication consists of a single
-function per authentication flavor; there is no concept of an AUTH
-structure containing function pointers and private data as with the
-client side. Previously, nothing else was necessary, because each
-flavor only did a single thing (authenticated individual calls in a
-stateless manner). More functions and state are now required,
-however; they are stored in the SVCAUTH structure, see figure
-\ref{fig:svcauth}.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-typedef struct {
- struct svc_auth_ops {
- int (*svc_ah_wrap)();
- int (*svc_ah_unwrap)();
- } *svc_ah_ops;
- caddr_t svc_ah_private;
-} SVCAUTH;
-\end{verbatim}
-\caption{The new SVCAUTH structure.}
-\label{fig:svcauth}
-\end{figure}
-
-There is one SVCAUTH structure per authentication flavor (there is a
-default, svc_auth_any, for existing authentication flavors that do not
-need the extra functionality). The svc_ah_wrap and svc_ah_unwrap
-perform the same logical function as their client-side counterparts.
-
-Just as with the client side, it is the responsibility of the
-transport mechanism to call the svc_ah_wrap and svc_ah_unwrap
-functions associated with the authentication flavor associated with
-each RPC call at the appropriate time. Unfortunately, the transport
-mechanism code does not have access to the RPC call structure
-containing the authenticator flavor because the RPC call structure
-itself is not passed as an argument to the necessary functions. The
-present solution is to add another argument to the transport mechanism
-structure, xp_auth, that stores the SVCAUTH of the {\it current} call
-on that mechanism; see figure \ref{fig:xprt}. xp_auth is initialized
-to svc_auth_any so that existing authentication mechanisms that do not
-set the field will still operate correctly. \footnote{This is not an
-great solution, because it forces each transport mechanism to be
-single threaded. The correct solution is to store the SVCAUTH
-associated with each RPC call in the RPC call structure; however,
-doing so would require changing a lot of code to pass around the RPC
-call structure that currently does not do so. Since other parts of
-Sun RPC use the XPRT structure in a non-reentrant way, the present
-solution does not make the situation any
-worse.}$^{\mbox{,}}$\footnote{A somewhat irrelevant side effect of
-adding SVCAUTH to XPRT is that the standard include file
-$<$rpc/rpc.h$>$ had to be changed to include $<$rpc/svc_auth$>$ before
-$<$rpc/svc.h$>$, whereas they used to be in the opposite order.}
-
-\begin{figure}[htbp]
-\begin{verbatim}
-typedef struct {
- int xp_sock;
- u_short xp_port; /* associated port number */
- struct xp_ops {
- bool_t (*xp_recv)(); /* receive incomming requests */
- enum xprt_stat (*xp_stat)(); /* get transport status */
- bool_t (*xp_getargs)(); /* get arguments */
- bool_t (*xp_reply)(); /* send reply */
- bool_t (*xp_freeargs)();/* free mem allocated for args */
- void (*xp_destroy)(); /* destroy this struct */
- } *xp_ops;
- int xp_addrlen; /* length of remote address */
- struct sockaddr_in xp_raddr; /* remote address */
- struct opaque_auth xp_verf; /* raw response verifier */
- SVCAUTH *xp_auth; /* auth flavor of current req */
- caddr_t xp_p1; /* private */
- caddr_t xp_p2; /* private */
-} SVCXPRT;
-\end{verbatim}
-\caption{The modified XPRT structure, with the xp_auth field.}
-\label{fig:xprt}
-\end{figure}
-
-Finally, with the modified XPRT structure carrying around the
-authentication flavor structure, the functions that serialize and
-deserialize function arguments and results must be modified to use the
-svc_ah_wrap and svc_ah_unwrap functions. Each service-side transport
-mechanism has getargs and reply functions that must be modified to use
-the SVCAUTH_UNWRAP and SVCAUTH_WRAP macros, respectively, in a manner
-completely parallel to the client side.
-
-\subsection{Authenticated Service Identification, svc_req}
-
-Sun RPC provides the authenticated credentials of a client to the
-application server via rq_clntcred (``cooked credentials'') field of
-the service request (svc_req) structure. In many authentication
-systems, services are also named entities, and there is no reason that
-an RPC should be restricted to accepting connections as a single
-authenticated service name. However, access control decisions may be
-based on the service name a client authenticated to, so that
-information must be available to the application server.
-
-Figure \ref{fig:svc-req} shows the modified service request structure
-that contains a single new field, rq_svccred. Like rq_clntcred, the
-authentication flavor is responsible for setting rq_svccred to the
-``cooked'' service credentials associated with a given RPC call.
-Authentication flavors that do not have the concept of service names
-can of course leave this field blank.
-
-\begin{figure}[htbp]
-\begin{verbatim}
-struct svc_req {
- u_long rq_prog; /* service program number */
- u_long rq_vers; /* service protocol version */
- u_long rq_proc; /* the desired procedure */
- struct opaque_auth rq_cred; /* raw creds from the wire */
- caddr_t rq_clntcred; /* read only cooked client cred */
- caddr_t rq_svccred; /* read only cooked svc cred */
- SVCXPRT *rq_xprt; /* associated transport */
-};
-\end{verbatim}
-\caption{The modified svc_req structure, with the rq_svccred field.}
-\label{fig:svc-req}
-\end{figure}
-
-
-
-\subsection{Authentication Negotiation, no_dispatch}
-
-In order to avoid having to transmit a full set of authentication
-information with every call, the service-side authentication mechanism
-must save state between calls. Establishing that state may require
-multiple messages between the client-side and service-side
-authentication mechanisms. The client-side authentication mechanism
-can make arbitrary RPC calls to the server simply by requiring the
-programmer to specify the CLIENT structure to the authentication
-flavor initialization routine. The service side, however, is more
-complex. In the normal course of events, an RPC call comes in, is
-authenticated, and is then dispatched to the appropriate procedure.
-For client- and service-side authentication flavors to communicate
-independent of the server implemented above the RPC layer, the
-service-side flavor must be able to send a reply to the client
-directly and {\it prevent} the call from being dispatched.
-
-This is implemented by a simple modification to the _authenticate
-routine, which dispatches each RPC call to the appropriate
-authentication flavor; see figure \ref{fig:authenticate}. It takes an
-additional argument, no_dispatch, that instructs the mechanism not to
-dispatch the RPC call to the specified procedure.
-
-\begin{figure}[htbp]
-\begin{verbatim}
- why=_authenticate(&r, &msg, &no_dispatch);
- if (why != AUTH_OK) {
- svcerr_auth(xprt, why);
- goto call_done;
- } else if (no_dispatch) {
- goto call_done;
- }
-\end{verbatim}
-\caption{A call to the modified _authenticate.}
-\label{fig:authenticate}
-\end{figure}
-
-If _authenticate sets no_dispatch to true, the call is considered
-finished and no procedure dispatch takes place. Presumably, an
-authentication flavor that sets no_dispatch to true also replies to
-the RPC call with svc_sendreply. Authentication flavors that do not
-modify no_dispatch implicitly leave it set to false, so the normal
-dispatch takes place.
-
-\subsection{Affected Files}
-
-Table \ref{tab:modfiles} lists the files that were
-affected for each of the modifications described in previous sections.
-
-\begin{table}[htbp]
-\centering
-\caption{Files modified for each change to Sun RPC.}
-\label{tab:modfiles}
-\begin{tabular}{ll}
-AUTH structure & auth.h \\
- & auth_none.c \\
- & auth_exit.c \\
- & auth_any.c \\
-Client Transport Mechanisms & clnt_udp.c \\
- & clnt_tcp.c \\
-SVCAUTH and XPRT structures & rpc.h \\
- & svc.h \\
- & svc_auth.h \\
- & svc.c \\
- & svc_auth.c \\
- & svc_auth_any.c \\
- & svc_auth_unix.c \\
-Server Transport Mechanisms & svc_udp.c \\
- & svc_tcp.c
-\end{tabular}
-\end{table}
-
-\section{GSS-API Authentication Flavor}
-
-The following sections describe the implementation of the GSS-API
-authentication flavor for Sun RPC.
-
-\subsection{Authentication Algorithms}
-\label{sec:algorithms}
-
-\subsubsection{Context Initiation}
-
-The client creates a GSS-API context with the server each time it
-calls auth_gssapi_create. The context is created using the standard
-gss_init_sec_context and gss_accept_sec_context function calls. The
-generated tokens are passed between the client and server as arguments
-and results of normal RPC calls.
-
-The client side, in auth_gssapi_create, performs the following steps
-to initiate a context:
-
-\begin{enumerate}
-\item\label{item:process-token} The client calls gss_init_sec_context.
-On the first such call, no input token is provided; on subsequent
-calls, the token received from the server is provided.
-
-\item If gss_init_sec_context produces an output token:
-
-\begin{enumerate}
-\item The client transmits the token to the server, identifying itself
-with client_handle if it has already been received (see next step).
-The return value from the server will contain a client_handle and one
-or both of a token and a signed initial sequence number.
-
-\item If this is the first response from the server, the client_handle
-is stored for subsequent calls. Otherwise, the client_handle should be
-the same as returned on the previous call.
-
-\item If the response contains a signed initian sequence number but
-the context is not yet established, then the response also contains a
-token that will established the context. The signed initial sequence
-number is stored.
-
-\item If the response contains a token, step \ref{item:process-token}
-repeated.
-\end{enumerate}
-
-\item The signed initial sequence number is verified using the
-established context.
-\end{enumerate}
-
-The server side, in _svcauth_gssapi, performs the following steps to
-initiate a context:
-
-\begin{enumerate}
-\item If a call arrives with no client_handle, a new client_handle is
-allocated and stored in the database. Otherwise, the client's
-previous state is is looked up in the database.
-
-\item The received token is passed to gss_accept_sec_context. If an
-output token is generated, it is returned to the client. Note that
-since the application server may have registered multiple service
-names and there is no way to determine {\it a priori} which service a
-token is for, _svcauth_gssapi calls gss_accept_sec_context once for
-each registered credential until one of them succeeds. The code
-assumes that GSS_S_FAILURE is the only error that can result from a
-credential mismatch, so any other error terminates the loop
-immediately.
-
-\item If the context is established, the server signs an initial
-sequence number and returns it to the client.
-\end{enumerate}
-
-Note that these algorithms require context establishment to be
-synchronous. If gss_init_sec_context returns GSS_S_COMPLETE upon
-processing a token, it will either produce a token or not. If it
-does, then gss_accept_sec_context will return GSS_S_COMPLETE when that
-token is processed; if it does not, then gss_accept_sec_context
-already returned GSS_S_COMPLETE (and presumably returned the token
-that caused gss_init_sec_context to return GSS_S_COMPLETE when
-processed). The reverse is also true.
-
-\subsubsection{RPC Calls}
-
-After the GSS-API context is established, both the server and the
-client possess a client handle and a corresponding sequence number.
-Each call from the client contains the client handle as the
-``credential'' so that the server can identify which context to apply
-to the call.
-
-Each client call and server response includes a ``verifier'' that
-contains the sealed current sequence number.\footnote{In a future
-version, the verifier will also contain a signature block for the call
-header, including the procedure number called.} The sequence number
-prevents replay attacks\footnote{Although some GSS-API mechanisms
-provide replay detection themselves, not all of them do; explicitly
-including the sequence number in the RPC therefore provides better
-end-to-end security}, but by itself it does not prevent splicing
-attacks.
-
-Each procedure argument and result block consists of the current
-sequence number and the actual serialized argument string, all sealed
-with gss_seal. Combining the sequence number with the argument/result
-data prevents splicing attacks.
-
-The sequence number is incremented by one for each RPC call and by one
-for each response. The client and server will both reject messages
-that do not contain the expected sequence number. Packets
-retransmitted by the client should use the {\it same} sequence number
-as the original packet, since even if the server receives multiple
-copies only one will be honored.
-
-\subsection{RPC Call Credential Structure}
-
-Every message transmitted from the client to the server has a
-credentials (cb_cred) field of the type auth_gssapi_creds:
-
-\begin{verbatim}
-typedef struct _auth_gssapi_creds {
- bool_t auth_msg;
- gss_buffer_desc client_handle;
-};
-\end{verbatim}
-
-The auth_msg field indicates whether the message is intended for the
-authentication mechanism for the actual server. Any message whose
-auth_msg field is true is processed by the authentication mechanism;
-any message whose auth_msg is false is passed to the application
-server's dispatch function if authentication succeeds. All messages
-must have an auth_msg of true until the context is established, since
-authentication cannot succeed until it is.
-
-The client_handle field contains the client handle obtained from the
-first call to the server. On the first call, this field is empty.
-
-\subsection{GSS-API Authentication Flavor Procedures}
-
-The GSS-API authentication flavor uses standard RPC calls over the
-client handle it is provided for the interactions described in
-\ref{sec:algorithms}. All of the following procedures require the
-auth_msg field in the credentials to be true; otherwise, the
-server-side authentication flavor will simply attempt to authenticate
-the caller and pass the call to the application server. The
-server-side authentication flavor uses the no_dispatch variable to
-indicate that it has handled the call.
-
-\subsubsection{AUTH_GSSAPI_INIT, AUTH_GSSAPI_CONTINUE_INIT}
-
-Context initiation is performed via AUTH_GSSAPI_INIT and
-AUTH_GSSAPI_CONTINUE_INIT. The former is used to transfer the first
-token generated by gss_init_sec_context, when no client handle is
-included in the credentials; the latter is used on subsequent calls,
-when a client handle is included.
-
-Both procedures take an argument of type auth_gssapi_init_arg and
-return results of the type auth_gssapi_init_res.
-
-\begin{verbatim}
-typedef struct _auth_gssapi_init_arg {
- u_long version;
- gss_buffer_desc token;
-} auth_gssapi_init_arg;
-\end{verbatim}
-
-\begin{description}
-\item[version] Three versions are presently defined.
-
-\begin{description}
-\item[1] The original version, as described in this document
-
-\item[2] In earlier versions of Secure there was a bug in the GSS-API
-library that affected the contents of accept_sec_context output
-tokens. A client specifies version 2 to indicate that it expects the
-correct (fixed) behavior. If the server indicates AUTH_BADCRED or
-AUTH_FAILED it does not understand this version, so the client should
-fall back to version 1.
-
-\item[3] Version three indicates that channel bindings are in use.
-The client must specify channel bindings with the version, and the
-server will as well. If the server indicates AUTH_BADCRED or
-AUTH_FAILED it does not understand this version, so the client should
-fall back to version 2 (and cease specifying channel bindings).
-
-\item[4] The previous versions all used the old GSS-API krb5 mechanism
-oid; this version uses the new one specified in the RFC.
-\end{description}
-
-\item[token] The token field contains the token generated by
-gss_init_sec_context.
-\end{description}
-
-\begin{verbatim}
-typedef struct _auth_gssapi_init_res {
- u_long version;
- gss_buffer_desc client_handle;
- gss_buffer_desc token;
- OM_uint32 gss_major, gss_minor;
- gss_buffer_desc signed_isn;
-} auth_gssapi_init_res;
-\end{verbatim}
-
-\begin{description}
-\item[version] There are two versions currently defined.
-\begin{description}
-\item[1] The original version, as described in this document. This is
-the response version for {\it both} versions 1 and 2. The Secure 1.1
-server will always return this version.
-
-\item[3] Version three indicates that the server specified channel
-bindings in response to a call arg version number of three. The
-server must not specify this version unless the client does.
-\end{description}
-
-\item[client_handle] The client_handle field contains the client
-handle that the client must use in the credentials field in all
-subsequent RPC calls. In response to AUTH_GSSAPI_CONTINUE_INIT, it is
-the same client handle that arrived in the credentials.
-
-\item[gss_major, gss_minor] The GSS-API error codes that resulted from
-processing the auth_gssapi_init_arg. If gss_major is GSS_S_COMPLETE,
-the argument token was processed successfully. Otherwise, gss_major
-and gss_minor contain the relevant major and minor status codes, and
-the context currently being negotiated is no longer valid.
-
-\item[token] In any response that the client is expecting another
-token (i.e.: gss_init_sec_context last returned GSS_S_CONTINUE), the
-token field contains the output token from gss_accept_sec_context. If
-the client is not expecting a token and this field is not empty, an
-error has occurred.
-
-\item[signed_isn] If the client is not expecting another token (i.e.:
-the previous call to gss_init_sec_context yielded a token and returned
-GSS_S_COMPLETE) or the supplied token completes the context, the
-signed_isn field contains the signed initial sequence number. The
-server expects the first RPC call to have a sequence number one
-greater than the initial sequence number (so that the signed_isn block
-cannot be replayed). If the client is expecting another token and the
-signed_isn field is not empty, an error has occurred.
-\end{description}
-
-\subsubsection{AUTH_GSSAPI_DESTROY}
-
-Context tear-down is performed via AUTH_GSSAPI_DESTROY. This
-procedure takes no arguments and returns no results; it merely informs
-the server that the client wishes to destroy the established context.
-
-When a client wishes to tear down an established context between
-itself and a server, auth_gssapi_destroy first calls the
-AUTH_GSSAPI_DESTROY procedure. The server authenticates the message
-and immediately sends a ``success'' response with no results. The
-client and server then both independently call gss_delete_sec_context
-and discard the context-destruction token that is generated.
-
-No RPC error checking is performed by either the client or the server.
-The client waits a brief time for a success response from the server,
-but if none arrives it destroys the context anyway since presumably
-the user is waiting for the application to exit. The server similar
-ignores any RPC errors since it knows that the client will ignore any
-errors that are reported.
-
-\subsection{RPC Call Authentication Implementation}
-
-Once the context has been established, all subsequent RPC calls are
-authenticated via the verifier described in section
-\ref{sec:algorithms}.
-
-auth_gssapi_marshall, invoked via AUTH_MARSHALL while the RPC call is
-being created on the client side, serializes the client_handle
-obtained during context initiation {\it in plaintext} as the
-credentials and serializes the current sequence number, sealed with
-gss_seal, as the verifier.
-
-auth_gssapi_wrap, invoked next via AUTH_WRAP, serializes a sealed
-token containing both the sequence number of the current call and the
-serialized arguments.
-
-_svcauth_gssapi, invoked on the server side by _authenticate, uses the
-client_handle contained in the credentials to look up the correct
-context and verifies the sequence number provided in the verifier; if
-the sequence number is not correct, it declares a potential replay
-attack.\footnote{Retransmitted packets will appear as replay attacks,
-of course.} The response verifier is set to the serialized sealed
-incremented sequence number.
-
-svc_auth_gssapi_unwrap, invoked when either the application server or
-_svcauth_gssapi (in response to an AUTH_GSSAPI authentication flavor
-message) attempts to read its arguments, deserialzes and unseals the
-block containing the current sequence number and serialized arguments.
-If the sequence number is incorrect, it declares a splicing attack;
-otherwise, it unserializes the arguments into the original structure.
-
-svc_auth_gssapi_wrap, invoked when either the application server or
-_svcauth_gssapi attempts to write its response, performs the same
-operation as auth_gssapi_wrap.
-
-auth_gssapi_validate, invoked by the client-side RPC mechanism when
-an RPC_SUCCESS response is received, verifies that the returned sequence
-number is one greater than the previous value sent by
-auth_gssapi_marshall.
-
-Finally, auth_gssapi_unwrap, invoked by the client-side RPC mechanism
-after auth_gssapi_validate succeeds, performs the same operation as
-svc_auth_gssapi_unwrap.
-
-If an RPC request generates an error message (a status of other than
-RPC_SUCCESS), auth_gssapi_refresh is called. If the error status is
-AUTH_REJECTEDVERF, then the server rejected the sequence number as
-invalid or replayed. The client guesses that, on some previous call,
-the server received a message but the server's response did not make
-it back to the client; this could happen if the packet got lost or if
-the server was being debugged and the client timed out waiting for it.
-As a result, the server is expected a higher sequence number than the
-client sent. auth_gssapi_refresh increments the sequence number and
-returns true so that the call will be tried again. The transport
-mechanism will only call auth_gssapi_refresh twice for each RPC
-request, so if some other error occurred an infinite loop will not
-result; however, it is unlikely the the client and server will be able
-to resynchronize after such an event.
-
-\subsection{Client State Information}
-
-The client-side GSS-API authentication flavor maintains an
-auth_gssapi_data structure for each authentication instance:
-
-\begin{verbatim}
-struct auth_gssapi_data {
- bool_t established;
- CLIENT *clnt;
- gss_ctx_id_t context;
- gss_buffer_desc client_handle;
- u_long seq_num;
- int def_cred;
-
- /* pre-serialized ah_cred */
- u_char cred_buf[MAX_AUTH_BYTES];
- u_long cred_len;
-};
-\end{verbatim}
-
-The established field indicates whether the authentication context
-between the client and server has been established. It is set to true
-when gss_init_sec_context returns GSS_S_COM\-PLETE. When this field is
-false, the auth_gssapi functions marshall, validate, wrap, and unwrap
-mimic the ``no authentication'' flavor since there is no context with
-which to perform authentication functions.\footnote{This field is
-necessary because, when auth_gssapi_create calls clnt_call to make an
-RPC call, it has to have set the client's authentication flavor to
-AUTH_GSSAPI; otherwise, the service-side RPC mechanism will not know
-to dispatch the call to _svcauth_gssapi. However, with the client's
-authentication flavor set, all of the authentication flavor's
-functions will be automatically invoked, even though they are not
-ready to operate.}
-
-The clnt field contains the RPC client structure that can be used to
-communicate with the GSS-API authentication flavor on the server.
-
-The context field contains the context structure created by
-gss_init_sec_context.
-
-The client_handle field contains the client handle used on all RPC
-calls except the first one; the handle is obtained as the result of
-the first call.
-
-The sequence_number field contains the sequence number that will be
-used when transmitting RPC calls to the server and verifying the
-server's responses after the context is initialized.
-
-The def_cred field is true if gss_init_sec_context created a default
-credential, in which case the authentication mechanism is responsible
-for releasing the default credential that gets automatically
-allocated.
-
-The cred_buf and cred_len fields contain the pre-serialized
-credentials structure used in each call. This provides a small
-performance enhancement since the credentials structure does not
-change very often; the same pre-serialized version can be used on
-virtually every call.
-
-\subsection{Server State Information}
-\label{sec:server-state}
-
-The server-side GSS-API authentication flavor maintains an
-svcauth_gssapi_data structure for each established or partially
-established context:
-
-\begin{verbatim}
-typedef struct _svc_auth_gssapi_data {
- bool_t established;
- gss_ctx_id_t context;
- gss_name_t client_name, server_name;
- gss_cred_id_t server_creds;
-
- u_long expiration;
- u_long seq_num;
- u_long key;
-
- SVCAUTH svcauth;
-} svc_auth_gssapi_data;
-\end{verbatim}
-
-The established field indicates whether the context is fully
-established.
-
-The context field contains the context created by
-gss_accept_sec_context.
-
-The client_name field contains the client's authenticated name, as
-returned by gss_accept_sec_context. _svcauth_gssapi sets the ``cooked
-credentials'' field of the RPC call structure to this value after the
-call is authenticated; the application server can use it to perform
-authorization.
-
-The server_name field contains the service name that the client
-established a context with. This is useful if the application server
-registered more than one service name with the library; it allows the
-server to determine which service the client chose.
-
-The server_creds field contains the service credentials that the
-client established a context with. It is used to avoid having to scan
-through the server_creds_list multiple times in the case that context
-establishment requires more than one round-trip to the server.
-
-The expiration field contains the expiration time of the context, as a
-Unix timestamp. If a context has no expiration (time_rec is
-GSS_C_INDEFINITE), the expiration time is set to 24 hours in the
-future. When the structure is created, before the context is
-established, the expiration time is initialized to small duration
-(currently 5 minutes) so that partially created and abandoned contexts
-will be expired quickly.
-
-The seq_num field is the current sequence number for the client.
-
-The key field is the client's key into the hash table (see below).
-The client_handle field sent to the client is the key treated as an
-arbitrary four-byte string.
-
-The svcauth field is a kludge that allows the svc_auth_gssapi
-functions to access the per-client data structure while processing a
-call. One SVCAUTH structure is allocated for each client structure,
-and the svc_ah_private field is set to the corresponding client. The
-client's svcauth field is then set to the new SVCAUTH structure, so
-that client_data->svcauth->svc_ah_private == client_data. As each
-request is processed, the transport mechanism's xp_auth field is set
-to the client's svcauth field; thus, the server-side functions that
-dispatch to server-side authentication flavors can access an
-appropriate SVCAUTH structure, and the server-side authentication
-function that is called can determine the appropriate per-client
-structure from the SVCAUTH structure.
-
-The per-client structures are all stored both in a BSD 4.4 db library
-hash table and b-tree. The hash table maps client handles (key
-fields) the client structures, and is used to look up client
-structures based on the client_handle field of a call's credentials
-structure. The b-tree stores the client structures as keys, sorted by
-their expiration time. Each time _svcauth_gssapi is activated, it
-traverses the tree and destroys all client structures that have
-expired.
-
-\end{document}