AUTH_DES Authentication
Use AUTH_DES authentication for programs that require more security than AUTH_SYS provides. AUTH_SYS authentication is easy to defeat. For example, instead of using authsys_create_default(), a program can call authsys_create() and change the RPC authentication handle to give itself any desired user ID and host name.
AUTH_DES authentication requires keyserv() daemons to be running on both the server and client hosts. The NIS or NIS+ naming service must also be running. Users on these hosts need public/secret key pairs assigned by the network administrator in the publickey() database. The users must also have decrypted their secret keys with the keylogin() command. This decryption is normally done by login() unless the login password and secure-RPC password differ.
To use AUTH_DES authentication, a client must set its authentication handle appropriately, as shown in the following example.
cl->cl_auth = authdes_seccreate(servername, 60, server, (char *)NULL); |
The first argument is the network name or "net name" of the owner of the server process. Server processes are usually root processes, and you can get their net names with the following call;
char servername[MAXNETNAMELEN]; host2netname(servername, server, (char *)NULL); |
servername points to the receiving string and server is the name of the host the server process is running on. If the server process was run by a non-root user, use the call user2netname() as follows:
char servername[MAXNETNAMELEN]; user2netname(servername, serveruid(), (char *)NULL); |
serveruid() is the user ID of the server process. The last argument of both functions is the name of the domain that contains the server. NULL means "use the local domain name."
The second argument of authdes_seccreate() is the lifetime (known also as the "window") of the client's credential. In this example, a credential expires 60 seconds after the client makes an RPC call. If a program tries to reuse the credential, the server RPC subsystem recognizes that the credential has expired and does not service the request carrying the expired credential. If any program tries to reuse a credential within its lifetime, the process is rejected, because the server RPC subsystem saves credentials it has seen in the near past and does not serve duplicates.
The third argument of authdes_seccreate() is the name of the timehost used to synchronize clocks. AUTH_DES authentication requires that server and client agree on the time. Example 5-8 specifies synchronization with the server. A (char *)NULL says not to synchronize. Use this syntax only when you are sure that the client and server are already synchronized.
The fourth argument of authdes_seccreate() points to a DES encryption key to encrypt timestamps and data. If this argument is (char *)NULL, as it is in Example 5-8, a random key is chosen. The ah_key field of the authentication handle contains the key.
The server side is simpler than the client. The following example shows the server in Example 5-8 changed to use AUTH_DES.
Example 5-9 AUTH_DES Server
The routine netname2user() converts a network name, or "net name" of a user, to a local system ID. It also supplies group IDs, which are not used in this example.
AUTH_KERB Authentication
SunOS 5.0 and compatible versions include support for most client-side features of Kerberos 5 except klogin. AUTH_KERB is conceptually similar to AUTH_DES. The essential difference is that DES passes a network name and a DES-encrypted session key, while Kerberos passes the encrypted service ticket. This section describes other factors that affect implementation and interoperability.
Kerberos uses the concept of a time window in which its credentials are valid. It does not place restrictions on the clocks of the client or server. Specifically, the window is passed as an argument to authkerb_seccreate(). The window does not change. If a timehost is specified as an argument, the client side gets the time from the timehost and alters its timestamp by the difference in time. Various methods of time synchronization are available. See the kerberos_rpc man page for more information.
Kerberos users are identified by a primary name, instance, and realm. The RPC authentication code ignores the realm and instance, while the Kerberos library code does not. The assumption is that user names are the same between client and server. This enables a server to translate a primary name into user identification information. Two forms of well-known names are used (omitting the realm):
root.host represents a privileged user on client host.
user.ignored represents the user whose user name is user. The instance is ignored.
Kerberos uses cipher block chaining (CBC) mode when sending a full name credential, one that includes the ticket and window, and electronic code book (ECB) mode otherwise. CBC and ECB are two methods of DES encryption. The session key is used as the initial input vector for CBC mode. The following notation means that XDR is used on object as a type.
xdr_type(object) |
The length in the next code section is the size, in bytes of the credential or verifier, rounded up to 4-byte units. The full name credential and verifier are obtained as follows:
xdr_long(timestamp.seconds) xdr_long(timestamp.useconds) xdr_long(window) xdr_long(window - 1) |
After encryption with CBC with input vector equal to the session key, the output is two DES cipher blocks:
CB0 CB1.low CB1.high |
xdr_long(AUTH_KERB) xdr_long(length) xdr_enum(AKN_FULLNAME) xdr_bytes(ticket) xdr_opaque(CB1.high) |
xdr_long(AUTH_KERB) xdr_long(length) xdr_opaque(CB0) xdr_opaque(CB1.low) |
xdr_long(timestamp.seconds) xdr_long(timestamp.useconds) |
The nickname is encrypted with ECB to obtain ECB0, and the credential is:
xdr_long(AUTH_KERB) xdr_long(length) xdr_enum(AKN_NICKNAME) xdr_opaque(akc_nickname) |
xdr_long(AUTH_KERB) xdr_long(length) xdr_opaque(ECB0) xdr_opaque(0) |