RFC 1831

RPC: Remote Procedure Call Protocol Specification Version 2

πŸ“… published August 1995, from ietf

RFC 1831: RPC: Remote Procedure Call Protocol Specification Version 2 πŸŽ€

okay so this is the RFC that defines ONC RPC Version 2 πŸ’–. Written by R. Srinivasan at Sun Microsystems for the Network Working Group, it's on the Standards Track and dates from August 1995 πŸ¦‹. The header doesn't list anything it obsoletes or updates, so it stands on its own ✨.


Status of this Memo ✨

this one is an Internet standards track protocol for the Internet community, and it's literally asking for discussion and suggestions for improvements 🫢. For the current standardization state and status, check the "Internet Official Protocol Standards" (STD 1) doc. And distribution of this memo is unlimited 🌈.

ABSTRACT πŸ”₯

this doc describes ONC Remote Procedure Call (ONC RPC Version 2) as it's currently deployed and accepted πŸ’…. "ONC" stands for "Open Network Computing" 🌸.

TABLE OF CONTENTS πŸ“‹

      1. INTRODUCTION                                              2
      2. TERMINOLOGY                                               2
      3. THE RPC MODEL                                             2
      4. TRANSPORTS AND SEMANTICS                                  4
      5. BINDING AND RENDEZVOUS INDEPENDENCE                       5
      6. AUTHENTICATION                                            5
      7. RPC PROTOCOL REQUIREMENTS                                 5
      7.1 RPC Programs and Procedures                              6
      7.2 Authentication                                           7
      7.3 Program Number Assignment                                8
      7.4 Other Uses of the RPC Protocol                           8
      7.4.1 Batching                                               8
      7.4.2 Broadcast Remote Procedure Calls                       8
      8. THE RPC MESSAGE PROTOCOL                                  9
      9. AUTHENTICATION PROTOCOLS                                 12
      9.1 Null Authentication                                     13
      10. RECORD MARKING STANDARD                                 13
      11. THE RPC LANGUAGE                                        13
      11.1 An Example Service Described in the RPC Language       13
      11.2 The RPC Language Specification                         14
      11.3 Syntax Notes                                           15
      APPENDIX A: SYSTEM AUTHENTICATION                           16
      REFERENCES                                                  17
      Security Considerations                                     18
      Author's Address                                            18

1. Introduction ✨

this doc specifies version two of the message protocol used in ONC Remote Procedure Call (RPC) πŸ’–. The message protocol is written in the eXternal Data Representation (XDR) language [9], and it assumes you already know XDR πŸŽ€. It doesn't try to justify remote procedure call systems or explain how they're used. If you want great background on the RPC concept, the paper by Birrell and Nelson [1] is recommended πŸ“š.

2. Terminology πŸ¦‹

this doc talks about clients, calls, servers, replies, services, programs, procedures, and versions 🧚. Each remote procedure call has two sides: an active client side that makes the call to a server, which sends back a reply πŸ’œ. A network service is a collection of one or more remote programs. A remote program implements one or more remote procedures, and the procedures, their parameters, and results are documented in that program's protocol specification 🌈. A server may support more than one version of a remote program so it can stay compatible with changing protocols ✨.

For example, a network file service could be made of two programs πŸ“. One program might handle high-level stuff like file system access control and locking. The other might handle low-level file input and output with procedures like "read" and "write" πŸ’…. A client of the network file service would call the procedures of the two programs on its behalf 🫢.

The terms client and server only apply to a particular transaction 🌸. A particular hardware entity (host) or software entity (process or program) can operate in both roles at different times πŸ‘‘. For example, a program that supplies remote execution service could also be a client of a network file service 😭.

3. The RPC Model πŸ’–

The ONC RPC protocol is based on the remote procedure call model, which is similar to the local procedure call model πŸŽ€. In the local case, the caller places arguments to a procedure in some well-specified location (such as a register window) πŸ¦‹. It then transfers control to the procedure, and eventually regains control. At that point, the results are extracted from the well-specified location, and the caller keeps on executing 🧚.

The remote procedure call model is similar πŸ’œ. One thread of control logically winds through two processes: the caller's process, and a server's process 🌈. The caller process first sends a call message to the server process and waits (blocks) for a reply message ✨. The call message includes the procedure's parameters, and the reply message includes the procedure's results πŸ“. Once the reply message arrives, the results are extracted and the caller's execution resumes πŸ’….

