1\documentstyle[fullpage,12pt]{article}
2
3\title{GSS-API Extensions to Sun RPC}
4\date{Draft---\today}
5\author{Barry Jaspan}
6
7\setlength{\parskip}{.7\baselineskip}
8\setlength{\parindent}{0pt}
9
10\makeatletter
11\newcount\savecnt\savecnt=0
12\def\saveenum#1{\global\savecnt=\csname c@enum#1\endcsname}
13\def\restoreenum#1{\csname c@enum#1\endcsname=\savecnt}
14\makeatother
15
16%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
17%% Make _ actually generate an _, and allow line-breaking after it.
18\let\underscore=\_
19\catcode`_=13
20\def_{\underscore\penalty75\relax}
21%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
22
23\begin{document}
24
25
26{\setlength{\parskip}{0pt}\maketitle\tableofcontents}
27
28\section{Introduction}
29
30This document describes the integration of GSS-API authentication and
31security with Sun RPC.
32
33\section{Requirements}
34
35The requirements of the GSS-API authentication system for Sun RPC are:
36
37\begin{enumerate}
38\item It must provide mutual authentication between RPC clients and
39servers.
40
41\item It must provide for integrity checking and encryption of all
42procedure arguments and results passed over the network.
43\saveenum{i}
44\end{enumerate}
45
46The following features are desired, but not mandatory:
47
48\begin{enumerate}
49\restoreenum{i}
50\item It should provide for integrity checking and encryption of all
51``header information'' that specifies the program and procedure being
52called.
53
54\item It should obey the Sun RPC protocol so that clients using
55it can interoperate with existing servers.  In this case,
56``interoperate'' means that existing servers will return an error code
57indicating that they do not understand the authentication flavor, but
58not that they do not understand the request at all.
59
60\item It should require minimal or no changes to the standard Sun RPC
61programming paradigm for either clients or servers so that existing
62code can use it with little or no effort.
63
64\item It should operate correctly with all the standard Sun RPC
65transport mechansims (e.g. UDP and TCP).
66\saveenum{i}
67\end{enumerate}
68
69\section{Functional Specification}
70
71This section describes the programmer's interface to the GSS-API
72authentication flavor.   Knowledge of standard Sun RPC programming is
73assumed.
74
75\subsection{Client Side}
76
77A RPC client can select the GSS-API authentication flavor in the same
78way it can select any other authentication flavor, by setting the
79cl_auth field of the CLIENT structure to the appropriate value:
80
81\begin{verbatim}
82    clnt = clnt_create(server_host, PROG_NUM, PROG_VERS, protocol);
83    clnt->cl_auth = auth_gssapi_create(clnt, ...);
84\end{verbatim}
85
86There are two functions that create GSS-API authentication flavor
87structures for the cl_auth field, auth_gssapi_create and
88auth_gssapi_create_default.
89
90\begin{verbatim}
91AUTH *auth_gssapi_create(CLIENT         *clnt,
92                        OM_uint32       *major_status,
93                        OM_uint32       *minor_status,
94                        gss_cred_id_t   claimant_cred_handle,
95                        gss_name_t      target_name,
96                        gss_OID         mech_type,
97                        int             req_flags,
98                        int             time_req,
99                        gss_OID         *actual_mech_type,
100                        int             *ret_flags,
101                        OM_uint32       *time_rec);
102\end{verbatim}
103
104auth_gssapi_create creates a GSS-API authentication structure and
105provides most of the flexibility of gss_init_sec_context.  The
106arguments have the same interpretation as those of
107gss_init_sec_context with the same name, except:
108
109\begin{description}
110\item[clnt] The CLIENT structure returned by client_create or one of
111its relatives.  It is not modified.
112\end{description}
113
114auth_gssapi_create calls gss_init_sec_context as needed, passing each
115generated token to and processing each token returned from the RPC
116server specified by the RPC handle clnt.  On return, if major_status
117is GSS_S_COMPLETE, the context has been established, the returned AUTH
118structure is valid, and all of the arguments filled in by
119gss_init_sec_context have the correct values.  If major_status is not
120GSS_S_COMPLETE then it and minor_status contain error codes that can
121be passed to gss_display_status and the returned value is NULL.
122
123\begin{verbatim}
124AUTH *auth_gssapi_create_default(CLIENT *clnt, char *service_name);
125\end{verbatim}
126
127auth_gssapi_create_default is a shorthand for auth_gssapi_create that
128attempts to create a context that provides procedure call and result
129integrity, using the default credentials and GSS-API mechanism.
130service_name is parsed as a GSS-API ``service'' name and used as the
131target name.  The other arguments to auth_gssapi_create are as follows:
132
133\begin{verbatim}
134auth_gssapi_create(clnt,
135                   &dummy,
136                   &dummy,
137                   GSS_C_NO_CREDENTIAL,
138                   target_name,
139                   GSS_C_NULL_OID,
140                   GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG,
141                   0,
142                   NULL,
143                   NULL,
144                   NULL);
145\end{verbatim}
146
147Note that if the underlying default mechanism does not support data
148integrity (e.g. the trust mechanism), this function will fail.
149
150The GSS-API major and minor status codes can be interpreted with
151auth_gssapi_display_status:
152
153\begin{verbatim}
154void auth_gssapi_display_status(char *msg, OM_uint32 major,
155                                OM_uint32 minor);
156\end{verbatim}
157
158All of the error messages associated with the major and minor status
159are displated on the standard error output, preceeded by the message
160``GSS-API authentication error $<$msg$>$:''.
161
162\subsection{Server Side}
163
164\subsubsection{Service Name Registration}
165
166An application server must register the service name(s) that it will
167use for GSS-API connections before any AUTH_GSSAPI requests will
168succeed.
169
170\begin{verbatim}
171typedef struct _auth_gssapi_name {
172     char *name;
173     gss_OID type;
174} auth_gssapi_name;
175
176bool_t _svcauth_gssapi_set_names(auth_gssapi_name *names, int num);
177\end{verbatim}
178
179names is an array of name specifications, each of which consists of a
180null-terminated ASCII representation of a name and the GSS-API name
181type that should be used to import it with gss_import_name.  The
182name type ``gss_nt_service_name'' is recommended.
183
184\subsubsection{Calling Client and Service Identification}
185
186Each application server's dispatch function is passed two arguments,
187the transport mechanism (transp) and the RPC service request (rqstp).
188If the service request's credential flavor (rq_cred.oa_flavor) is
189AUTH_GSSAPI (300001)\footnote{The value 4 was originally used, but
190300001 has been officially assigned by the IETF.}, then the call has
191been authenticated.  The rq_clntcred field of transp contains the
192gss_name_t of the authenticated caller and can be passed to
193gss_display_name to obtain a string represtation or gss_compare_name
194to compare it with other names.  The rq_svccred field of transp
195contains the GSS-API context established with the caller and can be
196passed to gss_inquire_context.
197
198\subsubsection{Error Logging}
199
200An application server can register a function to be called when a
201failure occurs during GSS-API context establishment with
202_svcauth_set_log_badauth_func.
203
204\begin{verbatim}
205typedef void (*auth_gssapi_log_badauth_func)(OM_uint32 major,
206                                             OM_uint32 minor,
207                                             struct sockaddr_in *raddr,
208                                             caddr_t data);
209
210void _svcauth_set_log_badauth_func(auth_gssapi_log_badauth_func func,
211                                   caddr_t data);
212\end{verbatim}
213
214The function func is called each time gss_accept_sec_context fails.
215The major and minor arguments indicate the GSS-API major and minor
216status codes returned.  The raddr field contains the INET socket that
217the request came from, and the data field contains the data argument
218of _svcauth_gssapi_set_log_badauth_func.
219
220An application server can register a function to be called when an RPC
221request with an invalid verifier arrives with
222_svcauth_set_log_badverf_func.
223
224\begin{verbatim}
225typedef void (*auth_gssapi_log_badverf_func)(gss_name_t client,
226                                             gss_name_t server,
227                                             struct svc_req *rqst,
228                                             struct rpc_msg *msg,
229                                             caddr_t data);
230
231void _svcauth_set_log_badverf_func(auth_gssapi_log_badverf_func func,
232                                   caddr_t data);
233\end{verbatim}
234
235The function specified in func is called each time an invalid verifier
236is received.  The client and server fields identify the (falsely
237claimed) originating client and the server it originally authenticated
238to.  The raddr and addrlen fields contain the INET socket that the
239request (claims to have) come from, and data contains the data
240argument of _svcauth_set_log_badverf_func.
241
242\section{Modifications to Sun RPC}
243
244The Sun RPC extensible authentication mechanism is designed to allow
245different authentication systems to be integrated into Sun RPC easily.
246Unfortunately, it has two drawbacks.  First, the existing system has a
247number of non-general design properties that are intended specifically
248for Sun's Secure RPC, and second, the existing system has no concept
249of or ability to perform authentication-flavor-specific operations on
250function arguments and results passed over the wire.  The first
251problem merely makes the system confusing, since a number of features
252touted as ``general'' do not make any sense for arbitrary
253authentication systems.  The second problem is more substantial, and
254can only be corrected by modifications to Sun RPC internals.
255
256The following sections describe the necessary modifications to Sun
257RPC.
258
259\subsection{Client Side Authentication, AUTH Structure}
260
261The AUTH structure (figure \ref{fig:auth}) encapsulates the data and
262function pointers for an authentication flavor instance.  It has been
263changed in two ways.
264
265\begin{figure}[htbp]
266\begin{verbatim}
267typedef struct {
268        struct  opaque_auth     ah_cred;
269        struct  opaque_auth     ah_verf;
270        union   des_block       ah_key;
271        struct auth_ops {
272                void    (*ah_nextverf)();
273                int     (*ah_marshal)();        /* nextverf & serialize */
274                int     (*ah_validate)();       /* validate varifier */
275                int     (*ah_refresh)();        /* refresh credentials */
276                int     (*ah_wrap)();           /* encode data for wire */
277                int     (*ah_unwrap)();         /* decode data from wire */
278                void    (*ah_destroy)();        /* destroy this structure */
279        } *ah_ops;
280        caddr_t ah_private;
281} AUTH;
282\end{verbatim}
283\caption{The AUTH structure, with the new function pointers ah_wrap
284and ah_unwrap.}
285\label{fig:auth}
286\end{figure}
287
288First, the new functions ah_wrap and ah_unwrap prepare function
289arguments and results for transmission over the wire.  The
290authentication mechanism can use them to sign, encrypt, or perform any
291other operation on the data.  Their prototype is:
292
293\begin{verbatim}
294bool_t ah_wrap(AUTH *auth, XDR *out_xdrs, xdrproc_t func, caddr_t ptr);
295bool_t ah_unwrap(AUTH *auth, XDR *in_xdrs, xdrproc_t func, caddr_t ptr);
296\end{verbatim}
297
298ah_wrap encodes function arguments for transmission.  func and ptr are
299the XDR procedure and pointer that serialize the arguments, and
300out_xdrs is the xdr stream that the encoded arguments should be
301written to.  ah_unwrap decodes function arguments received from the
302network.  Its arguments are the converse of those to ah_wrap.
303
304It is the responsibility of RPC transport mechanisms to call an
305authorization flavor's ah_wrap and ah_unwrap functions when function
306arguments or results would normally be written to or read from the
307wire.  Authorization flavors that do not need to perform any encoding
308or decoding can use the provided function authany_wrap for ah_wrap
309and ah_unwrap; it consists of the single statement ``return
310(*func)(out_xdrs, ptr)'' (or in_xdrs, as appropriate).
311
312Second, the function ah_refresh has been changed to take the RPC error
313message that resulted in its being called as an argument.  This is
314necessary since the contents of the error message may dictate how
315ah_refresh should go about correcting the authentication failure.
316
317\subsection{Client Side Transport Mechanisms}
318
319Each client side transport mechanism must be modified to call the
320ah_wrap and ah_unwrap functions from the cl_auth field of the CLIENT
321structure during the call and reply process.  The modification is
322fairly simple.  For example, the UDP transport mechanism used to
323encode procedure calls like this:
324
325\begin{verbatim}
326        if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
327            (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
328            (! (*xargs)(xdrs, argsp)))
329                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
330\end{verbatim}
331
332The last function call in the conditional serializes the arguments
333onto the xdr stream.  This must be replaced with a call to the
334appropriate ah_wrap function:
335
336\begin{verbatim}
337        if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
338            (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
339            (! AUTH_WRAP(cl->cl_auth, xdrs, xargs, argsp)))
340                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
341\end{verbatim}
342
343AUTH_WRAP is a macro that takes the four arguments for an ah_wrap
344function and extracts and calls the function pointer from the cl_auth
345structure with the specified arguments.
346
347Similarly, the transport mechanism must unwrap procedure results.
348Again, the UDP mechanism will be instructive.  It used to deserialize
349function results like this:
350
351\begin{verbatim}
352        reply_msg.acpted_rply.ar_results.where = resultsp;
353        reply_msg.acpted_rply.ar_results.proc = xresults;
354
355        ok = xdr_replymsg(&reply_xdrs, &reply_msg);
356\end{verbatim}
357
358The problem here is that xdr_replymsg deserializes an entire reply
359message, including the results.  Since xresults and resultsp are the
360function and pointer to decode the results, they will be automatically
361deserialized {\it without} ah_unwrap being invoked.  The simplest
362solution (which is also the normal method used by the TCP mechanism)
363is to arrange to deserialize the function results explicitly:
364
365\begin{verbatim}
366        reply_msg.acpted_rply.ar_results.where = NULL;
367        reply_msg.acpted_rply.ar_results.proc = xdr_void;
368
369        if ((! xdr_replymsg(&reply_xdrs, &reply_msg)) ||
370            (! AUTH_UNWRAP(cl->cl_auth, reply_xdrs, xresults,
371                           resultsp))) {
372                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
373        }
374\end{verbatim}
375
376Since xdr_void does not read any data from the XDR stream, the
377function results are still available when AUTH_UNWRAP is called.  Note
378that AUTH_UNWRAP should only be called on {\it successful} calls; if
379the reply message status is not RPC_SUCCESS there are no arguments to
380read.
381
382Currently, the UDP and TCP transport mechanisms has been
383converted.\footnote{The ``raw'' mechanism, for direct connections, has
384not been.}
385
386\subsection{Service Side Authentication, SVCAUTH and XPRT}
387
388Standard Sun RPC service-side authentication consists of a single
389function per authentication flavor; there is no concept of an AUTH
390structure containing function pointers and private data as with the
391client side.  Previously, nothing else was necessary, because each
392flavor only did a single thing (authenticated individual calls in a
393stateless manner).  More functions and state are now required,
394however; they are stored in the SVCAUTH structure, see figure
395\ref{fig:svcauth}.
396
397\begin{figure}[htbp]
398\begin{verbatim}
399typedef struct {
400     struct svc_auth_ops {
401          int   (*svc_ah_wrap)();
402          int   (*svc_ah_unwrap)();
403     } *svc_ah_ops;
404     caddr_t svc_ah_private;
405} SVCAUTH;
406\end{verbatim}
407\caption{The new SVCAUTH structure.}
408\label{fig:svcauth}
409\end{figure}
410
411There is one SVCAUTH structure per authentication flavor (there is a
412default, svc_auth_any, for existing authentication flavors that do not
413need the extra functionality).  The svc_ah_wrap and svc_ah_unwrap
414perform the same logical function as their client-side counterparts.
415
416Just as with the client side, it is the responsibility of the
417transport mechanism to call the svc_ah_wrap and svc_ah_unwrap
418functions associated with the authentication flavor associated with
419each RPC call at the appropriate time.  Unfortunately, the transport
420mechanism code does not have access to the RPC call structure
421containing the authenticator flavor because the RPC call structure
422itself is not passed as an argument to the necessary functions.  The
423present solution is to add another argument to the transport mechanism
424structure, xp_auth, that stores the SVCAUTH of the {\it current} call
425on that mechanism; see figure \ref{fig:xprt}.  xp_auth is initialized
426to svc_auth_any so that existing authentication mechanisms that do not
427set the field will still operate correctly.  \footnote{This is not an
428great solution, because it forces each transport mechanism to be
429single threaded.  The correct solution is to store the SVCAUTH
430associated with each RPC call in the RPC call structure; however,
431doing so would require changing a lot of code to pass around the RPC
432call structure that currently does not do so.  Since other parts of
433Sun RPC use the XPRT structure in a non-reentrant way, the present
434solution does not make the situation any
435worse.}$^{\mbox{,}}$\footnote{A somewhat irrelevant side effect of
436adding SVCAUTH to XPRT is that the standard include file
437$<$rpc/rpc.h$>$ had to be changed to include $<$rpc/svc_auth$>$ before
438$<$rpc/svc.h$>$, whereas they used to be in the opposite order.}
439
440\begin{figure}[htbp]
441\begin{verbatim}
442typedef struct {
443        int             xp_sock;
444        u_short         xp_port;         /* associated port number */
445        struct xp_ops {
446            bool_t      (*xp_recv)();    /* receive incomming requests */
447            enum xprt_stat (*xp_stat)(); /* get transport status */
448            bool_t      (*xp_getargs)(); /* get arguments */
449            bool_t      (*xp_reply)();   /* send reply */
450            bool_t      (*xp_freeargs)();/* free mem allocated for args */
451            void        (*xp_destroy)(); /* destroy this struct */
452        } *xp_ops;
453        int             xp_addrlen;      /* length of remote address */
454        struct sockaddr_in xp_raddr;     /* remote address */
455        struct opaque_auth xp_verf;      /* raw response verifier */
456        SVCAUTH         *xp_auth;        /* auth flavor of current req */
457        caddr_t         xp_p1;           /* private */
458        caddr_t         xp_p2;           /* private */
459} SVCXPRT;
460\end{verbatim}
461\caption{The modified XPRT structure, with the xp_auth field.}
462\label{fig:xprt}
463\end{figure}
464
465Finally, with the modified XPRT structure carrying around the
466authentication flavor structure, the functions that serialize and
467deserialize function arguments and results must be modified to use the
468svc_ah_wrap and svc_ah_unwrap functions.  Each service-side transport
469mechanism has getargs and reply functions that must be modified to use
470the SVCAUTH_UNWRAP and SVCAUTH_WRAP macros, respectively, in a manner
471completely parallel to the client side.
472
473\subsection{Authenticated Service Identification, svc_req}
474
475Sun RPC provides the authenticated credentials of a client to the
476application server via rq_clntcred (``cooked credentials'') field of
477the service request (svc_req) structure.  In many authentication
478systems, services are also named entities, and there is no reason that
479an RPC should be restricted to accepting connections as a single
480authenticated service name.  However, access control decisions may be
481based on the service name a client authenticated to, so that
482information must be available to the application server.
483
484Figure \ref{fig:svc-req} shows the modified service request structure
485that contains a single new field, rq_svccred.  Like rq_clntcred, the
486authentication flavor is responsible for setting rq_svccred to the
487``cooked'' service credentials associated with a given RPC call.
488Authentication flavors that do not have the concept of service names
489can of course leave this field blank.
490
491\begin{figure}[htbp]
492\begin{verbatim}
493struct svc_req {
494        u_long          rq_prog;        /* service program number */
495        u_long          rq_vers;        /* service protocol version */
496        u_long          rq_proc;        /* the desired procedure */
497        struct opaque_auth rq_cred;     /* raw creds from the wire */
498        caddr_t         rq_clntcred;    /* read only cooked client cred */
499        caddr_t         rq_svccred;     /* read only cooked svc cred */
500        SVCXPRT         *rq_xprt;       /* associated transport */
501};
502\end{verbatim}
503\caption{The modified svc_req structure, with the rq_svccred field.}
504\label{fig:svc-req}
505\end{figure}
506
507
508
509\subsection{Authentication Negotiation, no_dispatch}
510
511In order to avoid having to transmit a full set of authentication
512information with every call, the service-side authentication mechanism
513must save state between calls.  Establishing that state may require
514multiple messages between the client-side and service-side
515authentication mechanisms.  The client-side authentication mechanism
516can make arbitrary RPC calls to the server simply by requiring the
517programmer to specify the CLIENT structure to the authentication
518flavor initialization routine.  The service side, however, is more
519complex.  In the normal course of events, an RPC call comes in, is
520authenticated, and is then dispatched to the appropriate procedure.
521For client- and service-side authentication flavors to communicate
522independent of the server implemented above the RPC layer, the
523service-side flavor must be able to send a reply to the client
524directly and {\it prevent} the call from being dispatched.
525
526This is implemented by a simple modification to the _authenticate
527routine, which dispatches each RPC call to the appropriate
528authentication flavor; see figure \ref{fig:authenticate}.  It takes an
529additional argument, no_dispatch, that instructs the mechanism not to
530dispatch the RPC call to the specified procedure.
531
532\begin{figure}[htbp]
533\begin{verbatim}
534                why=_authenticate(&r, &msg, &no_dispatch);
535                if (why != AUTH_OK) {
536                     svcerr_auth(xprt, why);
537                     goto call_done;
538                } else if (no_dispatch) {
539                     goto call_done;
540                }
541\end{verbatim}
542\caption{A call to the modified _authenticate.}
543\label{fig:authenticate}
544\end{figure}
545
546If _authenticate sets no_dispatch to true, the call is considered
547finished and no procedure dispatch takes place.  Presumably, an
548authentication flavor that sets no_dispatch to true also replies to
549the RPC call with svc_sendreply.  Authentication flavors that do not
550modify no_dispatch implicitly leave it set to false, so the normal
551dispatch takes place.
552
553\subsection{Affected Files}
554
555Table \ref{tab:modfiles} lists the files that were
556affected for each of the modifications described in previous sections.
557
558\begin{table}[htbp]
559\centering
560\caption{Files modified for each change to Sun RPC.}
561\label{tab:modfiles}
562\begin{tabular}{ll}
563AUTH structure                  & auth.h \\
564                                & auth_none.c \\
565                                & auth_exit.c \\
566                                & auth_any.c \\
567Client Transport Mechanisms     & clnt_udp.c \\
568                                & clnt_tcp.c \\
569SVCAUTH and XPRT structures     & rpc.h \\
570                                & svc.h \\
571                                & svc_auth.h \\
572                                & svc.c \\
573                                & svc_auth.c \\
574                                & svc_auth_any.c \\
575                                & svc_auth_unix.c \\
576Server Transport Mechanisms     & svc_udp.c \\
577                                & svc_tcp.c
578\end{tabular}
579\end{table}
580
581\section{GSS-API Authentication Flavor}
582
583The following sections describe the implementation of the GSS-API
584authentication flavor for Sun RPC.
585
586\subsection{Authentication Algorithms}
587\label{sec:algorithms}
588
589\subsubsection{Context Initiation}
590
591The client creates a GSS-API context with the server each time it
592calls auth_gssapi_create.  The context is created using the standard
593gss_init_sec_context and gss_accept_sec_context function calls.  The
594generated tokens are passed between the client and server as arguments
595and results of normal RPC calls.
596
597The client side, in auth_gssapi_create, performs the following steps
598to initiate a context:
599
600\begin{enumerate}
601\item\label{item:process-token} The client calls gss_init_sec_context.
602On the first such call, no input token is provided; on subsequent
603calls, the token received from the server is provided.
604
605\item If gss_init_sec_context produces an output token:
606
607\begin{enumerate}
608\item The client transmits the token to the server, identifying itself
609with client_handle if it has already been received (see next step).
610The return value from the server will contain a client_handle and one
611or both of a token and a signed initial sequence number.
612
613\item If this is the first response from the server, the client_handle
614is stored for subsequent calls.  Otherwise, the client_handle should be
615the same as returned on the previous call.
616
617\item If the response contains a signed initian sequence number but
618the context is not yet established, then the response also contains a
619token that will established the context.  The signed initial sequence
620number is stored.
621
622\item If the response contains a token, step \ref{item:process-token}
623repeated.
624\end{enumerate}
625
626\item The signed initial sequence number is verified using the
627established context.
628\end{enumerate}
629
630The server side, in _svcauth_gssapi, performs the following steps to
631initiate a context:
632
633\begin{enumerate}
634\item If a call arrives with no client_handle, a new client_handle is
635allocated and stored in the database.  Otherwise, the client's
636previous state is is looked up in the database.
637
638\item The received token is passed to gss_accept_sec_context.  If an
639output token is generated, it is returned to the client.  Note that
640since the application server may have registered multiple service
641names and there is no way to determine {\it a priori} which service a
642token is for, _svcauth_gssapi calls gss_accept_sec_context once for
643each registered credential until one of them succeeds.  The code
644assumes that GSS_S_FAILURE is the only error that can result from a
645credential mismatch, so any other error terminates the loop
646immediately.
647
648\item If the context is established, the server signs an initial
649sequence number and returns it to the client.
650\end{enumerate}
651
652Note that these algorithms require context establishment to be
653synchronous.  If gss_init_sec_context returns GSS_S_COMPLETE upon
654processing a token, it will either produce a token or not.  If it
655does, then gss_accept_sec_context will return GSS_S_COMPLETE when that
656token is processed; if it does not, then gss_accept_sec_context
657already returned GSS_S_COMPLETE (and presumably returned the token
658that caused gss_init_sec_context to return GSS_S_COMPLETE when
659processed).  The reverse is also true.
660
661\subsubsection{RPC Calls}
662
663After the GSS-API context is established, both the server and the
664client possess a client handle and a corresponding sequence number.
665Each call from the client contains the client handle as the
666``credential'' so that the server can identify which context to apply
667to the call.
668
669Each client call and server response includes a ``verifier'' that
670contains the sealed current sequence number.\footnote{In a future
671version, the verifier will also contain a signature block for the call
672header, including the procedure number called.} The sequence number
673prevents replay attacks\footnote{Although some GSS-API mechanisms
674provide replay detection themselves, not all of them do; explicitly
675including the sequence number in the RPC therefore provides better
676end-to-end security}, but by itself it does not prevent splicing
677attacks.
678
679Each procedure argument and result block consists of the current
680sequence number and the actual serialized argument string, all sealed
681with gss_seal.  Combining the sequence number with the argument/result
682data prevents splicing attacks.
683
684The sequence number is incremented by one for each RPC call and by one
685for each response.  The client and server will both reject messages
686that do not contain the expected sequence number.  Packets
687retransmitted by the client should use the {\it same} sequence number
688as the original packet, since even if the server receives multiple
689copies only one will be honored.
690
691\subsection{RPC Call Credential Structure}
692
693Every message transmitted from the client to the server has a
694credentials (cb_cred) field of the type auth_gssapi_creds:
695
696\begin{verbatim}
697typedef struct _auth_gssapi_creds {
698        bool_t       auth_msg;
699        gss_buffer_desc client_handle;
700};
701\end{verbatim}
702
703The auth_msg field indicates whether the message is intended for the
704authentication mechanism for the actual server.  Any message whose
705auth_msg field is true is processed by the authentication mechanism;
706any message whose auth_msg is false is passed to the application
707server's dispatch function if authentication succeeds.  All messages
708must have an auth_msg of true until the context is established, since
709authentication cannot succeed until it is.
710
711The client_handle field contains the client handle obtained from the
712first call to the server.  On the first call, this field is empty.
713
714\subsection{GSS-API Authentication Flavor Procedures}
715
716The GSS-API authentication flavor uses standard RPC calls over the
717client handle it is provided for the interactions described in
718\ref{sec:algorithms}.  All of the following procedures require the
719auth_msg field in the credentials to be true; otherwise, the
720server-side authentication flavor will simply attempt to authenticate
721the caller and pass the call to the application server.  The
722server-side authentication flavor uses the no_dispatch variable to
723indicate that it has handled the call.
724
725\subsubsection{AUTH_GSSAPI_INIT, AUTH_GSSAPI_CONTINUE_INIT}
726
727Context initiation is performed via AUTH_GSSAPI_INIT and
728AUTH_GSSAPI_CONTINUE_INIT.  The former is used to transfer the first
729token generated by gss_init_sec_context, when no client handle is
730included in the credentials; the latter is used on subsequent calls,
731when a client handle is included.
732
733Both procedures take an argument of type auth_gssapi_init_arg and
734return results of the type auth_gssapi_init_res.
735
736\begin{verbatim}
737typedef struct _auth_gssapi_init_arg {
738        u_long       version;
739        gss_buffer_desc token;
740} auth_gssapi_init_arg;
741\end{verbatim}
742
743\begin{description}
744\item[version]  Three versions are presently defined.
745
746\begin{description}
747\item[1] The original version, as described in this document
748
749\item[2] In earlier versions of Secure there was a bug in the GSS-API
750library that affected the contents of accept_sec_context output
751tokens.  A client specifies version 2 to indicate that it expects the
752correct (fixed) behavior.  If the server indicates AUTH_BADCRED or
753AUTH_FAILED it does not understand this version, so the client should
754fall back to version 1.
755
756\item[3] Version three indicates that channel bindings are in use.
757The client must specify channel bindings with the version, and the
758server will as well.  If the server indicates AUTH_BADCRED or
759AUTH_FAILED it does not understand this version, so the client should
760fall back to version 2 (and cease specifying channel bindings).
761
762\item[4] The previous versions all used the old GSS-API krb5 mechanism
763oid; this version uses the new one specified in the RFC.
764\end{description}
765
766\item[token] The token field contains the token generated by
767gss_init_sec_context.
768\end{description}
769
770\begin{verbatim}
771typedef struct _auth_gssapi_init_res {
772        u_long       version;
773        gss_buffer_desc client_handle;
774        gss_buffer_desc token;
775        OM_uint32 gss_major, gss_minor;
776        gss_buffer_desc signed_isn;
777} auth_gssapi_init_res;
778\end{verbatim}
779
780\begin{description}
781\item[version] There are two versions currently defined.
782\begin{description}
783\item[1] The original version, as described in this document.  This is
784the response version for {\it both} versions 1 and 2.  The Secure 1.1
785server will always return this version.
786
787\item[3] Version three indicates that the server specified channel
788bindings in response to a call arg version number of three.  The
789server must not specify this version unless the client does.
790\end{description}
791
792\item[client_handle] The client_handle field contains the client
793handle that the client must use in the credentials field in all
794subsequent RPC calls.  In response to AUTH_GSSAPI_CONTINUE_INIT, it is
795the same client handle that arrived in the credentials.
796
797\item[gss_major, gss_minor] The GSS-API error codes that resulted from
798processing the auth_gssapi_init_arg.  If gss_major is GSS_S_COMPLETE,
799the argument token was processed successfully.  Otherwise, gss_major
800and gss_minor contain the relevant major and minor status codes, and
801the context currently being negotiated is no longer valid.
802
803\item[token] In any response that the client is expecting another
804token (i.e.: gss_init_sec_context last returned GSS_S_CONTINUE), the
805token field contains the output token from gss_accept_sec_context.  If
806the client is not expecting a token and this field is not empty, an
807error has occurred.
808
809\item[signed_isn]  If the client is not expecting another token (i.e.:
810the previous call to gss_init_sec_context yielded a token and returned
811GSS_S_COMPLETE) or the supplied token completes the context, the
812signed_isn field contains the signed initial sequence number.  The
813server expects the first RPC call to have a sequence number one
814greater than the initial sequence number (so that the signed_isn block
815cannot be replayed).  If the client is expecting another token and the
816signed_isn field is not empty, an error has occurred.
817\end{description}
818
819\subsubsection{AUTH_GSSAPI_DESTROY}
820
821Context tear-down is performed via AUTH_GSSAPI_DESTROY.  This
822procedure takes no arguments and returns no results; it merely informs
823the server that the client wishes to destroy the established context.
824
825When a client wishes to tear down an established context between
826itself and a server, auth_gssapi_destroy first calls the
827AUTH_GSSAPI_DESTROY procedure.  The server authenticates the message
828and immediately sends a ``success'' response with no results.  The
829client and server then both independently call gss_delete_sec_context
830and discard the context-destruction token that is generated.
831
832No RPC error checking is performed by either the client or the server.
833The client waits a brief time for a success response from the server,
834but if none arrives it destroys the context anyway since presumably
835the user is waiting for the application to exit.  The server similar
836ignores any RPC errors since it knows that the client will ignore any
837errors that are reported.
838
839\subsection{RPC Call Authentication Implementation}
840
841Once the context has been established, all subsequent RPC calls are
842authenticated via the verifier described in section
843\ref{sec:algorithms}.
844
845auth_gssapi_marshall, invoked via AUTH_MARSHALL while the RPC call is
846being created on the client side, serializes the client_handle
847obtained during context initiation {\it in plaintext} as the
848credentials and serializes the current sequence number, sealed with
849gss_seal, as the verifier.
850
851auth_gssapi_wrap, invoked next via AUTH_WRAP, serializes a sealed
852token containing both the sequence number of the current call and the
853serialized arguments.
854
855_svcauth_gssapi, invoked on the server side by _authenticate, uses the
856client_handle contained in the credentials to look up the correct
857context and verifies the sequence number provided in the verifier; if
858the sequence number is not correct, it declares a potential replay
859attack.\footnote{Retransmitted packets will appear as replay attacks,
860of course.} The response verifier is set to the serialized sealed
861incremented sequence number.
862
863svc_auth_gssapi_unwrap, invoked when either the application server or
864_svcauth_gssapi (in response to an AUTH_GSSAPI authentication flavor
865message) attempts to read its arguments, deserialzes and unseals the
866block containing the current sequence number and serialized arguments.
867If the sequence number is incorrect, it declares a splicing attack;
868otherwise, it unserializes the arguments into the original structure.
869
870svc_auth_gssapi_wrap, invoked when either the application server or
871_svcauth_gssapi attempts to write its response, performs the same
872operation as auth_gssapi_wrap.
873
874auth_gssapi_validate, invoked by the client-side RPC mechanism when
875an RPC_SUCCESS response is received, verifies that the returned sequence
876number is one greater than the previous value sent by
877auth_gssapi_marshall.
878
879Finally, auth_gssapi_unwrap, invoked by the client-side RPC mechanism
880after auth_gssapi_validate succeeds, performs the same operation as
881svc_auth_gssapi_unwrap.
882
883If an RPC request generates an error message (a status of other than
884RPC_SUCCESS), auth_gssapi_refresh is called.  If the error status is
885AUTH_REJECTEDVERF, then the server rejected the sequence number as
886invalid or replayed.  The client guesses that, on some previous call,
887the server received a message but the server's response did not make
888it back to the client; this could happen if the packet got lost or if
889the server was being debugged and the client timed out waiting for it.
890As a result, the server is expected a higher sequence number than the
891client sent.  auth_gssapi_refresh increments the sequence number and
892returns true so that the call will be tried again.  The transport
893mechanism will only call auth_gssapi_refresh twice for each RPC
894request, so if some other error occurred an infinite loop will not
895result; however, it is unlikely the the client and server will be able
896to resynchronize after such an event.
897
898\subsection{Client State Information}
899
900The client-side GSS-API authentication flavor maintains an
901auth_gssapi_data structure for each authentication instance:
902
903\begin{verbatim}
904struct auth_gssapi_data {
905     bool_t established;
906     CLIENT *clnt;
907     gss_ctx_id_t context;
908     gss_buffer_desc client_handle;
909     u_long seq_num;
910     int def_cred;
911
912     /* pre-serialized ah_cred */
913     u_char cred_buf[MAX_AUTH_BYTES];
914     u_long cred_len;
915};
916\end{verbatim}
917
918The established field indicates whether the authentication context
919between the client and server has been established.  It is set to true
920when gss_init_sec_context returns GSS_S_COM\-PLETE.  When this field is
921false, the auth_gssapi functions marshall, validate, wrap, and unwrap
922mimic the ``no authentication'' flavor since there is no context with
923which to perform authentication functions.\footnote{This field is
924necessary because, when auth_gssapi_create calls clnt_call to make an
925RPC call, it has to have set the client's authentication flavor to
926AUTH_GSSAPI; otherwise, the service-side RPC mechanism will not know
927to dispatch the call to _svcauth_gssapi.  However, with the client's
928authentication flavor set, all of the authentication flavor's
929functions will be automatically invoked, even though they are not
930ready to operate.}
931
932The clnt field contains the RPC client structure that can be used to
933communicate with the GSS-API authentication flavor on the server.
934
935The context field contains the context structure created by
936gss_init_sec_context.
937
938The client_handle field contains the client handle used on all RPC
939calls except the first one; the handle is obtained as the result of
940the first call.
941
942The sequence_number field contains the sequence number that will be
943used when transmitting RPC calls to the server and verifying the
944server's responses after the context is initialized.
945
946The def_cred field is true if gss_init_sec_context created a default
947credential, in which case the authentication mechanism is responsible
948for releasing the default credential that gets automatically
949allocated.
950
951The cred_buf and cred_len fields contain the pre-serialized
952credentials structure used in each call.  This provides a small
953performance enhancement since the credentials structure does not
954change very often; the same pre-serialized version can be used on
955virtually every call.
956
957\subsection{Server State Information}
958\label{sec:server-state}
959
960The server-side GSS-API authentication flavor maintains an
961svcauth_gssapi_data structure for each established or partially
962established context:
963
964\begin{verbatim}
965typedef struct _svc_auth_gssapi_data {
966     bool_t established;
967     gss_ctx_id_t context;
968     gss_name_t client_name, server_name;
969     gss_cred_id_t server_creds;
970
971     u_long expiration;
972     u_long seq_num;
973     u_long key;
974
975     SVCAUTH svcauth;
976} svc_auth_gssapi_data;
977\end{verbatim}
978
979The established field indicates whether the context is fully
980established.
981
982The context field contains the context created by
983gss_accept_sec_context.
984
985The client_name field contains the client's authenticated name, as
986returned by gss_accept_sec_context.  _svcauth_gssapi sets the ``cooked
987credentials'' field of the RPC call structure to this value after the
988call is authenticated; the application server can use it to perform
989authorization.
990
991The server_name field contains the service name that the client
992established a context with.  This is useful if the application server
993registered more than one service name with the library; it allows the
994server to determine which service the client chose.
995
996The server_creds field contains the service credentials that the
997client established a context with.  It is used to avoid having to scan
998through the server_creds_list multiple times in the case that context
999establishment requires more than one round-trip to the server.
1000
1001The expiration field contains the expiration time of the context, as a
1002Unix timestamp.  If a context has no expiration (time_rec is
1003GSS_C_INDEFINITE), the expiration time is set to 24 hours in the
1004future.  When the structure is created, before the context is
1005established, the expiration time is initialized to small duration
1006(currently 5 minutes) so that partially created and abandoned contexts
1007will be expired quickly.
1008
1009The seq_num field is the current sequence number for the client.
1010
1011The key field is the client's key into the hash table (see below).
1012The client_handle field sent to the client is the key treated as an
1013arbitrary four-byte string.
1014
1015The svcauth field is a kludge that allows the svc_auth_gssapi
1016functions to access the per-client data structure while processing a
1017call.  One SVCAUTH structure is allocated for each client structure,
1018and the svc_ah_private field is set to the corresponding client.  The
1019client's svcauth field is then set to the new SVCAUTH structure, so
1020that client_data->svcauth->svc_ah_private == client_data.  As each
1021request is processed, the transport mechanism's xp_auth field is set
1022to the client's svcauth field; thus, the server-side functions that
1023dispatch to server-side authentication flavors can access an
1024appropriate SVCAUTH structure, and the server-side authentication
1025function that is called can determine the appropriate per-client
1026structure from the SVCAUTH structure.
1027
1028The per-client structures are all stored both in a BSD 4.4 db library
1029hash table and b-tree.  The hash table maps client handles (key
1030fields) the client structures, and is used to look up client
1031structures based on the client_handle field of a call's credentials
1032structure.  The b-tree stores the client structures as keys, sorted by
1033their expiration time.  Each time _svcauth_gssapi is activated, it
1034traverses the tree and destroys all client structures that have
1035expired.
1036
1037\end{document}
1038