| Security

## SASL Authentication

> > Software Requirement: In versions of the LDAP provider prior to the Java 2 SDK, v1.4, to run these examples, you need to install the `ldapbp.jar` and `jaas.jar` archive files in addition to the software requirements listed in the Preparations lesson. These can be downloaded as part of the LDAP service provider from the JNDI Web site.

> The LDAP v3 protocol uses the SASL to support pluggable authentication. This means that the LDAP client and server can be configured to negotiate and use possibly nonstandard and/or customized mechanisms for authentication, depending on the level of protection desired by the client and the server. The LDAP v2 protocol does not support the SASL.

> Several SASL mechanisms are currently defined:

> - Anonymous (RFC 2245)
> - CRAM-MD5 (RFC 2195)
> - Digest-MD5 (RFC 2831)
> - External (RFC 2222)
> - Kerberos V4 (RFC 2222)
> - Kerberos V5 (RFC 2222)
> - SecurID (RFC 2808)
> - Secure Remote Password (draft-burdis-cat-srp-sasl-04.txt)
> - S/Key (RFC 2222)
> - X.509 (draft-ietf-ldapext-x509-sasl-03.txt)

> #### SASL Mechanisms Supported by LDAP Servers

> Of the mechanisms on the previous list, popular LDAP servers (such as those from Netscape, OpenLDAP, and Microsoft) support External, Digest-MD5, and Kerberos V5. RFC 2829 proposes the use of Digest-MD5 as the mandatory default mechanism for LDAP v3 servers.

> Here is a simple program for finding out the list of SASL mechanisms that an LDAP server supports.

> >     // Create initial context
> >     DirContext ctx = new InitialDirContext();

> >     // Read supportedSASLMechanisms from root DSE
> >     Attributes attrs = ctx.getAttributes(
> >         "ldap://localhost:389", new String[]{"supportedSASLMechanisms"});

> Here is the output produced by running this program against a server that supports the External SASL mechanism.

> >     {supportedsaslmechanisms=supportedSASLMechanisms: EXTERNAL}

> #### Specifying the Authentication Mechanism

> To use a particular SASL mechanism, you specify its Internet Assigned Numbers Authority (IANA)-registered mechanism name in the `Context.SECURITY_AUTHENTICATION` environment property. You can also specify a list of mechanisms for the LDAP provider to try. This is done by specifying an ordered list of space-separated mechanism names. The LDAP provider will use the first mechanism for which it finds an implementation.

> Here's an example that asks the LDAP provider to try to get the implementation for the DIGEST-MD5 mechanism and if that's not available, use the one for GSSAPI.

> >     env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI");

> You might get this list of authentication mechanisms from the user of your application. Or you might get it by asking the LDAP server, via a call similar to that shown previously. The LDAP provider itself does not consult the server for this information. It simply attempts to locate and use the implementation of the specified mechanisms.

> The LDAP provider in Java 2 SDK, v1.4 has built-in support for the External, Digest-MD5, and GSSAPI (Kerberos v5) SASL mechanisms. Older versions of the LDAP provider have built-in support for the CRAM-MD5 and External SASL mechanisms. You can add support for additional mechanisms. See the Using Arbitrary SASL Mechanisms section.

> #### Using Policies to Filter the Selection of Authentication Mechanisms

> The previous example that showed how to select an authentication mechanism can be refined by specifying policies that restrict the selection of authentication mechanisms. This can be used by an application or system to specify general characteristics of the acceptable authentication mechanisms without explicitly naming them, and allows the list of explicit mechanism names to be supplied orthogonally.

> Here is a list of environment properties used to filter the selection of authentication mechanisms. Each property's value is either `"true"` or `"false"`. If a property is absent, then the resulting mechanism need not have that characteristic (that is, the value is effectively `"false"`).

> 1. `javax.security.sasl.policy.forward`
>      Specifies that the selected SASL mechanism must support forward secrecy between sessions. This means that breaking into one session will not automatically provide information for breaking into future sessions.
> 2. `javax.security.sasl.policy.credentials`
>      Specifies that the selected SASL mechanism must require client credentials.
> 3. `javax.security.sasl.policy.noplaintext`
>      Specifies that the selected SASL mechanism must not be susceptible to simple plain passive attacks.
> 4. `javax.security.sasl.policy.noactive`
>      Specifies that the selected SASL mechanism must not be susceptible to active (non-dictionary) attacks. The mechanism might require mutual authentication as a way to prevent active attacks.
> 5. `javax.security.sasl.policy.nodictionary`
>      Specifies that the selected SASL mechanism must not be susceptible to passive dictionary attacks.
> 6. `javax.security.sasl.policy.noanonymous`
>      Specifies that the selected SASL mechanism must not accept anonymous logins.
> Here is a table that shows the characteristics of the various SASL mechanisms as described by the policy properties. The numbers in the table headings identify the policy properties. A check mark indicates that the mechanism exhibits that characteristic.

> Mechanism/Policy | 1 | 2 | 3 | 4 | 5 | 6
> --- | --- | --- | --- | --- | --- | ---
> EXTERNAL |  |  |  |  |  |
> GSSAPI (Kerberos v5) |  |  |  |  |  |
> DIGEST-MD5 |  |  |  |  |  |
> CRAM-MD5 |  |  |  |  |  |
> PLAIN |  |  |  |  |  |
> ANONYMOUS |  |  |  |  |  |

> Here is a modification of the previous example.

> >     env.put("javax.security.sasl.policy.noactive", "true");
> >     env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5 GSSAPI");