On the server side, a process is dormant until a call message shows up 🫢. When one arrives, the server process extracts the procedure's parameters, computes the results, sends a reply message, and then waits for the next call message 🌸.

In this model, only one of the two processes is active at any given time πŸ‘‘. But this model is only given as an example 😭. The ONC RPC protocol makes no restrictions on the concurrency model implemented, and others are possible πŸ”₯. For example, an implementation may choose to have RPC calls be asynchronous, so the client can do useful work while waiting for the server's reply πŸ¦‹. Another possibility is to have the server create a separate task to process an incoming call, so the original server is free to receive other requests 🧚.

There are a few important ways that remote procedure calls differ from local procedure calls πŸ’…:

  1. Error handling: failures of the remote server or network must be handled when using remote procedure calls.
  2. Global variables and side-effects: since the server does not have access to the client's address space, hidden arguments cannot be passed as global variables or returned as side effects.
  3. Performance: remote procedures usually operate one or more orders of magnitude slower than local procedure calls 🐒.
  4. Authentication: since remote procedure calls can be transported over unsecured networks, authentication may be necessary. Authentication prevents one entity from masquerading as some other entity πŸ™ˆ.

The conclusion is that even though there are tools to automatically generate client and server libraries for a given service, protocols must still be designed carefully 🫢.

4. Transports and Semantics πŸ¦‹

The RPC protocol can be implemented on several different transport protocols 🌈. The RPC protocol doesn't care how a message gets passed from one process to another. It only cares about the specification and interpretation of messages ✨. However, the application may want to get information about (and maybe control over) the transport layer through an interface that isn't specified in this document πŸ’œ. For example, the transport protocol may impose a restriction on the maximum size of RPC messages, or it may be stream-oriented like TCP with no size limit πŸ“. The client and server must agree on their transport protocol choices 🫢.

It's important to point out that RPC does not try to implement any kind of reliability, and the application may need to be aware of the type of transport protocol underneath RPC πŸ”₯. If it knows it's running on top of a reliable transport such as TCP [6], then most of the work is already done for it πŸ‘‘. On the other hand, if it's running on top of an unreliable transport such as UDP [7], it must implement its own time-out, retransmission, and duplicate detection policies, because the RPC protocol doesn't provide these services 😭.

Because of transport independence, the RPC protocol doesn't attach specific semantics to the remote procedures or their execution requirements 🧚. Semantics can be inferred from (but should be explicitly specified by) the underlying transport protocol πŸ’…. For example, consider RPC running on top of an unreliable transport such as UDP. If an application retransmits RPC call messages after time-outs and doesn't receive a reply, it can't infer anything about the number of times the procedure was executed πŸ™ˆ. If it does receive a reply, then it can infer that the procedure was executed at least once πŸŽ€.

A server may want to remember previously granted requests from a client and not regrant them, in order to ensure some degree of execute-at-most-once semantics 🌸. A server can do this by taking advantage of the transaction ID that comes packaged with every RPC message πŸ’–. The main use of this transaction ID is by the client RPC entity, which uses it to match replies to calls πŸ¦‹. However, a client application may choose to reuse its previous transaction ID when retransmitting a call 🧚. The server may choose to remember this ID after executing a call and not execute calls with the same ID, in order to achieve some degree of execute-at-most-once semantics πŸ’œ. The server is not allowed to examine this ID in any other way except as a test for equality 🫢.

On the other hand, if using a "reliable" transport such as TCP, the application can infer from a reply message that the procedure was executed exactly once 🌈. But if it receives no reply message, it can't assume the remote procedure wasn't executed 😭. Note that even if a connection-oriented protocol like TCP is used, an application still needs time-outs and reconnection to handle server crashes πŸ’€.

There are other possibilities for transports besides datagram- or connection-oriented protocols πŸ“. For example, a request-reply protocol such as VMTP [2] is perhaps a natural transport for RPC ✨. ONC RPC uses both TCP and UDP transport protocols πŸ‘‘. Section 10 (RECORD MARKING STANDARD) describes the mechanism ONC RPC uses to utilize a connection-oriented, stream-oriented transport such as TCP πŸŽ€.

5. Binding and Rendezvous Independence πŸ’…

