"Fossies" - the Fresh Open Source Software Archive

Member "krb5-1.18/doc/rpc/design.tex" (12 Feb 2020, 43979 Bytes) of package /linux/misc/krb5-1.18.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) TeX and LaTeX source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    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 
   30 This document describes the integration of GSS-API authentication and
   31 security with Sun RPC.
   32 
   33 \section{Requirements}
   34 
   35 The 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
   39 servers.
   40 
   41 \item It must provide for integrity checking and encryption of all
   42 procedure arguments and results passed over the network.
   43 \saveenum{i}
   44 \end{enumerate}
   45 
   46 The 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
   52 called.
   53 
   54 \item It should obey the Sun RPC protocol so that clients using
   55 it can interoperate with existing servers.  In this case,
   56 ``interoperate'' means that existing servers will return an error code
   57 indicating that they do not understand the authentication flavor, but
   58 not that they do not understand the request at all.
   59 
   60 \item It should require minimal or no changes to the standard Sun RPC
   61 programming paradigm for either clients or servers so that existing
   62 code can use it with little or no effort.
   63 
   64 \item It should operate correctly with all the standard Sun RPC
   65 transport mechansims (e.g. UDP and TCP).
   66 \saveenum{i}
   67 \end{enumerate}
   68 
   69 \section{Functional Specification}
   70 
   71 This section describes the programmer's interface to the GSS-API
   72 authentication flavor.   Knowledge of standard Sun RPC programming is
   73 assumed.
   74 
   75 \subsection{Client Side}
   76 
   77 A RPC client can select the GSS-API authentication flavor in the same
   78 way it can select any other authentication flavor, by setting the
   79 cl_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 
   86 There are two functions that create GSS-API authentication flavor
   87 structures for the cl_auth field, auth_gssapi_create and
   88 auth_gssapi_create_default.
   89 
   90 \begin{verbatim}
   91 AUTH *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 
  104 auth_gssapi_create creates a GSS-API authentication structure and
  105 provides most of the flexibility of gss_init_sec_context.  The
  106 arguments have the same interpretation as those of
  107 gss_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
  111 its relatives.  It is not modified.
  112 \end{description}
  113 
  114 auth_gssapi_create calls gss_init_sec_context as needed, passing each
  115 generated token to and processing each token returned from the RPC
  116 server specified by the RPC handle clnt.  On return, if major_status
  117 is GSS_S_COMPLETE, the context has been established, the returned AUTH
  118 structure is valid, and all of the arguments filled in by
  119 gss_init_sec_context have the correct values.  If major_status is not
  120 GSS_S_COMPLETE then it and minor_status contain error codes that can
  121 be passed to gss_display_status and the returned value is NULL.
  122 
  123 \begin{verbatim}
  124 AUTH *auth_gssapi_create_default(CLIENT *clnt, char *service_name);
  125 \end{verbatim}
  126 
  127 auth_gssapi_create_default is a shorthand for auth_gssapi_create that
  128 attempts to create a context that provides procedure call and result
  129 integrity, using the default credentials and GSS-API mechanism.
  130 service_name is parsed as a GSS-API ``service'' name and used as the
  131 target name.  The other arguments to auth_gssapi_create are as follows:
  132 
  133 \begin{verbatim}
  134 auth_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 
  147 Note that if the underlying default mechanism does not support data
  148 integrity (e.g. the trust mechanism), this function will fail.
  149 
  150 The GSS-API major and minor status codes can be interpreted with
  151 auth_gssapi_display_status:
  152 
  153 \begin{verbatim}
  154 void auth_gssapi_display_status(char *msg, OM_uint32 major, 
  155                                 OM_uint32 minor); 
  156 \end{verbatim}
  157 
  158 All of the error messages associated with the major and minor status
  159 are 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 
  166 An application server must register the service name(s) that it will
  167 use for GSS-API connections before any AUTH_GSSAPI requests will
  168 succeed.
  169 
  170 \begin{verbatim}
  171 typedef struct _auth_gssapi_name {
  172      char *name;
  173      gss_OID type;
  174 } auth_gssapi_name;
  175 
  176 bool_t _svcauth_gssapi_set_names(auth_gssapi_name *names, int num);
  177 \end{verbatim}
  178 
  179 names is an array of name specifications, each of which consists of a
  180 null-terminated ASCII representation of a name and the GSS-API name
  181 type that should be used to import it with gss_import_name.  The
  182 name type ``gss_nt_service_name'' is recommended.
  183 
  184 \subsubsection{Calling Client and Service Identification}
  185 
  186 Each application server's dispatch function is passed two arguments,
  187 the transport mechanism (transp) and the RPC service request (rqstp).
  188 If the service request's credential flavor (rq_cred.oa_flavor) is
  189 AUTH_GSSAPI (300001)\footnote{The value 4 was originally used, but
  190 300001 has been officially assigned by the IETF.}, then the call has
  191 been authenticated.  The rq_clntcred field of transp contains the
  192 gss_name_t of the authenticated caller and can be passed to
  193 gss_display_name to obtain a string represtation or gss_compare_name
  194 to compare it with other names.  The rq_svccred field of transp
  195 contains the GSS-API context established with the caller and can be
  196 passed to gss_inquire_context.
  197 
  198 \subsubsection{Error Logging}
  199 
  200 An application server can register a function to be called when a
  201 failure occurs during GSS-API context establishment with
  202 _svcauth_set_log_badauth_func.
  203 
  204 \begin{verbatim}
  205 typedef void (*auth_gssapi_log_badauth_func)(OM_uint32 major,
  206                                              OM_uint32 minor,
  207                                              struct sockaddr_in *raddr,
  208                                              caddr_t data);
  209    
  210 void _svcauth_set_log_badauth_func(auth_gssapi_log_badauth_func func,
  211                                    caddr_t data); 
  212 \end{verbatim}
  213 
  214 The function func is called each time gss_accept_sec_context fails.
  215 The major and minor arguments indicate the GSS-API major and minor
  216 status codes returned.  The raddr field contains the INET socket that
  217 the request came from, and the data field contains the data argument
  218 of _svcauth_gssapi_set_log_badauth_func.
  219 
  220 An application server can register a function to be called when an RPC
  221 request with an invalid verifier arrives with
  222 _svcauth_set_log_badverf_func.
  223 
  224 \begin{verbatim}
  225 typedef 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 
  231 void _svcauth_set_log_badverf_func(auth_gssapi_log_badverf_func func,
  232                                    caddr_t data); 
  233 \end{verbatim}
  234 
  235 The function specified in func is called each time an invalid verifier
  236 is received.  The client and server fields identify the (falsely
  237 claimed) originating client and the server it originally authenticated
  238 to.  The raddr and addrlen fields contain the INET socket that the
  239 request (claims to have) come from, and data contains the data
  240 argument of _svcauth_set_log_badverf_func.
  241 
  242 \section{Modifications to Sun RPC}
  243 
  244 The Sun RPC extensible authentication mechanism is designed to allow
  245 different authentication systems to be integrated into Sun RPC easily.
  246 Unfortunately, it has two drawbacks.  First, the existing system has a
  247 number of non-general design properties that are intended specifically
  248 for Sun's Secure RPC, and second, the existing system has no concept
  249 of or ability to perform authentication-flavor-specific operations on
  250 function arguments and results passed over the wire.  The first
  251 problem merely makes the system confusing, since a number of features
  252 touted as ``general'' do not make any sense for arbitrary
  253 authentication systems.  The second problem is more substantial, and
  254 can only be corrected by modifications to Sun RPC internals.
  255 
  256 The following sections describe the necessary modifications to Sun
  257 RPC.
  258 
  259 \subsection{Client Side Authentication, AUTH Structure}
  260 
  261 The AUTH structure (figure \ref{fig:auth}) encapsulates the data and
  262 function pointers for an authentication flavor instance.  It has been
  263 changed in two ways.
  264 
  265 \begin{figure}[htbp]
  266 \begin{verbatim}
  267 typedef 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
  284 and ah_unwrap.}
  285 \label{fig:auth}
  286 \end{figure}
  287 
  288 First, the new functions ah_wrap and ah_unwrap prepare function
  289 arguments and results for transmission over the wire.  The
  290 authentication mechanism can use them to sign, encrypt, or perform any
  291 other operation on the data.  Their prototype is:
  292 
  293 \begin{verbatim}
  294 bool_t ah_wrap(AUTH *auth, XDR *out_xdrs, xdrproc_t func, caddr_t ptr);
  295 bool_t ah_unwrap(AUTH *auth, XDR *in_xdrs, xdrproc_t func, caddr_t ptr);
  296 \end{verbatim}
  297 
  298 ah_wrap encodes function arguments for transmission.  func and ptr are
  299 the XDR procedure and pointer that serialize the arguments, and
  300 out_xdrs is the xdr stream that the encoded arguments should be
  301 written to.  ah_unwrap decodes function arguments received from the
  302 network.  Its arguments are the converse of those to ah_wrap.
  303 
  304 It is the responsibility of RPC transport mechanisms to call an
  305 authorization flavor's ah_wrap and ah_unwrap functions when function
  306 arguments or results would normally be written to or read from the
  307 wire.  Authorization flavors that do not need to perform any encoding
  308 or decoding can use the provided function authany_wrap for ah_wrap
  309 and ah_unwrap; it consists of the single statement ``return
  310 (*func)(out_xdrs, ptr)'' (or in_xdrs, as appropriate).
  311 
  312 Second, the function ah_refresh has been changed to take the RPC error
  313 message that resulted in its being called as an argument.  This is
  314 necessary since the contents of the error message may dictate how
  315 ah_refresh should go about correcting the authentication failure.
  316 
  317 \subsection{Client Side Transport Mechanisms}
  318 
  319 Each client side transport mechanism must be modified to call the
  320 ah_wrap and ah_unwrap functions from the cl_auth field of the CLIENT
  321 structure during the call and reply process.  The modification is
  322 fairly simple.  For example, the UDP transport mechanism used to
  323 encode 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 
  332 The last function call in the conditional serializes the arguments
  333 onto the xdr stream.  This must be replaced with a call to the
  334 appropriate 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 
  343 AUTH_WRAP is a macro that takes the four arguments for an ah_wrap
  344 function and extracts and calls the function pointer from the cl_auth
  345 structure with the specified arguments.
  346 
  347 Similarly, the transport mechanism must unwrap procedure results.
  348 Again, the UDP mechanism will be instructive.  It used to deserialize
  349 function 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 
  358 The problem here is that xdr_replymsg deserializes an entire reply
  359 message, including the results.  Since xresults and resultsp are the
  360 function and pointer to decode the results, they will be automatically
  361 deserialized {\it without} ah_unwrap being invoked.  The simplest
  362 solution (which is also the normal method used by the TCP mechanism)
  363 is 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 
  376 Since xdr_void does not read any data from the XDR stream, the
  377 function results are still available when AUTH_UNWRAP is called.  Note
  378 that AUTH_UNWRAP should only be called on {\it successful} calls; if
  379 the reply message status is not RPC_SUCCESS there are no arguments to
  380 read.
  381 
  382 Currently, the UDP and TCP transport mechanisms has been
  383 converted.\footnote{The ``raw'' mechanism, for direct connections, has
  384 not been.}
  385 
  386 \subsection{Service Side Authentication, SVCAUTH and XPRT}
  387 
  388 Standard Sun RPC service-side authentication consists of a single
  389 function per authentication flavor; there is no concept of an AUTH
  390 structure containing function pointers and private data as with the
  391 client side.  Previously, nothing else was necessary, because each
  392 flavor only did a single thing (authenticated individual calls in a
  393 stateless manner).  More functions and state are now required,
  394 however; they are stored in the SVCAUTH structure, see figure
  395 \ref{fig:svcauth}.
  396 
  397 \begin{figure}[htbp]
  398 \begin{verbatim}
  399 typedef 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 
  411 There is one SVCAUTH structure per authentication flavor (there is a
  412 default, svc_auth_any, for existing authentication flavors that do not
  413 need the extra functionality).  The svc_ah_wrap and svc_ah_unwrap
  414 perform the same logical function as their client-side counterparts.
  415 
  416 Just as with the client side, it is the responsibility of the
  417 transport mechanism to call the svc_ah_wrap and svc_ah_unwrap
  418 functions associated with the authentication flavor associated with
  419 each RPC call at the appropriate time.  Unfortunately, the transport
  420 mechanism code does not have access to the RPC call structure
  421 containing the authenticator flavor because the RPC call structure
  422 itself is not passed as an argument to the necessary functions.  The
  423 present solution is to add another argument to the transport mechanism
  424 structure, xp_auth, that stores the SVCAUTH of the {\it current} call
  425 on that mechanism; see figure \ref{fig:xprt}.  xp_auth is initialized
  426 to svc_auth_any so that existing authentication mechanisms that do not
  427 set the field will still operate correctly.  \footnote{This is not an
  428 great solution, because it forces each transport mechanism to be
  429 single threaded.  The correct solution is to store the SVCAUTH
  430 associated with each RPC call in the RPC call structure; however,
  431 doing so would require changing a lot of code to pass around the RPC
  432 call structure that currently does not do so.  Since other parts of
  433 Sun RPC use the XPRT structure in a non-reentrant way, the present
  434 solution does not make the situation any
  435 worse.}$^{\mbox{,}}$\footnote{A somewhat irrelevant side effect of
  436 adding 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}
  442 typedef 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 
  465 Finally, with the modified XPRT structure carrying around the
  466 authentication flavor structure, the functions that serialize and
  467 deserialize function arguments and results must be modified to use the
  468 svc_ah_wrap and svc_ah_unwrap functions.  Each service-side transport
  469 mechanism has getargs and reply functions that must be modified to use
  470 the SVCAUTH_UNWRAP and SVCAUTH_WRAP macros, respectively, in a manner
  471 completely parallel to the client side.
  472 
  473 \subsection{Authenticated Service Identification, svc_req}
  474 
  475 Sun RPC provides the authenticated credentials of a client to the
  476 application server via rq_clntcred (``cooked credentials'') field of
  477 the service request (svc_req) structure.  In many authentication
  478 systems, services are also named entities, and there is no reason that
  479 an RPC should be restricted to accepting connections as a single
  480 authenticated service name.  However, access control decisions may be
  481 based on the service name a client authenticated to, so that
  482 information must be available to the application server.
  483 
  484 Figure \ref{fig:svc-req} shows the modified service request structure
  485 that contains a single new field, rq_svccred.  Like rq_clntcred, the
  486 authentication flavor is responsible for setting rq_svccred to the
  487 ``cooked'' service credentials associated with a given RPC call.
  488 Authentication flavors that do not have the concept of service names
  489 can of course leave this field blank.
  490 
  491 \begin{figure}[htbp]
  492 \begin{verbatim}
  493 struct 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 
  511 In order to avoid having to transmit a full set of authentication
  512 information with every call, the service-side authentication mechanism
  513 must save state between calls.  Establishing that state may require
  514 multiple messages between the client-side and service-side
  515 authentication mechanisms.  The client-side authentication mechanism
  516 can make arbitrary RPC calls to the server simply by requiring the
  517 programmer to specify the CLIENT structure to the authentication
  518 flavor initialization routine.  The service side, however, is more
  519 complex.  In the normal course of events, an RPC call comes in, is
  520 authenticated, and is then dispatched to the appropriate procedure.
  521 For client- and service-side authentication flavors to communicate
  522 indepedent of the server implemented above the RPC layer, the
  523 service-side flavor must be able to send a reply to the client
  524 directly and {\it prevent} the call from being dispatched.
  525 
  526 This is implemented by a simple modification to the _authenticate
  527 routine, which dispatches each RPC call to the appropriate
  528 authentication flavor; see figure \ref{fig:authenticate}.  It takes an
  529 additional argument, no_dispatch, that instructs the mechanism not to
  530 dispatch 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 
  546 If _authenticate sets no_dispatch to true, the call is considered
  547 finished and no procedure dispatch takes place.  Presumably, an
  548 authentication flavor that sets no_dispatch to true also replies to
  549 the RPC call with svc_sendreply.  Authentication flavors that do not
  550 modify no_dispatch implicitly leave it set to false, so the normal
  551 dispatch takes place.
  552 
  553 \subsection{Affected Files}
  554 
  555 Table \ref{tab:modfiles} lists the files that were
  556 affected 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}
  563 AUTH structure                  & auth.h \\
  564                                 & auth_none.c \\
  565                                 & auth_exit.c \\
  566                                 & auth_any.c \\
  567 Client Transport Mechanisms     & clnt_udp.c \\
  568                                 & clnt_tcp.c \\
  569 SVCAUTH 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 \\
  576 Server Transport Mechanisms     & svc_udp.c \\
  577                                 & svc_tcp.c
  578 \end{tabular}
  579 \end{table}
  580 
  581 \section{GSS-API Authentication Flavor}
  582 
  583 The following sections describe the implemetation of the GSS-API
  584 authentication flavor for Sun RPC.
  585 
  586 \subsection{Authentication Algorithms}
  587 \label{sec:algorithms}
  588 
  589 \subsubsection{Context Initiation}
  590 
  591 The client creates a GSS-API context with the server each time it
  592 calls auth_gssapi_create.  The context is created using the standard
  593 gss_init_sec_context and gss_accept_sec_context function calls.  The
  594 generated tokens are passed between the client and server as arguments
  595 and results of normal RPC calls.
  596 
  597 The client side, in auth_gssapi_create, performs the following steps
  598 to initiate a context:
  599 
  600 \begin{enumerate}
  601 \item\label{item:process-token} The client calls gss_init_sec_context.
  602 On the first such call, no input token is provided; on subsequent
  603 calls, 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
  609 with client_handle if it has already been received (see next step).
  610 The return value from the server will contain a client_handle and one
  611 or 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
  614 is stored for subsequent calls.  Otherwise, the client_handle should be
  615 the same as returned on the previous call.
  616 
  617 \item If the response contains a signed initian sequence number but
  618 the context is not yet established, then the response also contains a
  619 token that will established the context.  The signed initial sequence
  620 number is stored.
  621 
  622 \item If the response contains a token, step \ref{item:process-token}
  623 repeated.
  624 \end{enumerate}
  625 
  626 \item The signed initial sequence number is verified using the
  627 established context.
  628 \end{enumerate}
  629 
  630 The server side, in _svcauth_gssapi, performs the following steps to
  631 initiate a context:
  632 
  633 \begin{enumerate}
  634 \item If a call arrives with no client_handle, a new client_handle is
  635 allocated and stored in the database.  Otherwise, the client's
  636 previous state is is looked up in the database.
  637 
  638 \item The received token is passed to gss_accept_sec_context.  If an
  639 output token is generated, it is returned to the client.  Note that
  640 since the application server may have registered multiple service
  641 names and there is no way to determine {\it a priori} which service a
  642 token is for, _svcauth_gssapi calls gss_accept_sec_context once for
  643 each registered credential until one of them succeedes.  The code
  644 assumes that GSS_S_FAILURE is the only error that can result from a
  645 credential mismatch, so any other error terminates the loop
  646 immediately.
  647 
  648 \item If the context is established, the server signs an initial
  649 sequence number and returns it to the client.
  650 \end{enumerate}
  651 
  652 Note that these algorithms require context establishment to be
  653 synchronous.  If gss_init_sec_context returns GSS_S_COMPLETE upon
  654 processing a token, it will either produce a token or not.  If it
  655 does, then gss_accept_sec_context will return GSS_S_COMPLETE when that
  656 token is processed; if it does not, then gss_accept_sec_context
  657 already returned GSS_S_COMPLETE (and presumably returned the token
  658 that caused gss_init_sec_context to return GSS_S_COMPLETE when
  659 processed).  The reverse is also true.
  660 
  661 \subsubsection{RPC Calls}
  662 
  663 After the GSS-API context is established, both the server and the
  664 client posess a client handle and a corresponding sequence number.
  665 Each call from the client contains the client handle as the
  666 ``credential'' so that the server can identify which context to apply
  667 to the call.
  668 
  669 Each client call and server response includes a ``verifier'' that
  670 contains the sealed current sequence number.\footnote{In a future
  671 version, the verifier will also contain a signature block for the call
  672 header, including the procedure number called.} The sequence number
  673 prevents replay attacks\footnote{Although some GSS-API mechanisms
  674 provide replay detection themselves, not all of them do; explicitly
  675 including the sequence number in the RPC therefore provides better
  676 end-to-end security}, but by itself it does not prevent splicing
  677 attacks.
  678 
  679 Each procedure argument and result block consists of the current
  680 sequence number and the actual serialized argument string, all sealed
  681 with gss_seal.  Combining the sequence number with the argument/result
  682 data prevents splicing attacks.
  683 
  684 The sequence number is incremented by one for each RPC call and by one
  685 for each response.  The client and server will both reject messages
  686 that do not contain the expected sequence number.  Packets
  687 retransmitted by the client should use the {\it same} sequence number
  688 as the original packet, since even if the server receives multiple
  689 copies only one will be honored.
  690 
  691 \subsection{RPC Call Credential Structure}
  692 
  693 Every message transmitted from the client to the server has a
  694 credentials (cb_cred) field of the type auth_gssapi_creds:
  695 
  696 \begin{verbatim}
  697 typedef struct _auth_gssapi_creds {
  698         bool_t       auth_msg;
  699         gss_buffer_desc client_handle;
  700 };
  701 \end{verbatim}
  702 
  703 The auth_msg field indicates whether the message is intended for the
  704 authentication mechanism for the actual server.  Any message whose
  705 auth_msg field is true is processed by the authentication mechanism;
  706 any message whose auth_msg is false is passed to the application
  707 server's dispatch function if authentication suceeds.  All messages
  708 must have an auth_msg of true until the context is established, since
  709 authentication cannot succeed until it is.
  710 
  711 The client_handle field contains the client handle obtained from the
  712 first call to the server.  On the first call, this field is empty.
  713 
  714 \subsection{GSS-API Authentication Flavor Procedures}
  715 
  716 The GSS-API authentication flavor uses standard RPC calls over the
  717 client handle it is provided for the interactions described in
  718 \ref{sec:algorithms}.  All of the following procedures require the
  719 auth_msg field in the credentials to be true; otherwise, the
  720 server-side authentication flavor will simply attempt to authenticate
  721 the caller and pass the call to the application server.  The
  722 server-side authentication flavor uses the no_dispatch variable to
  723 indicate that it has handled the call.
  724 
  725 \subsubsection{AUTH_GSSAPI_INIT, AUTH_GSSAPI_CONTINUE_INIT}
  726 
  727 Context initiation is performed via AUTH_GSSAPI_INIT and
  728 AUTH_GSSAPI_CONTINUE_INIT.  The former is used to transfer the first
  729 token generated by gss_init_sec_context, when no client handle is
  730 included in the credentials; the latter is used on subsequent calls,
  731 when a client handle is included.
  732 
  733 Both procedures take an argument of type auth_gssapi_init_arg and
  734 return results of the type auth_gssapi_init_res.
  735 
  736 \begin{verbatim}
  737 typedef 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
  750 library that affected the contents of accept_sec_context output
  751 tokens.  A client specifies version 2 to indicate that it expects the
  752 correct (fixed) behavior.  If the server indicates AUTH_BADCRED or
  753 AUTH_FAILED it does not understand this version, so the client should
  754 fall back to version 1.
  755 
  756 \item[3] Version three indicates that channel bindings are in use.
  757 The client must specify channel bindings with the version, and the
  758 server will as well.  If the server indicates AUTH_BADCRED or
  759 AUTH_FAILED it does not understand this version, so the client should
  760 fall back to version 2 (and cease specifying channel bindings).
  761 
  762 \item[4] The previous versions all used the old GSS-API krb5 mechanism
  763 oid; 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
  767 gss_init_sec_context.
  768 \end{description}
  769 
  770 \begin{verbatim}
  771 typedef 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
  784 the response version for {\it both} versions 1 and 2.  The Secure 1.1
  785 server will always return this version.
  786 
  787 \item[3] Version three indicates that the server specified channel
  788 bindings in response to a call arg version number of three.  The
  789 server must not specify this version unless the client does.
  790 \end{description}
  791 
  792 \item[client_handle] The client_handle field contains the client
  793 handle that the client must use in the credentials field in all
  794 subsequent RPC calls.  In response to AUTH_GSSAPI_CONTINUE_INIT, it is
  795 the same client handle that arrived in the credentials.
  796 
  797 \item[gss_major, gss_minor] The GSS-API error codes that resulted from
  798 processing the auth_gssapi_init_arg.  If gss_major is GSS_S_COMPLETE,
  799 the argument token was processed successfully.  Otherwise, gss_major
  800 and gss_minor contain the relevant major and minor status codes, and
  801 the context currently being negotiated is no longer valid.
  802 
  803 \item[token] In any response that the client is expecting another
  804 token (i.e.: gss_init_sec_context last returned GSS_S_CONTINUE), the
  805 token field contains the output token from gss_accept_sec_context.  If
  806 the client is not expecting a token and this field is not empty, an
  807 error has occurred.
  808 
  809 \item[signed_isn]  If the client is not expecting another token (i.e.:
  810 the previous call to gss_init_sec_context yielded a token and returned
  811 GSS_S_COMPLETE) or the supplied token completes the context, the
  812 signed_isn field contains the signed initial sequence number.  The
  813 server expects the first RPC call to have a sequence number one
  814 greater than the initial sequence number (so that the signed_isn block
  815 cannot be replayed).  If the client is expecting another token and the
  816 signed_isn field is not empty, an error has occurred.
  817 \end{description}
  818 
  819 \subsubsection{AUTH_GSSAPI_DESTROY}
  820 
  821 Context tear-down is performed via AUTH_GSSAPI_DESTROY.  This
  822 procedure takes no arguments and returns no results; it merely informs
  823 the server that the client wishes to destroy the established context.
  824 
  825 When a client wishes to tear down an established context between
  826 itself and a server, auth_gssapi_destroy first calls the
  827 AUTH_GSSAPI_DESTROY procedure.  The server authenticates the message
  828 and immediately sends a ``success'' response with no results.  The
  829 client and server then both independently call gss_delete_sec_context
  830 and discard the context-destruction token that is generated.
  831 
  832 No RPC error checking is performed by either the client or the server.
  833 The client waits a brief time for a success response from the server,
  834 but if none arrives it destroys the context anyway since presumably
  835 the user is waiting for the application to exit.  The server similar
  836 ignores any RPC errors since it knows that the client will ignore any
  837 errors that are reported.
  838 
  839 \subsection{RPC Call Authentication Implementation}
  840 
  841 Once the context has been established, all subsequent RPC calls are
  842 authenticated via the verifier described in section
  843 \ref{sec:algorithms}.
  844 
  845 auth_gssapi_marshall, invoked via AUTH_MARSHALL while the RPC call is
  846 being created on the client side, serializes the client_handle
  847 obtained during context initiation {\it in plaintext} as the
  848 credentials and serializes the current sequence number, sealed with
  849 gss_seal, as the verifier.
  850 
  851 auth_gssapi_wrap, invoked next via AUTH_WRAP, serializes a sealed
  852 token containing both the sequence number of the current call and the
  853 serialized arguments.
  854 
  855 _svcauth_gssapi, invoked on the server side by _authenticate, uses the
  856 client_handle contained in the credentials to look up the correct
  857 context and verifies the sequence number provided in the verifier; if
  858 the sequence number is not correct, it declares a potential replay
  859 attack.\footnote{Retransmitted packets will appear as replay attacks,
  860 of course.} The response verifier is set to the serialized sealed
  861 incremented sequence number.
  862 
  863 svc_auth_gssapi_unwrap, invoked when either the application server or
  864 _svcauth_gssapi (in response to an AUTH_GSSAPI authentication flavor
  865 message) attempts to read its arguments, deserialzes and unseals the
  866 block containing the current sequence number and serialized arguments.
  867 If the sequence number is incorrect, it declares a splicing attack;
  868 otherwise, it unserializes the arguments into the original structure.
  869 
  870 svc_auth_gssapi_wrap, invoked when either the application server or
  871 _svcauth_gssapi attempts to write its response, performs the same
  872 operation as auth_gssapi_wrap.
  873 
  874 auth_gssapi_validate, invoked by the client-side RPC mechanism when
  875 an RPC_SUCCESS response is received, verifies that the returned sequence
  876 number is one greater than the previous value sent by
  877 auth_gssapi_marshall.
  878 
  879 Finally, auth_gssapi_unwrap, invokved by the client-side RPC mechanism
  880 after auth_gssapi_validate succeeds, performs the same operation as
  881 svc_auth_gssapi_unwrap.
  882 
  883 If an RPC request generates an error message (a status of other than
  884 RPC_SUCCESS), auth_gssapi_refresh is called.  If the error status is
  885 AUTH_REJECTEDVERF, then the server rejected the sequence number as
  886 invalid or replayed.  The client guesses that, on some previous call,
  887 the server received a message but the server's response did not make
  888 it back to the client; this could happen if the packet got lost or if
  889 the server was being debugged and the client timed out waiting for it.
  890 As a result, the server is expected a higher sequence number than the
  891 client sent.  auth_gssapi_refresh increments the sequence number and
  892 returns true so that the call will be tried again.  The transport
  893 mechanism will only call auth_gssapi_refresh twice for each RPC
  894 request, so if some other error occurred an infinite loop will not
  895 result; however, it is unlikely the the client and server will be able
  896 to resynchronize after such an event.
  897 
  898 \subsection{Client State Information}
  899 
  900 The client-side GSS-API authentication flavor maintains an
  901 auth_gssapi_data structure for each authentication instance:
  902 
  903 \begin{verbatim}
  904 struct 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 
  918 The established field indicates whether the authentication context
  919 between the client and server has been established.  It is set to true
  920 when gss_init_sec_context returns GSS_S_COM\-PLETE.  When this field is
  921 false, the auth_gssapi functions marshall, validate, wrap, and unwrap
  922 mimic the ``no authentication'' flavor since there is no context with
  923 which to perform authentication functions.\footnote{This field is
  924 necessary because, when auth_gssapi_create calls clnt_call to make an
  925 RPC call, it has to have set the client's authentication flavor to
  926 AUTH_GSSAPI; otherwise, the service-side RPC mechanism will not know
  927 to dispatch the call to _svcauth_gssapi.  However, with the client's
  928 authentication flavor set, all of the authentication flavor's
  929 functions will be automatically invoked, even though they are not
  930 ready to operate.}
  931 
  932 The clnt field contains the RPC client structure that can be used to
  933 communicate with the GSS-API authentication flavor on the server.
  934 
  935 The context field contains the context structure created by
  936 gss_init_sec_context.
  937 
  938 The client_handle field contains the client handle used on all RPC
  939 calls except the first one; the handle is obtained as the result of
  940 the first call.
  941 
  942 The sequence_number field contains the sequence number that will be
  943 used when transmitting RPC calls to the server and verifing the
  944 server's responses after the context is initialized.
  945 
  946 The def_cred field is true if gss_init_sec_context created a default
  947 credential, in which case the authentication mechanism is responsible
  948 for releasing the default credential that gets automatically
  949 allocated.
  950 
  951 The cred_buf and cred_len fields contain the pre-serialized
  952 credentials structure used in each call.  This provides a small
  953 performance enhancement since the credentials structure does not
  954 change very often; the same pre-serialized version can be used on
  955 virtually every call.
  956 
  957 \subsection{Server State Information}
  958 \label{sec:server-state}
  959 
  960 The server-side GSS-API authentication flavor maintains an
  961 svcauth_gssapi_data structure for each established or partially
  962 established context:
  963 
  964 \begin{verbatim}
  965 typedef 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 
  979 The established field indicates whether the context is fully
  980 established.
  981 
  982 The context field contains the context created by
  983 gss_accept_sec_context.
  984 
  985 The client_name field contains the client's authenticated name, as
  986 returned by gss_accept_sec_context.  _svcauth_gssapi sets the ``cooked
  987 credentials'' field of the RPC call structure to this value after the
  988 call is authenticated; the application server can use it to perform
  989 authorization.
  990 
  991 The server_name field contains the service name that the client
  992 established a context with.  This is useful if the application server
  993 registered more than one service name with the library; it allows the
  994 server to determine which service the client chose.
  995 
  996 The server_creds field contains the service credentials that the
  997 client established a context with.  It is used to avoid having to scan
  998 through the server_creds_list multiple times in the case that context
  999 establishment requires more than one round-trip to the server.
 1000 
 1001 The expiration field contains the expiration time of the context, as a
 1002 Unix timestamp.  If a context has no expiration (time_rec is
 1003 GSS_C_INDEFINITE), the expiration time is set to 24 hours in the
 1004 future.  When the structure is created, before the context is
 1005 established, the expiration time is initialized to small duration
 1006 (currently 5 minutes) so that partially created and abandoned contexts
 1007 will be expired quickly.
 1008 
 1009 The seq_num field is the current sequence number for the client.
 1010 
 1011 The key field is the client's key into the hash table (see below).
 1012 The client_handle field sent to the client is the key treated as an
 1013 arbitrary four-byte string.
 1014 
 1015 The svcauth field is a kludge that allows the svc_auth_gssapi
 1016 functions to access the per-client data structure while processing a
 1017 call.  One SVCAUTH structure is allocated for each client structure,
 1018 and the svc_ah_private field is set to the corresponding client.  The
 1019 client's svcauth field is then set to the new SVCAUTH structure, so
 1020 that client_data->svcauth->svc_ah_private == client_data.  As each
 1021 request is processed, the transport mechanism's xp_auth field is set
 1022 to the client's svcauth field; thus, the server-side functions that
 1023 dispatch to server-side authentication flavors can access an
 1024 appropriate SVCAUTH structure, and the server-side authentication
 1025 function that is called can determine the appropriate per-client
 1026 structure from the SVCAUTH structure.
 1027 
 1028 The per-client structures are all stored both in a BSD 4.4 db library
 1029 hash table and b-tree.  The hash table maps client handles (key
 1030 fields) the client structures, and is used to look up client
 1031 structures based on the client_handle field of a call's credentials
 1032 structure.  The b-tree stores the client structures as keys, sorted by
 1033 their expiration time.  Each time _svcauth_gssapi is activated, it
 1034 traverses the tree and destroys all client structures that have
 1035 expired.
 1036 
 1037 \end{document}