> By adding the policy environment property, the DIGEST-MD5 mechanism will not be selected even if its implementation is available because the `"javax.security.sasl.policy.noactive"` property prohibits it from being selected.

> #### Specifying the "Bind" Distinguished Name

> SASL authentication consists of the client and the server exchanging SASL messages embedded inside LDAP "bind" requests and responses. The "bind" request contains a name field, which is the DN of the directory object that the client wishes to authenticate as. For SASL authentication, the authentication identity, which might not even be a DN, is typically embedded within the credentials that are exchanged with the server. The name field is therefore left unset for SASL authentication.

> #### Specifying Input for the Authentication Mechanism

> Some mechanisms, such as External, require no additional input--the mechanism name alone is sufficient for the authentication to proceed. The External example shows how to use the External SASL mechanism.

> Most other mechanisms require some additional input. Depending on the mechanism, the type of input might vary. Following are some common inputs required by mechanisms.

> - Authentication id. The identity of the entity performing the authentication.
> - Authorization id. The identity of the entity for which access control checks should be made if the authentication succeeds.
> - Authentication credentials. For example, a password or a key.
> The authentication and authorization ids might differ if the program (such as a proxy server) is authenticating on behalf of another entity. The authentication id is specified by using the `Context.SECURITY_PRINCIPAL` environment property. It is of type `java.lang.String`.

> The password/key of the authentication id is specified by using the `Context.SECURITY_CREDENTIALS` environment property. It is of type `java.lang.String`, `char` array (`char[]`), or `byte` array (`byte[]`). If the password is a `byte` array, then it is transformed into a `char` array by using an UTF-8 encoding.

> If the `"java.naming.security.sasl.authorizationId"` property has been set, then its value is used as the authorization ID. Its value must be of type `java.lang.String`. By default, the empty string is used as the authorization ID, which directs the server to derive an authorization ID from the client's authentication credentials.

> The Digest-MD5 example shows how to use the `Context.SECURITY_PRINCIPAL` and `Context.SECURITY_CREDENTIALS` properties for Digest-MD5 authentication.

> If a mechanism requires input other than those already described, then you need to define a callback object for the mechanism to use. See the Callback section for an example of how to do this.

> #### Specifying the Quality of Protection

> In additional to authentication, some SASL mechanisms support integrity and privacy protection of the communication channel after successful authentication. With integrity protection, subsequent LDAP requests and responses are protected against tampering. With privacy protection, subsequent LDAP requests and responses are encrypted and therefore protected against unintended monitoring. Privacy protection automatically entails integrity protection. These different types of protection are referred to as the quality of protection (qop). It is negotiated between the client and server during the authentication phase of the SASL exchange. If the client and server cannot negotiate a common qop, then the SASL authentication fails.

> You use the `"javax.security.sasl.qop"` environment property to specify the client's preferred qop. The value of this property is a comma-separated list of qop values, the order of which specifies the preference order. There are three possible qop values, as listed in the following table.

> Token | Description
> --- | ---
> `auth` | Authentication only
> `auth-int` | Authentication with integrity protection
> `auth-conf` | Authentication with integrity and privacy protection

> If you do not specify this property, it defaults to `"auth"`. This property is ignored by SASL mechanisms that support authentication only. See the Digest-MD5 integrity example for an example of how to set the qop.

> #### Specifying the Encryption Strength for Privacy Protection

> Some SASL mechanisms support the use of different privacy protection strengths--that is, different ciphers and key lengths used for encryption. The protection strength determines how easily the encryption code can be cracked. The Java SASL API broadly categorizes privacy protection strengths into low, medium, and high. The mapping of these categories into specific ciphers and key lengths are SASL mechanism-specific. The ciphers, key lengths or other means of strength specification are negotiated between the client and server during the authentication phase of the SASL exchange. If the client and server cannot negotiate a common strength, then the SASL authentication fails.

> You use the `"javax.security.sasl.strength"` environment property to specify the client's preferred privacy protection strength. The value of this property is a comma-separated list of strength values, the order of which specifies the preference order. The three possible strength values are `"low"`, `"medium"`, and `"high"`. If you do not specify this property, then it defaults to `"high,medium,low"`. This property is ignored by SASL mechanisms that do not support privacy protection. See the Digest-MD5 strength example for an example of how to set the strength.

> #### Specifying the Maximum Receive Buffer Size

> If a client is using a SASL mechanism that supports integrity or privacy protection, then it must negotiate with the server their respective receive buffer sizes.

> You use the `"javax.security.sasl.maxbuffer"` environment property to specify the client's maximum receive buffer size. The value of this property is the string representation of an integer that specifies the maximum size of the receive buffer in bytes. If you do not specify this property, it defaults to a SASL mechanism-specific size. This property is ignored by SASL mechanisms that do not support integrity or privacy protection. See the Digest-MD5 buffer example for an example of how to set the maximum receive buffer size.

> #### Specifying Mutual Authentication

> When you think of authentication, you typically think of the process by which you verify your identity to the LDAP server. For some applications, it is equally important that the LDAP server's identity be verified. The process by which both parties participating in the exchange authenticate each other is referred to as mutual authentication.

> You use the `"javax.security.sasl.server.authentication"` environment property to indicate that you want mutual authentication. The value of this property is either `"true"` or `"false"`; `"true"` means mutual authentication is required. If you do not specify this property, it defaults to `"false"`. This property is ignored by SASL mechanisms that do not support mutual authentication. See the GSSAPI mutual authentication example for an example of how to specify mutual authentication.

| Security