The act of binding a particular client to a particular service and transport parameters is NOT part of this RPC protocol specification πŸ™ˆ. This important and necessary function is left up to some higher-level software 🫢.

Implementors could think of the RPC protocol as the jump-subroutine instruction ("JSR") of a network 🧚. The loader (binder) makes JSR useful, and the loader itself uses JSR to accomplish its task 🌸. Likewise, the binding software makes RPC useful, possibly using RPC to accomplish this task πŸ”₯.

6. Authentication 🌈

The RPC protocol provides the fields necessary for a client to identify itself to a service, and vice-versa, in each call and reply message πŸ’–. Security and access control mechanisms can be built on top of this message authentication πŸ‘‘. Several different authentication protocols can be supported πŸ¦‹. A field in the RPC header indicates which protocol is being used ✨. More information on specific authentication protocols is in section 9: "Authentication Protocols" πŸ“.


(Part 1 of 4 done, bestie! πŸ’œ Sections 7 onward are coming next 🧚✨)

7. RPC Protocol Requirements ✨

okay bestie, time for the requirements πŸ’… The RPC protocol must provide for the following:

  1. Unique specification of a procedure to be called.
  2. Provisions for matching response messages to request messages.
  3. Provisions for authenticating the caller to service and vice-versa.

Besides these requirements, features that detect the following are worth supporting because of protocol roll-over errors, implementation bugs, user error, and network administration πŸ™ˆ

  1. RPC protocol mismatches.
  2. Remote program protocol version mismatches.
  3. Protocol errors (such as misspecification of a procedure's parameters).
  4. Reasons why remote authentication failed.
  5. Any other reasons why the desired procedure was not called.

7.1 RPC Programs and Procedures πŸŽ€

the RPC call message has three unsigned integer fields (remote program number, remote program version number, and remote procedure number) and together they uniquely identify the procedure to be called 🧚 Program numbers are administered by a central authority (rpc@sun.com). Once implementors have a program number, they can implement their remote program, and the first implementation would most likely have the version number 1. Because most new protocols evolve, a version field of the call message identifies which version of the protocol the caller is using. Version numbers enable support of both old and new protocols through the same server process, which is honestly so iconic πŸ¦‹

The procedure number identifies the procedure to be called. These numbers are documented in the specific program's protocol specification. For example, a file service's protocol specification may state that its procedure number 5 is "read" and procedure number 12 is "write" πŸ“–

Just as remote program protocols may change over several versions, the actual RPC message protocol could also change. Therefore, the call message also has in it the RPC version number, which is always equal to two for the version of RPC described here πŸ’œ

The reply message to a request message has enough information to distinguish the following error conditions πŸ‘€

  1. The remote implementation of RPC does not support protocol version 2. The lowest and highest supported RPC version numbers are returned.
  2. The remote program is not available on the remote system.
  3. The remote program does not support the requested version number. The lowest and highest supported remote program version numbers are returned.
  4. The requested procedure number does not exist. (This is usually a client side protocol or programming error πŸ’€)
  5. The parameters to the remote procedure appear to be garbage from the server's point of view. (Again, this is usually caused by a disagreement about the protocol between client and service 😭)

7.2 Authentication πŸ”

Provisions for authentication of caller to service and vice-versa are provided as a part of the RPC protocol. The call message has two authentication fields, the credential and verifier. The reply message has one authentication field, the response verifier. The RPC protocol specification defines all three fields to be the following opaque type (in the eXternal Data Representation (XDR) language [9]):

enum auth_flavor {
   AUTH_NONE       = 0,
   AUTH_SYS        = 1,
   AUTH_SHORT      = 2
   /* and more to be defined */
};

struct opaque_auth {
   auth_flavor flavor;
   opaque body<400>;
};

In other words, any "opaque_auth" structure is an "auth_flavor" enumeration followed by up to 400 bytes which are opaque to (uninterpreted by) the RPC protocol implementation. Basically the RPC layer just carries the bytes and doesn't read them 🫢

The interpretation and semantics of the data contained within the authentication fields is specified by individual, independent authentication protocol specifications. (Section 9 defines the various authentication protocols ✨)

If authentication parameters were rejected, the reply message contains information stating why they were rejected 🚫

7.3 Program Number Assignment 🌈

Program numbers are given out in groups of hexadecimal 20000000 (decimal 536870912) according to the following chart:

          0 - 1fffffff   defined by rpc@sun.com
   20000000 - 3fffffff   defined by user
   40000000 - 5fffffff   transient
   60000000 - 7fffffff   reserved
   80000000 - 9fffffff   reserved
   a0000000 - bfffffff   reserved
   c0000000 - dfffffff   reserved
   e0000000 - ffffffff   reserved

The first group is a range of numbers administered by rpc@sun.com and should be identical for all sites. The second range is for applications peculiar to a particular site. This range is intended primarily for debugging new programs. When a site develops an application that might be of general interest, that application should be given an assigned number in the first range. Application developers may apply for blocks of RPC program numbers in the first range by sending electronic mail to "rpc@sun.com". The third group is for applications that generate program numbers dynamically. The final groups are reserved for future use, and should not be used 🚫✨

the final groups are reserved, so please don't touch them πŸ™…β€β™€οΈ

7.4 Other Uses of the RPC Protocol πŸ¦‹

The intended use of this protocol is for calling remote procedures. Normally, each call message is matched with a reply message. However, the protocol itself is a message-passing protocol with which other (non-procedure call) protocols can be implemented. so it's more flexible than it looks 🧚

7.4.1 Batching πŸ“

Batching is useful when a client wishes to send an arbitrarily large sequence of call messages to a server. Batching typically uses reliable byte stream protocols (like TCP) for its transport. In the case of batching, the client never waits for a reply from the server, and the server does not send replies to batch calls. A sequence of batch calls is usually terminated by a legitimate remote procedure call operation in order to flush the pipeline and get positive acknowledgement 🌸

7.4.2 Broadcast Remote Procedure Calls πŸ“‘

In broadcast protocols, the client sends a broadcast call to the network and waits for numerous replies. This requires the use of packet-based protocols (like UDP) as its transport protocol. Servers that support broadcast protocols usually respond only when the call is successfully processed and are silent in the face of errors, but this varies with the application πŸ’œ

The principles of broadcast RPC also apply to multicasting - an RPC request can be sent to a multicast address. the same vibes, just a different audience πŸ‘‘

8. THE RPC MESSAGE PROTOCOL ✨

okay bestie, this section is where the RPC message protocol gets defined πŸŽ€ It's written in the XDR data description language [9], so everything below is a little XDR puzzle 🧩

enum msg_type {
   CALL  = 0,
   REPLY = 1
};

a reply to a call message can take one of two forms πŸ’… it's either accepted or rejected, no in-between πŸ™…β€β™€οΈ

enum reply_stat {
   MSG_ACCEPTED = 0,
   MSG_DENIED   = 1
};

if a call message gets accepted, this is where you see what happened when the server tried to run the remote procedure πŸ‘€

enum accept_stat {
   SUCCESS       = 0, /* RPC executed successfully             */
   PROG_UNAVAIL  = 1, /* remote hasn't exported program        */
   PROG_MISMATCH = 2, /* remote can't support version #        */
   PROC_UNAVAIL  = 3, /* program can't support procedure       */
   GARBAGE_ARGS  = 4, /* procedure can't decode params         */
   SYSTEM_ERR    = 5  /* errors like memory allocation failure */
};

and here are the reasons a call message could get rejected πŸ™ˆ

enum reject_stat {
   RPC_MISMATCH = 0, /* RPC version number != 2          */
   AUTH_ERROR = 1    /* remote can't authenticate caller */
};

and if it's the auth part that failed, this enum tells you why πŸ”

enum auth_stat {
   AUTH_OK           = 0,  /* success                          */
   /*
    * failed at remote end
    */
   AUTH_BADCRED      = 1,  /* bad credential (seal broken)     */
   AUTH_REJECTEDCRED = 2,  /* client must begin new session    */
   AUTH_BADVERF      = 3,  /* bad verifier (seal broken)       */
   AUTH_REJECTEDVERF = 4,  /* verifier expired or replayed     */
   AUTH_TOOWEAK      = 5,  /* rejected for security reasons    */
   /*
    * failed locally
    */
   AUTH_INVALIDRESP  = 6,  /* bogus response verifier          */
   AUTH_FAILED       = 7   /* reason unknown                   */
};

The RPC message:

every message starts with a transaction identifier, xid, followed by a two-armed discriminated union πŸ¦‹ the discriminant is a msg_type that switches to whichever of the two message types it is. The xid of a REPLY always matches the xid of the CALL that started it, so they can be paired up πŸ’– NB: the xid field is only used by clients to match replies with calls, and by servers to spot retransmissions πŸ” The service side can't treat this id as any kind of sequence number, so please don't be that person 😭

struct rpc_msg {
   unsigned int xid;
   union switch (msg_type mtype) {
   case CALL:
      call_body cbody;
   case REPLY:
      reply_body rbody;
   } body;
};

Body of an RPC call:

in version 2 of the RPC protocol spec, rpcvers must be equal to 2 🌸 Then prog, vers, and proc tell you which remote program, which version of it, and which procedure inside it you want to call ✨ After those come two authentication parameters: cred (the authentication credential) and verf (the authentication verifier) πŸŽ€ After those come the parameters for the remote procedure, which are defined by that specific program's protocol πŸ‘‘

the verifier's whole job is to validate the credential 🫢 These two items are historically separate, but they're always used together as one logical entity, so think of them as besties who never leave each other's side πŸ’…

struct call_body {
   unsigned int rpcvers;       /* must be equal to two (2) */
   unsigned int prog;
   unsigned int vers;
   unsigned int proc;
   opaque_auth  cred;
   opaque_auth  verf;
   /* procedure specific parameters start here */
};

Body of a reply to an RPC call:

union reply_body switch (reply_stat stat) {
case MSG_ACCEPTED:
   accepted_reply areply;
case MSG_DENIED:
   rejected_reply rreply;
} reply;

Reply to an RPC call that was accepted by the server:

even when a call gets accepted, something can still go wrong 😭 The first field is an authentication verifier that the server makes to prove itself to the client 🫢 After that comes a union whose discriminant is an accept_stat enum. The SUCCESS arm is protocol specific 🌈 The PROG_UNAVAIL, PROC_UNAVAIL, GARBAGE_ARGS, and SYSTEM_ERR arms are void πŸ™ˆ The PROG_MISMATCH arm tells you the lowest and highest version numbers of the remote program that the server supports πŸ”₯

struct accepted_reply {
   opaque_auth verf;
   union switch (accept_stat stat) {
   case SUCCESS:
      opaque results[0];
      /*
       * procedure-specific results start here
       */
    case PROG_MISMATCH:
       struct {
          unsigned int low;
          unsigned int high;
       } mismatch_info;
    default:
       /*

        * Void.  Cases include PROG_UNAVAIL, PROC_UNAVAIL,
        * GARBAGE_ARGS, and SYSTEM_ERR.
        */
       void;
    } reply_data;
};

Reply to an RPC call that was rejected by the server:

a call can get rejected for two reasons πŸ’€ Either the server isn't running a version of the RPC protocol that matches (RPC_MISMATCH), or it doesn't accept who the caller says they are (AUTH_ERROR) πŸ™…β€β™€οΈ For a version mismatch, the server sends back the lowest and highest RPC version numbers it supports πŸ¦‹ For bad auth, you get a failure status instead πŸ”

union rejected_reply switch (reject_stat stat) {
case RPC_MISMATCH:
   struct {
      unsigned int low;
      unsigned int high;
   } mismatch_info;
case AUTH_ERROR:
   auth_stat stat;
};

9. AUTHENTICATION PROTOCOLS πŸ”

okay so, as we said before, authentication parameters are opaque, but they're open-ended as far as the rest of the RPC protocol is concerned 🧚 This section defines two standard "flavors" of authentication πŸ’œ Implementors are free to invent brand new authentication types, following the same rules for flavor number assignment as for program number assignment 🌸 The "flavor" of a credential or verifier is the value in the "flavor" field of the opaque_auth structure ✨ Flavor numbers, like RPC program numbers, are also handled centrally, and developers can get a new flavor number by applying through electronic mail to "rpc@sun.com" πŸ“§ Credentials and verifiers are represented as variable length opaque data (the "body" field in the opaque_auth structure) πŸŽ€

in this document, two flavors are described πŸ¦‹ Null authentication (covered in the next subsection) is mandatory, meaning it must be available in all implementations πŸ’… System authentication is described in Appendix A 🫢 It is strongly recommended that implementors include System authentication in their implementations πŸ”₯ Lots of applications use this style of authentication, and having this flavor in an implementation will boost interoperability πŸ‘‘

9.1 Null Authentication 🌈

often a call has to be made where the client doesn't care about its identity, or the server doesn't care who the client is πŸ™ˆ In that case, the flavor of the RPC message's credential, verifier, and reply verifier is AUTH_NONE 🌸 The opaque data associated with AUTH_NONE is undefined πŸ€·β€β™€οΈ It is recommended that the length of the opaque data be zero ✨


10. RECORD MARKING STANDARD 🧢

when RPC messages ride on top of a byte stream transport protocol (like TCP), you need a way to tell one message apart from the next πŸ’– That's how you detect protocol errors and maybe recover from them πŸ” This is called record marking (RM) πŸŽ€ One RPC message fits into exactly one RM record πŸ’…

a record is made of one or more record fragments 🧩 A record fragment is a four-byte header followed by 0 to (231) - 1 bytes of fragment data πŸ¦‹ The bytes encode an unsigned binary number, and just like XDR integers, the byte order goes from highest to lowest 🫢 That number packs in two values: a boolean that says whether the fragment is the last fragment of the record (bit value 1 means it is the last fragment), and a 31-bit unsigned binary value that's the length in bytes of the fragment's data 🌈 The boolean is the highest-order bit of the header, and the length is the 31 low-order bits πŸ”₯ (Note that this record specification is **NOT in XDR standard form!) πŸ™ˆ


11. THE RPC LANGUAGE πŸ“œ

just like we needed a formal language to describe XDR data types, we also need one to describe the procedures that work on those data types πŸ‘‘ The RPC Language is an extension of the XDR language, with added "program", "procedure", and "version" declarations πŸ’œ The example below shows the essence of the language 🌸

11.1 An Example Service Described in the RPC Language ✨

here's an example spec for a simple ping program πŸ“

program PING_PROG {
      /*
       * Latest and greatest version
       */
      version PING_VERS_PINGBACK {
         void
         PINGPROC_NULL(void) = 0;
         /*
          * Ping the client, return the round-trip time
          * (in microseconds). Returns -1 if the operation
          * timed out.
          */
         int
         PINGPROC_PINGBACK(void) = 1;
      } = 2;

      /*
       * Original version
       */
      version PING_VERS_ORIG {
         void
         PINGPROC_NULL(void) = 0;
      } = 1;
   } = 1;

const PING_VERS = 2;      /* latest version */

the first version described is PING_VERS_PINGBACK, which has two procedures: PINGPROC_NULL and PINGPROC_PINGBACK πŸ¦‹ PINGPROC_NULL takes no arguments and returns no results, but it's super handy for measuring round-trip times from the client to the server and back again 🧚 By convention, procedure 0 of any RPC protocol should have the same semantics, and should never require any kind of authentication πŸ” The second procedure lets the client have the server do a reverse ping back to the client, and it returns how long that operation took (in microseconds) ⏱️ The next version, PING_VERS_ORIG, is the original version of the protocol, and it does not contain the PINGPROC_PINGBACK procedure πŸ₯Ί It's useful for compatibility with old client programs, and as the program matures it may be dropped from the protocol entirely 🌈

11.2 The RPC Language Specification πŸ“

the RPC language is identical to the XDR language defined in RFC 1014, except for the added definition of a "program-def", described below πŸ’…

program-def:
   "program" identifier "{"
      version-def
      version-def *
   "}" "=" constant ";"

version-def:
   "version" identifier "{"

       procedure-def
       procedure-def *
   "}" "=" constant ";"

procedure-def:
   type-specifier identifier "(" type-specifier
     ("," type-specifier )* ")" "=" constant ";"

11.3 Syntax Notes 🧠

(1) The following keywords are added and can't be used as identifiers: "program" and "version" 🚫

(2) A version name can't occur more than once within the scope of a program definition. Nor can a version number occur more than once within the scope of a program definition πŸ™…β€β™€οΈ

(3) A procedure name can't occur more than once within the scope of a version definition. Nor can a procedure number occur more than once within the scope of a version definition πŸ™…β€β™€οΈ

(4) Program identifiers are in the same name space as constant and type identifiers 🫢

(5) Only unsigned constants can be assigned to programs, versions and procedures πŸ”’

APPENDIX A: SYSTEM AUTHENTICATION ✨

Okay so bestie, this appendix is all about how a client can say "hi, it's me!" using the AUTH_SYS flavor πŸ’–. The credential is basically a little bundle of who you are on a UNIX(tm) box, and it looks like this:

   struct authsys_parms {
      unsigned int stamp;
      string machinename<255>;
      unsigned int uid;
      unsigned int gid;
      unsigned int gids<16>;
   };

The stamp is an arbitrary ID the caller's machine can make up πŸŽ€. The machinename is the caller's machine name (think "krypton" 🧚). The uid is the caller's effective user ID, the gid is the effective group ID, and gids is a counted array of the groups the caller belongs to πŸ‘‘. The verifier that comes with this credential should have the AUTH_NONE flavor value (the one we defined up above) πŸ’…. Also, this credential is only unique within a particular domain of machine names, uids, and gids, so keep that in mind πŸ™ˆ.

The server's reply verifier can have a flavor of either AUTH_NONE or AUTH_SHORT πŸ¦‹. With AUTH_SHORT, the bytes in the reply verifier's string encode an opaque structure. The client can then pass that shorthand structure back to the server instead of the full AUTH_SYS credential, and it's giving efficiency πŸ”₯. The server can keep a cache that maps those shorthand structures back to the caller's original credentials, and the caller saves network bandwidth and server CPU cycles by using the shorthand 🌈.

Here's the plot twist 😭: the server is allowed to flush the shorthand structure at any time. If that happens, the RPC message gets rejected with an authentication error, and the reason will be AUTH_REJECTEDCRED. When that happens, the client may wish to go back to the original AUTH_SYS style of credential 🌸.

Not me saying this is a security guarantee πŸ’€. Using this flavor does not guarantee any security for the users or providers of a service, all by itself. The authentication only counts as legitimate when the applications using it and the network can be secured externally, and privileged transport addresses are used for the communicating end-points. An example is privileged TCP/UDP ports on Unix systems, and note that not all systems enforce privileged transport address mechanisms ⚠️.

REFERENCES πŸ“š

  • [1] Birrell, A. D. & Nelson, B. J., "Implementing Remote Procedure Calls", XEROX CSL-83-7, October 1983.
  • [2] Cheriton, D., "VMTP: Versatile Message Transaction Protocol", Preliminary Version 0.3, Stanford University, January 1987.
  • [3] Diffie & Hellman, "New Directions in Cryptography", IEEE Transactions on Information Theory IT-22, November 1976.
  • [4] Mills, D., "Network Time Protocol", RFC 1305, UDEL, March 1992.
  • [5] National Bureau of Standards, "Data Encryption Standard", Federal Information Processing Standards Publication 46, January 1977.
  • [6] Postel, J., "Transmission Control Protocol - DARPA Internet Program Protocol Specification", STD 7, RFC 793, USC/Information Sciences Institute, September 1981.
  • [7] Postel, J., "User Datagram Protocol", STD 6, RFC 768, USC/Information Sciences Institute, August 1980.
  • [8] Reynolds, J., and Postel, J., "Assigned Numbers", STD 2, RFC 1700, USC/Information Sciences Institute, October 1994.
  • [9] Srinivasan, R., "XDR: External Data Representation Standard", RFC 1832, Sun Microsystems, Inc., August 1995.
  • [10] Miller, S., Neuman, C., Schiller, J., and J. Saltzer, "Section E.2.1: Kerberos Authentication and Authorization System", M.I.T. Project Athena, Cambridge, Massachusetts, December 21, 1987.
  • [11] Steiner, J., Neuman, C., and J. Schiller, "Kerberos: An Authentication Service for Open Network Systems", pp. 191-202 in Usenix Conference Proceedings, Dallas, Texas, February 1988.
  • [12] Kohl, J. and C. Neuman, "The Kerberos Network Authentication Service (V5)", RFC 1510, Digital Equipment Corporation, USC/Information Sciences Institute, September 1993.

Security Considerations πŸ”

Security issues are not discussed in this memo. πŸ™ˆ

Author's Address πŸŽ€

Raj Srinivasan Sun Microsystems, Inc. ONC Technologies 2550 Garcia Avenue M/S MTV-5-40 Mountain View, CA 94043 USA

Phone: 415-336-2478 Fax: 415-336-6015 EMail: raj@eng.sun.com

πŸ“¦ where this page comes from