3 Network Working Group Rosanna Lee
4 INTERNET-DRAFT Sun Microsystems
5 Intended Category: Standards Track Rob Weltman
10 The Java SASL Application Program Interface
11 draft-weltman-java-sasl-05.txt
16 This document is an Internet-Draft and is in full conformance with
17 all provisions of Section 10 of RFC2026.
19 Internet-Drafts are working documents of the Internet Task Force
20 (IETF), its areas, and its working groups. Note that other groups
21 may also distribute working documents as Internet-Drafts.
23 Internet-Drafts are draft documents valid for a maximum of six months
24 and may be updated, replaced, or obsoleted by other documents at any
25 time. It is inappropriate to use Internet Drafts as reference
26 material or to cite them other than as "work in progress."
28 The list of current Internet-Drafts can be accessed at
29 http://www.ietf.org/ietf/1id-abstracts.txt
31 The list of Internet-Draft Shadow Directories can be accessed at
32 http://www.ietf.org/shadow.html.
37 This document defines a client-side and a server-side Java language
38 interface for using the Simple Authentication and Security Layer
39 (SASL) mechanisms for adding authentication support to connection-
40 based protocols. The interface promotes sharing of SASL Mechanism
41 Drivers and security layers between applications using different
42 protocols. It complements but does not replace [SASL], which defines
43 and exemplifies use of the SASL protocol in a language-independent
58 Expires November 2001 [Page 1]
60 JAVA SASL API May, 2001
64 1. Introduction....................................................4
65 2. Overview of the SASL classes....................................6
66 2.1 Interfaces.....................................................6
67 2.2 Classes........................................................7
68 3. Overview of SASL API Use........................................7
69 4. The Java SASL classes...........................................9
70 4.1 public class Sasl..............................................9
71 4.1.1 createSaslClient...............................................9
72 4.1.2 setSaslClientFactory..........................................11
73 4.1.3 createSaslServer..............................................11
74 4.1.4 setSaslServerFactory..........................................12
75 4.1.5 getSaslClientFactories........................................13
76 4.1.6 getSaslServerFactories........................................13
77 4.1.7 Standard Properties...........................................14
78 4.2 public interface SaslClient...................................16
79 4.2.1 evaluateChallenge.............................................16
80 4.2.2 hasInitialResponse............................................17
81 4.2.3 isComplete....................................................17
82 4.2.4 unwrap........................................................17
83 4.2.5 wrap..........................................................18
84 4.2.6 getMechanismName..............................................18
85 4.2.7 getNegotiatedProperty.........................................18
86 4.2.8 dispose.......................................................19
87 4.3 public interface SaslClientFactory............................19
88 4.3.1 createSaslClient..............................................19
89 4.3.2 getMechanismNames.............................................20
90 4.4 public interface SaslServer...................................21
91 4.4.1 evaluateResponse..............................................21
92 4.4.2 isComplete....................................................21
93 4.4.3 unwrap........................................................22
94 4.4.4 wrap..........................................................22
95 4.4.5 getMechanismName..............................................23
96 4.4.6 getAuthorizationID............................................23
97 4.4.7 getNegotiatedProperty.........................................23
98 4.4.8 dispose.......................................................24
99 4.5 public interface SaslServerFactory............................24
100 4.5.1 createSaslServer..............................................24
101 4.5.2 getMechanismNames.............................................25
102 4.6 public class AuthorizeCallback................................25
103 4.6.1 Constructors..................................................26
104 4.6.2 getAuthenticationID...........................................26
105 4.6.3 getAuthorizationID............................................26
106 4.6.4 isAuthorized..................................................26
107 4.6.5 setAuthorized.................................................26
108 4.6.6 getAuthorizedID...............................................26
109 4.6.7 setAuthorizedID...............................................27
110 4.7 public class RealmCallback....................................27
111 4.7.1 Constructors..................................................27
112 4.8 public class RealmChoiceCallback..............................27
113 4.8.1 Constructors..................................................28
114 4.9 public class SaslException extends IOException................28
115 4.9.1 Constructors..................................................28
117 Expires November 2001 [Page 2
119 JAVA SASL API May, 2001
122 4.9.2 getCause......................................................29
123 4.9.3 printStackTrace...............................................29
124 5. Security Considerations........................................30
125 6. Copyright......................................................30
126 7. Bibliography...................................................30
127 8. Authors' Addresses.............................................31
128 9. Acknowledgements...............................................31
129 10. Changes from draft-weltman-java-sasl-04.txt....................31
130 11. Changes from draft-weltman-java-sasl-03.txt....................32
131 12. Changes from draft-weltman-java-sasl-02.txt....................32
132 13. Appendix A - Sample Java LDAP program using SASL...............34
176 Expires November 2001 [Page 3
178 JAVA SASL API May, 2001
183 See [SASL], section 3, for an introduction to and overview of the
184 SASL framework for authentication and negotiation of a security
185 layer. The following presents an outline of the concepts.
187 --------------- ------------------- -----------------
188 | Application |-----| Protocol Driver |------| MD5 |
189 --------------- ------------------- | -----------------
205 An application chooses a Protocol Driver specific to the protocol it
206 wants to use, and specifies one or more acceptable mechanisms. The
207 Protocol Driver controls the socket, and knows the format/packaging
208 of bytes sent down and received from the socket, but does not know
209 how to authenticate or to encrypt/ decrypt the bytes. It uses one of
210 the Mechanism Drivers to help it perform authentication. The Protocol
211 Driver examines each byte string received from the server during the
212 authentication in a protocol-specific way to determine if the
213 authentication process has been completed. If not, the byte string is
214 passed to the Mechanism Driver to be interpreted as a server
215 challenge; the Mechanism Driver returns an appropriate response,
216 which the Protocol Driver can encode in a protocol-specific way and
217 return to the server.
219 If the Protocol Driver concludes from the byte string received from
220 the server that authentication is complete, it may query the
221 Mechanism Driver if it considers the authentication process complete,
222 in order to thwart early completion messages inserted by an intruder.
224 On completed authentication, the Protocol Driver may use the
225 Mechanism Driver to encode and decode any data exchanged through the
226 socket if a security layer was negotiated.
228 A complication here is that some authentication methods may require
229 additional user/application input. That means that a Mechanism
230 Driver may need to call up to an application during the
231 authentication process. To satisfy this requirement, the application
232 can supply a javax.security.auth.callback.CallbackHandler instance
235 Expires November 2001 [Page 4
237 JAVA SASL API May, 2001
240 [JAAS] that can be used by the Mechanism Driver to prompt the user
241 for additional input.
243 Protocol Drivers are protocol-dependent and may be built in to a
244 protocol package or an application. There is a generalized framework
245 for registering and finding Mechanism Drivers. The framework uses a
246 factory to produce an appropriate Mechanism Driver. The factory may
247 be preconfigured, explicitly specified by the caller, specified as a
248 list of packages by the caller, or be identified based on a list of
249 packages in the System properties.
251 The Mechanism Drivers are protocol-independent, and don't deal
252 directly with network connections, just byte arrays, so they can be
253 implemented in a generalizable way for all protocols.
255 The negotiated security layer is implemented by encoding and decoding
256 routines in the Mechanism Driver, using parameters and resolutions
257 reached during authentication.
259 Different Mechanism Drivers may require different parameters to carry
260 out the authentication process. This is handled by passing a
261 java.util.Hashtable object as an argument to instantiation methods.
263 In the following discussion, 'client' refers to the client-side
264 Protocol Driver that is using the SASL mechanism while 'server'
265 refers to the server-side Protocol Driver that is using the SASL
294 Expires November 2001 [Page 5
296 JAVA SASL API May, 2001
299 In the Java SASL environment, the SaslClient interface represents the
300 client's view of the Mechanism Driver, while the SaslServer interface
301 represents the server's view.
303 --------------- ---------------
304 | Application |--+ +--| Server |
305 --------------- | | ---------------
307 ------------------- -------------------
308 | Protocol Driver |--+ <- - - - -> +--| Protocol Driver |
309 ------------------- | | -------------------
311 ------------------- -------------------
312 | SaslClient | | SaslServer |
313 ------------------- -------------------
315 ----------------- | | -----------------
316 | MD5 |----| |---| MD5 |
317 ----------------- | | -----------------
319 ----------------- | | -----------------
320 | Kerberos v5 |----| |---| Kerberos v5 |
321 ----------------- | | -----------------
323 ----------------- | | -----------------
324 | PKCS-11 |----| |---| PKCS-11 |
325 ----------------- | | -----------------
327 - - - - - - - - - | | - - - - - - - - -
328 | xxxYYYxxx |----+ +---| xxxYYYxxx |
329 - - - - - - - - - - - - - - - - - -
331 A client using the Java SASL API may communicate with any server
332 implementing the SASL protocol, and a server may use the API to
333 process authentication requests from any client using the SASL
334 protocol. It is not required that both sides use the same language
338 2. Overview of the SASL classes
343 SaslClient Performs SASL authentication as a
346 SaslClientFactory An interface for creating instances of
347 SaslClient. It is not normally accessed
348 directly by a client, which will use the
349 Sasl static methods instead. However, a
350 particular environment may provide and
352 Expires November 2001 [Page 6
354 JAVA SASL API May, 2001
357 install a new or different
360 SaslServer Performs SASL authentication as a
363 SaslServerFactory An interface for creating instances of
364 SaslServer. It is not normally accessed
365 directly by a server, which will use the
366 Sasl static methods instead. However, a
367 particular environment may provide and
368 install a new or different
375 Sasl A static class for creating SASL clients
376 and servers. It transparently locates
377 and uses any available
378 SaslClientFactory/SaslServerFactory
381 AuthorizeCallback This callback is used by SaslServer to
382 determine whether one entity (identified
383 by an authenticated authentication id)
384 can act on behalf of another entity
385 (identified by an authorization id).
387 RealmCallback This callback is used by SaslClient and
388 SaslServer to retrieve realm information.
390 RealmChoiceCallback This callback is used by SaslClient and
391 SaslServer to obtain one or more realms
392 given a list of realm choices.
394 SaslException Exception thrown on errors and failures
395 in the authentication process.
398 3. Overview of SASL API Use
400 An application generally uses the SASL API as follows:
402 - Create an object implementing the client authentication
403 callback interfaces, which can provide credentials when
404 required by the SaslClient.
406 - Pass a list of acceptable or known Mechanisms and a callback
407 handler to Sasl.createSaslClient. The method returns an object
408 implementing SaslClient on success.
410 Expires November 2001 [Page 7
412 JAVA SASL API May, 2001
417 - Have the SaslClient object begin the authentication process by
418 providing an initial server response, if the protocol supports
421 - Responses/challenges are exchanged with the server. If a
422 response indicates authentication has completed, SaslClient is
423 queried for validation, and methods for encoding and decoding
424 data according to the negotiated security layer may be invoked
425 on it. If not, the SaslClient is queried for an appropriate
426 next response to the server. This continues until
427 authentication has completed.
429 - If a security layer has been negotiated, for the rest of the
430 session, messages to the server are first encoded by using
431 SaslClient before being written, and messages from the server
432 are first decoded by using SaslClient before being processed in
436 A server generally uses the SASL API as follows:
438 - It receives a request from the client requesting authentication
439 for a particular SASL mechanism, accompanied by an optional
442 - It processes the initial response and generates a challenge
443 specific to the SASL mechanism to be sent back to the client if
444 the response is processed successfully. If the response is
445 not processed successfully, it sends an error to the client and
446 terminates the authentication session.
448 - Responses/challenges are exchanged with the client. If the
449 server cannot successfully process a response, the server sends
450 an error to the client and terminates the authentication. If
451 the server has completed the authentication and has no more
452 challenges to send, it sends a success indication to the
455 - If the authentication has completed successfully, the server
456 extracts the authorization ID of the client from the SaslServer
457 instance (if appropriate) to be used for subsequent access
460 - For the rest of the session, messages to and from the client are
461 encoded and decoded by using SaslServer to implement the
462 negotiated security layer (if any).
464 The following sections describe the SASL classes in more detail.
469 Expires November 2001 [Page 8
471 JAVA SASL API May, 2001
474 4. The Java SASL classes
477 4.1 public class Sasl
479 A class capable of providing a SaslClient or SaslServer.
482 4.1.1 createSaslClient
484 public static SaslClient
485 createSaslClient(String[] mechanisms,
486 String authorizationID,
490 javax.security.auth.callback.CallbackHandler cbh)
493 Creates a SaslClient using the parameters supplied. It returns null
494 if no SaslClient can be created using the parameters supplied. Throws
495 SaslException if it cannot create a SaslClient because of an error.
497 The algorithm for selection is as follows:
499 1. If a factory has been installed via setSaslClientFactory(),
500 invoke createSaslClient() on it. If the method invocation returns
501 a non-null SaslClient instance, return the SaslClient instance;
503 2. Create a list of fully qualified class names using the package
504 names listed in the CLIENT_PKGS
505 ("javax.security.sasl.client.pkgs") property in props and the
506 class name ClientFactory. Each class name in this list identifies
507 a SaslClientFactory implementation. Starting with the first class
508 on the list, create an instance of SaslClientFactory using the
509 class' public no-argument constructor and invoke
510 createSaslClient() on it. If the method invocation returns a non-
511 null SaslClient instance, return it; otherwise repeat using the
512 next class on the list until a non-null SaslClient is produced or
513 the list is exhausted.
514 3. Repeat the previous step using the CLIENT_PKGS
515 ("javax.security.sasl.client.pkgs") System property instead of
516 the property in props.
517 4. As per the Java 2 Standard Edition version 1.3 service provider
518 guidelines, check for the existence of one of more files named
519 META-INF/services/javax.security.sasl.SaslClientFactory in the
520 classpath and installed JAR files. Each file lists the fully
521 qualified class names of the factories (i.e. implementations of
522 SaslClientFactory) found in the JAR files or classpath. Construct
523 a merged list of class names using these files and repeat Step 2
524 using this list. If there are more than one of these files, the
527 Expires November 2001 [Page 9
529 JAVA SASL API May, 2001
532 order in which they are processed is undefined. If no non-null
533 SaslClient instance is produced, return null.
537 mechanisms The non-null list of mechanism names to try. Each
538 is the IANA-registered name of a SASL mechanism
539 (e.g. "GSSAPI", "CRAM-MD5").
541 authorizationID The possibly null protocol-dependent
542 identification to be used for authorization. If
543 null or empty, the server derives an
544 authorization ID from the client's authentication
545 credentials. When the SASL authentication
546 completes successfully, the specified entity is
549 protocol The non-null string name of the protocol for
550 which the authentication is being performed, e.g
553 serverName The non-null fully qualified host name of the
554 server to authenticate to.
556 props The possibly null set of properties used to
557 select the SASL mechanism and to configure the
558 authentication exchange of the selected
559 mechanism. For example, if props includes the
560 Sasl.POLICY_NOPLAINTEXT property with the value
561 "true", then the selected SASL mechanism must not
562 be susceptible to simple plain passive attacks.
564 In addition to the standard properties of this
565 class, other, possibly mechanism-specific,
566 properties can be included.
567 Properties not relevant to the selected mechanism
569 See Standard Properties for a list of standard
572 cbh The possibly null callback handler to be used by
573 the SASL mechanisms to get further information
574 from the application/library to complete the
575 authentication. For example, a SASL mechanism
576 might require the authentication ID, password and
577 realm from the caller. The authentication ID is
578 requested by using a NameCallback. The password
579 is requested by using a PasswordCallback. The
580 realm is requested by using a RealmChoiceCallback
581 if there is a list of realms to choose from, and
582 by using a RealmCallback if the realm must be
586 Expires November 2001 [Page 10
588 JAVA SASL API May, 2001
591 4.1.2 setSaslClientFactory
594 setSaslClientFactory(SaslClientFactory fac)
596 Sets the default SaslClientFactory to use. This method sets fac to be
597 the default factory. It can only be called with a non-null value once
598 per VM. If a factory has been set already, this method throws
599 IllegalStateException. The method throws java.lang.SecurityException
600 if the caller does not have the necessary permission to set the
605 fac The possibly null factory to set. If null, it
609 4.1.3 createSaslServer
611 public static SaslServer
612 createSaslServer(String mechanism,
616 javax.security.auth.callback.CallbackHandler cbh)
619 This method creates a SaslServer for the specified mechanism. It
620 returns null if no SaslServer can be created for the specified
623 The algorithm for selection is as follows:
625 1. If a factory has been installed via setSaslServerFactory(),
626 invoke createSaslServer() on it. If the method invocation returns
627 a non-null SaslServer instance, return the SaslServer instance;
629 2. Create a list of fully qualified class names using the package
630 names listed in the SERVER_PKGS
631 ("javax.security.sasl.server.pkgs") property in props and the
632 class name ServerFactory. Each class name in this list identifies
633 a SaslServerFactory implementation. Starting with the first class
634 on the list, create an instance of SaslServerFactory using the
635 class' public no-argument constructor and invoke
636 createSaslServer() on it. If the method invocation returns a non-
637 null SaslServer instance, return it; otherwise repeat using the
638 next class on the list until a non-null SaslServer is produced or
639 the list is exhausted.
640 3. Repeat the previous step using the SERVER_PKGS
641 ("javax.security.sasl.server.pkgs") System property instead of
642 the property in props.
644 Expires November 2001 [Page 11
646 JAVA SASL API May, 2001
649 4. As per the Java 2 Standard Edition version 1.3 service provider
650 guidelines, check for the existence of one of more files named
651 META-INF/services/javax.security.sasl.SaslServerFactory in the
652 classpath and installed JAR files. Each file lists the fully
653 qualified class names of the factories (i.e. implementations of
654 SaslServerFactory) found in the JAR files or classpath. Construct
655 a merged list of class names using these files and repeat Step 2
656 using this list. If there are more than one of these files, the
657 order in which they are processed is undefined. If no non-null
658 SaslServer instance is produced, return null.
662 mechanism A non-null IANA-registered name of a SASL
663 mechanism (e.g. "GSSAPI", "CRAM-MD5").
665 protocol The non-null string name of the protocol for
666 which the authentication is being performed, e.g
669 serverName The non-null fully qualified host name of the
672 props The possibly null set of properties used to
673 select the SASL mechanism and to configure the
674 authentication exchange of the selected
675 mechanism. For example, if props includes the
676 Sasl.POLICY_NOPLAINTEXT property with the value
677 "true", then the selected SASL mechanism must not
678 be susceptible to simple plain passive attacks.
680 In addition to the standard properties defined in
681 this class, other, possibly mechanism-specific,
682 properties can be included.
683 Properties not relevant to the selected mechanism
685 See section 4.1.7 Standard Properties for a list
686 of standard properties.
688 cbh The possibly null callback handler to be used by
689 the SASL mechanism to get further information
690 from the application/library to complete the
691 authentication. For example, a SASL mechanism
692 might require the authentication ID and password
693 from the caller. The authentication ID is
694 requested with a NameCallback, and the password
695 with a PasswordCallback.
698 4.1.4 setSaslServerFactory
702 Expires November 2001 [Page 12
704 JAVA SASL API May, 2001
707 setSaslServerFactory(SaslServerFactory fac)
709 Sets the default SaslServerFactory to use. This method sets fac to
710 be the default factory. It can only be called with a non-null value
711 once per VM. If a factory has been set already, this method throws
712 IllegalStateException. The method throws java.lang.SecurityException
713 if the caller does not have the necessary permission to set the
718 fac The possibly null factory to set. If null, it
722 4.1.5 getSaslClientFactories
724 public java.util.Enumeration
725 getSaslClientFactories(java.util.Hashtable props)
727 Gets an enumeration of known factories for producing SaslClient. This
728 method uses the same sources for locating factories as
733 props A possibly null set of properties that may
734 contain policy properties and the property
735 CLIENT_PKGS ("javax.security.sasl.client.pkgs")
736 for specifying a list of SaslClientFactory
737 implementation package names.
740 4.1.6 getSaslServerFactories
742 public java.util.Enumeration
743 getSaslServerFactories(java.util.Hashtable props)
745 Gets an enumeration of known factories for producing SaslServer. This
746 method uses the same sources for locating factories as
751 props A possibly null set of properties that may
752 contain policy properties and the property
753 SERVER_PKGS ("javax.security.sasl.server.pkgs")
754 for specifying a list of SaslServerFactory
755 implementation package names.
760 Expires November 2001 [Page 13
762 JAVA SASL API May, 2001
765 4.1.7 Standard Properties
767 There are a number of properties that may be specified in a Hashtable
768 parameter when creating a SASL client or server. The standard
769 properties and descriptions of their values are as follows (with the
770 Sasl constant name followed by the literal value in parentheses):
772 QOP ("javax.security.sasl.qop")
774 A comma-separated, ordered list of quality-of-protection
775 values that the client or server is willing to support. A
778 "auth" authentication only
780 "auth-int" authentication plus integrity protection
782 "auth-conf" authentication plus integrity and
783 confidentiality protection
786 The order of the list specifies the preference order of
787 the client or server. If this property is absent, the
788 default qop is "auth".
790 STRENGTH ("javax.security.sasl.strength")
792 A comma-separated, ordered list of cipher strength values
793 that the client or server is willing to support. A
794 strength value is one of
802 The order of the list specifies the preference order of
803 the client or server. An implementation SHOULD allow
804 configuration of the meaning of these values.
806 An application MAY use the Java Cryptography Extension
807 (JCE) with JCE-aware mechanisms to control the selection
808 of cipher suites that match the strength values.
810 If this property is absent, the default strength is
813 SERVER_AUTH ("javax.security.sasl.server.authentication")
815 "true" if server must authenticate to client; default
818 Expires November 2001 [Page 14
820 JAVA SASL API May, 2001
824 MAX_BUFFER ("javax.security.sasl.maxbuffer")
826 Maximum size of receive buffer in bytes of
827 SaslClient/SaslServer; the default is defined by the
828 mechanism. The property value is the string
829 representation of an integer.
831 CLIENT_PKGS ("javax.security.sasl.client.pkgs")
833 A |-separated list of package names to use when locating
834 a SaslClientFactory. Each package MUST contain a class
835 named ClientFactory that implements the SaslClientFactory
838 SERVER_PKGS ("javax.security.sasl.server.pkgs")
840 A |-separated list of package names to use when locating
841 a SaslServerFactory. Each package MUST contain a class
842 named ServerFactory that implements the SaslServerFactory
845 RAW_SEND_SIZE ("javax.security.sasl.rawsendsize")
847 Maximum size of the raw send buffer in bytes of
848 SaslClient/SaslServer. The property value is the string
849 representation of an integer and is negotiated between
850 the client and server during the authentication exchange.
852 The following properties are for defining a security policy for a
853 server or client. Absence of the property is interpreted as "false".
855 POLICY_NOPLAINTEXT ("javax.security.sasl.policy.noplaintext")
857 "true" if mechanisms susceptible to simple
858 plain passive attacks (e.g. "PLAIN") are
861 "false" if such mechanisms are permitted
863 POLICY_NOACTIVE ("javax.security.sasl.policy.noactive")
865 "true" if mechanisms susceptible to active
866 (non-dictionary) attacks are not
869 "false" if such mechanisms are permitted.
871 POLICY_NODICTIONARY ("javax.security.sasl.policy.nodictionary")
873 "true" if mechanisms susceptible to passive
874 dictionary attacks are not permitted
877 Expires November 2001 [Page 15
879 JAVA SASL API May, 2001
882 "false" if such mechanisms are permitted
884 POLICY_NOANONYMOUS ("javax.security.sasl.policy.noanonymous")
886 "true" if mechanisms that accept anonymous
887 login are not permitted
889 "false" if such mechanisms are permitted
891 POLICY_FORWARD_SECRECY ("javax.security.sasl.policy.forward")
893 Forward secrecy means that breaking into one session will not
894 automatically provide information for breaking into future sessions.
896 "true" if mechanisms that implement forward
897 secrecy between sessions are required
899 "false" if such mechanisms are not required
901 POLICY_PASS_CREDENTIALS ("javax.security.sasl.policy.credentials")
903 "true" if mechanisms that pass client
904 credentials are required
906 "false" if such mechanisms are not required
910 4.2 public interface SaslClient
912 An object implementing this interface can negotiate authentication as a
913 client using one of the IANA-registered mechanisms.
916 4.2.1 evaluateChallenge
919 evaluateChallenge(byte[] challenge)
922 If a challenge is received from the server during the authentication
923 process, this method is called to prepare an appropriate next
924 response to submit to the server. The response is null if the
925 challenge accompanied a "SUCCESS" status and the challenge only
926 contains data for the client to update its state and no response
927 needs to be sent to the server. The response is a zero-length byte
928 array if the client is to send a response with no data. A
929 SaslException is thrown if an error occurred while processing the
930 challenge or generating a response.
935 Expires November 2001 [Page 16
937 JAVA SASL API May, 2001
941 challenge The non-null challenge received from the server.
942 The challenge array may have zero length.
945 4.2.2 hasInitialResponse
947 public boolean hasInitialResponse()
949 Determines whether this mechanism has an optional initial response.
950 If true, caller should call evaluateChallenge() with an empty array
951 to get the initial response.
959 This method may be called at any time to determine if the
960 authentication process is finished. Typically, the Protocol Driver
961 will not do this until it has received indication from the server (in
962 a protocol-specific manner) that the process has completed.
967 public byte[] unwrap(byte[] incoming, int offset, int len )
970 Unwraps a byte array received from the server to return the
971 corresponding decoded bytes in a byte array.
973 This method can be called only after the authentication process has
974 completed (i.e., when isComplete() returns true) and only if the
975 authentication process has negotiated integrity and/or privacy as the
976 quality of protection; otherwise, a SaslException is thrown. A
977 SaslException is thrown also if incoming cannot be successfully
980 incoming is the contents of the SASL buffer as defined in [SASL]
981 without the leading four octet field that represents the length.
982 offset and len specify the portion of incoming to use.
986 incoming A non-null byte array containing the encoded
987 bytes from the server.
989 offset The starting position at incoming of the bytes to
993 Expires November 2001 [Page 17
995 JAVA SASL API May, 2001
998 len The number of bytes from incoming to use.
1004 public byte[] wrap(byte[] outgoing, int offset, int len)
1005 throws SaslException
1007 Wraps a byte array to be sent to the server to return the
1008 corresponding encoded bytes in a byte array.
1010 This method can be called only after the authentication exchange has
1011 completed (i.e., when isComplete() returns true) and only if the
1012 authentication exchange has negotiated integrity and/or privacy as
1013 the quality of protection; otherwise, a SaslException is thrown. A
1014 SaslException is thrown also if outgoing cannot be successfully
1017 The result of this method will make up the contents of the SASL
1018 buffer as defined in [SASL] without the leading four octet field that
1019 represents the length.
1021 offset and len specify the portion of outgoing to use.
1025 outgoing A non-null byte array containing the bytes to
1028 offset The starting position at outgoing of the bytes to
1031 len The number of bytes from outgoing to use.
1034 4.2.6 getMechanismName
1039 Reports the IANA-registered name of the mechanism used by this
1040 client, e.g. "GSSAPI" or "CRAM-MD5".
1044 4.2.7 getNegotiatedProperty
1046 public String getNegotiatedProperty(String propName)
1047 throws SaslException
1051 Expires November 2001 [Page 18
1053 JAVA SASL API May, 2001
1056 Retrieves the negotiated property. This method can be called only
1057 after the authentication exchange has completed (i.e., when
1058 isComplete() returns true); otherwise, a SaslException is thrown.
1060 For example, this method may be used to obtained the negotiated raw
1061 send buffer size, quality-of-protection, and cipher strength. See
1062 Section 4.1.7 for a list of standard properties.
1064 This method returns null when the specified property was
1065 not negotiated or is not applicable to this mechanism.
1069 propName The non-null property name.
1074 public abstract void dispose() throws SaslException
1076 Disposes of any system resources or security-sensitive information
1077 the SaslClient might be using. Invoking this method invalidates the
1078 SaslClient instance. This method is idempotent.
1082 4.3 public interface SaslClientFactory
1084 An object implementing this interface can provide a SaslClient. The
1085 implementation must be thread-safe and handle multiple simultaneous
1086 requests. It must also have a public constructor that accepts no
1090 4.3.1 createSaslClient
1093 createSaslClient(String[] mechanisms,
1094 String authorizationID,
1098 javax.security.auth.callback.CallbackHandler cbh)
1099 throws SaslException
1101 Creates a SaslClient using the parameters supplied. It returns null
1102 if no SaslClient can be created using the parameters supplied. Throws
1103 SaslException if it cannot create a SaslClient because of an error.
1109 Expires November 2001 [Page 19
1111 JAVA SASL API May, 2001
1114 mechanisms The non-null list of mechanism names to try. Each
1115 is the IANA-registered name of a SASL mechanism
1116 (e.g. "GSSAPI", "CRAM-MD5").
1118 authorizationID The possibly null protocol-dependent
1119 identification to be used for authorization. If
1120 null or empty, the server derives an
1121 authorization ID from the client's authentication
1122 credentials. When the SASL authentication
1123 completes successfully, the specified entity is
1126 protocol The non-null string name of the protocol for
1127 which the authentication is being performed, e.g
1130 serverName The non-null fully qualified host name of the
1131 server to authenticate to.
1133 props The possibly null set of properties used to
1134 select the SASL mechanism and to configure the
1135 authentication exchange of the selected
1136 mechanism. See the Sasl class for a list of
1137 standard properties. Other, possibly mechanism-
1138 specific, properties can be included. Properties
1139 not relevant to the selected mechanism are
1142 cbh The possibly null callback handler to be used by
1143 the SASL mechanisms to get further information
1144 from the application/library to complete the
1145 authentication. For example, a SASL mechanism
1146 might require the authentication ID, password and
1147 realm from the caller. The authentication ID is
1148 requested by using a NameCallback. The password
1149 is requested by using a PasswordCallback. The
1150 realm is requested by using a RealmChoiceCallback
1151 if there is a list of realms to choose from, and
1152 by using a RealmCallback if the realm must be
1156 4.3.2 getMechanismNames
1159 getMechanismNames(Hashtable props)
1161 Returns a non-null array of names of mechanisms supported by this
1162 factory that match the specified mechanism selection policies.
1167 Expires November 2001 [Page 20
1169 JAVA SASL API May, 2001
1172 props The possibly null set of properties used to
1173 specify the security policy of the SASL
1174 mechanisms. For example, if props contains the
1175 Sasl.POLICY_NOPLAINTEXT property with the value
1176 "true", then the factory must not return any SASL
1177 mechanisms that are susceptible to simple plain
1178 passive attacks. See the Sasl class for a
1179 complete list of policy properties. Non-policy
1180 related properties, if present in props, are
1185 4.4 public interface SaslServer
1187 An object implementing this interface can negotiate authentication as a
1188 server using one of the IANA-registered mechanisms.
1191 4.4.1 evaluateResponse
1194 evaluateResponse(byte[] response)
1195 throws SaslException
1197 If a response is received from the client during the authentication
1198 process, this method is called to prepare an appropriate next
1199 challenge to submit to the client. The challenge is null if the
1200 authentication has succeeded and no more challenge data is to be sent
1201 to the client. It is non-null if the authentication must be continued
1202 by sending a challenge to the client, or if the authentication has
1203 succeeded but challenge data needs to be processed by the client. A
1204 SaslException is thrown if an error occurred while processing the
1205 response or generating a challenge. isComplete() should be called
1206 after each call to evaluateResponse() to determine if any further
1207 response is needed from the client. The Protocol Driver will send an
1208 indication (in a protocol-specific manner) as to whether the
1209 authentication has succeeded, failed, or should be continued, and any
1210 accompanying challenge data.
1214 response Non-null response received from client.
1222 This method may be called at any time to determine if the
1223 authentication process is finished. This method is typically called
1225 Expires November 2001 [Page 21
1227 JAVA SASL API May, 2001
1230 after each invocation of evaluateResponse() to determine whether the
1231 authentication has completed successfully or should be continued.
1236 public byte[] unwrap(byte[] incoming, int offset, int len)
1237 throws SaslException
1239 Unwraps a byte array received from the client to return the
1240 corresponding decoded bytes in a byte array.
1242 This method can be called only after the authentication process has
1243 completed (i.e., when isComplete() returns true) and only if the
1244 authentication process has negotiated integrity and/or privacy as the
1245 quality of protection; otherwise, a SaslException is thrown. A
1246 SaslException is thrown also if incoming cannot be successfully
1249 incoming is the contents of the SASL buffer as defined in [SASL]
1250 without the leading four octet field that represents the length.
1251 offset and len specify the portion of incoming to use.
1255 incoming A non-null byte array containing the encoded
1256 bytes from the client.
1258 offset The starting position at incoming of the bytes to
1261 len The number of bytes from incoming to use.
1267 public byte[] wrap(byte[] outgoing, int offset, int len)
1268 throws SaslException
1270 Wraps a byte array to be sent to the client to return the
1271 corresponding encoded bytes in a byte array.
1273 This method can be called only after the authentication exchange has
1274 completed (i.e., when isComplete() returns true) and only if the
1275 authentication exchange has negotiated integrity and/or privacy as
1276 the quality of protection; otherwise, a SaslException is thrown. A
1277 SaslException is thrown also if outgoing cannot be successfully
1283 Expires November 2001 [Page 22
1285 JAVA SASL API May, 2001
1288 The result of this method will make up the contents of the SASL
1289 buffer as defined in [SASL] without the leading four octet field that
1290 represents the length.
1292 offset and len specify the portion of outgoing to use.
1296 outgoing A non-null byte array containing the bytes to
1299 offset The starting position at outgoing of the bytes to
1302 len The number of bytes from outgoing to use.
1305 4.4.5 getMechanismName
1310 Returns the non-null IANA-registered name of the mechanism used by
1311 this server, e.g. "GSSAPI" or "CRAM-MD5".
1314 4.4.6 getAuthorizationID
1317 getAuthorizationID() throws SaslException
1319 Reports the authorization ID in effect for the client of this
1320 session. Can only be called if isComplete() returns true; throws
1321 SaslException if called before authentication completes.
1324 4.4.7 getNegotiatedProperty
1326 public String getNegotiatedProperty(String propName)
1327 throws SaslException
1329 Retrieves the negotiated property. This method can be called only
1330 after the authentication exchange has completed (i.e., when
1331 isComplete() returns true); otherwise, a SaslException is thrown.
1333 For example, this method may be used to obtained the negotiated raw
1334 send buffer size, quality-of-protection, and cipher strength. See
1335 Section 4.1.7 for a list of standard properties.
1337 This method returns null when the specified property was
1338 not negotiated or is not applicable to this mechanism.
1341 Expires November 2001 [Page 23
1343 JAVA SASL API May, 2001
1348 propName The non-null property name.
1353 public abstract void dispose() throws SaslException
1355 Disposes of any system resources or security-sensitive information
1356 the SaslServer might be using. Invoking this method invalidates the
1357 SaslServer instance. This method is idempotent.
1360 4.5 public interface SaslServerFactory
1362 An object implementing this interface can provide a SaslServer. The
1363 implementation must be thread-safe and handle multiple simultaneous
1364 requests. It must also have a public constructor that accepts no
1368 4.5.1 createSaslServer
1371 createSaslServer(String mechanism,
1375 javax.security.auth.callback.CallbackHandler cbh)
1376 throws SaslException
1378 Creates a SaslServer using the mechanism supplied. It returns null if
1379 no SaslServer can be created using the parameters supplied. Throws
1380 SaslException if it cannot create a SaslServer because of an error.
1382 Returns a possibly null SaslServer which supports the specified
1383 mechanism. If null, this factory cannot produce a SaslServer for the
1384 specified mechanism.
1388 mechanism The non-null IANA-registered name of a SASL
1389 mechanism (e.g. "GSSAPI", "CRAM-MD5").
1391 protocol The non-null string name of the protocol for
1392 which the authentication is being performed, e.g
1395 serverName The non-null fully qualified host name of the
1399 Expires November 2001 [Page 24
1401 JAVA SASL API May, 2001
1404 props The possibly null set of properties to be used to
1405 select the SASL mechanism and to configure the
1406 authentication exchange of the selected
1407 mechanism. See the Sasl class for a list of
1408 standard properties. Other, possibly mechanism-
1409 specific, properties can be included. Properties
1410 not relevant to the selected mechanism are
1413 cbh The possibly null callback handler to be used
1414 by the SASL mechanisms to get further information
1415 from the application/library to complete the
1416 authentication. For example, a SASL mechanism
1417 might require the authentication ID, password and
1418 realm from the caller. The authentication ID is
1419 requested by using a NameCallback. The password
1420 is requested by using a PasswordCallback. The
1421 realm is requested by using a RealmChoiceCallback
1422 if there is a list of realms to choose from, and
1423 by using a RealmCallback if the realm must be
1427 4.5.2 getMechanismNames
1430 getMechanismNames(Hashtable props)
1432 Returns a non-null array of names of mechanisms supported by this
1433 factory that match the specified mechanism selection policies.
1437 props The possibly null set of properties used to
1438 specify the security policy of the SASL
1439 mechanisms. For example, if props includes the
1440 Sasl.POLICY_NOPLAINTEXT property with the value
1441 "true", then the factory must not return any SASL
1442 mechanisms that are susceptible to simple plain
1443 passive attacks. See the Sasl class for a
1444 complete list of policy properties. Non-policy
1445 related properties, if present in props, are
1449 4.6 public class AuthorizeCallback
1450 implements javax.security.auth.callback.Callback
1452 This callback is used by SaslServer to determine whether one entity
1453 (identified by an authenticated authentication id) can act on behalf of
1454 another entity (identified by an authorization id).
1457 Expires November 2001 [Page 25
1459 JAVA SASL API May, 2001
1464 public AuthorizeCallback(String authnID,
1469 authnID The authentication id
1471 authzID The authorization id
1474 4.6.2 getAuthenticationID
1476 public String getAuthenticationID()
1478 Returns the authentication id to check.
1481 4.6.3 getAuthorizationID
1483 public String getAuthorizationID()
1485 Returns the authorization id to check.
1490 public boolean isAuthorized()
1492 Returns true if authorization is allowed, false otherwise.
1497 public void setAuthorized(boolean ok)
1499 Sets whether authorization is allowed or not.
1503 ok true if authorization is to be allowed, false
1507 4.6.6 getAuthorizedID
1509 public String getAuthorizedID()
1511 Returns the id of the authorized user. If null, this means the
1512 authorization failed.
1514 Expires November 2001 [Page 26
1516 JAVA SASL API May, 2001
1521 4.6.7 setAuthorizedID
1523 public void setAuthorizedID(String id)
1525 Sets the id of the authorized entity. The method is called by the
1526 handler only if the id is different from that returned by
1527 getAuthorizationID(). For example, the id might need to be
1528 canonicalized for the environment in which it will be used.
1532 id The id of the authorized user
1535 4.7 public class RealmCallback
1536 extends javax.security.auth.callback.TextInputCallback
1538 This callback is used by SaslClient and SaslServer to retrieve realm
1544 public RealmCallback (String prompt)
1546 Constructs a RealmCallback with a prompt.
1549 public RealmCallback (String prompt, String defaultRealm)
1551 Constructs a RealmCallback with a prompt and a default realm.
1554 IllegalArgumentException is thrown if prompt is null or the empty
1555 string, or if defaultRealm is empty or null.
1560 prompt The non-null prompt to use to request the realm
1563 defaultRealm The non-null default realm to use
1566 4.8 public class RealmChoiceCallback
1567 extends javax.security.auth.callback.ChoiceCallback
1569 This callback is used by SaslClient and SaslServer to obtain one or
1570 more realms given a list of realm choices.
1572 Expires November 2001 [Page 27
1574 JAVA SASL API May, 2001
1581 public RealmChoiceCallback (String prompt,
1584 boolean multipleSelectionsAllowed)
1586 Constructs a RealmChoiceCallback with a prompt, a list of choices and
1589 IllegalArgumentException is thrown if prompt is null or the empty
1590 string, or if defaultRealm is empty or null.
1595 prompt The non-null prompt to use to request the realm
1597 choices The non-null list of realms to choose from
1599 defaultChoice The choice to use as the default choice when the
1600 list of choices is displayed. It is an index into
1603 multipleSelectionsAllowed Specifies whether or not multiple
1604 selections can be made from the list of choices.
1607 4.9 public class SaslException extends IOException
1609 Exception thrown on errors and failures that occur when using SASL.
1614 public SaslException()
1616 Constructs a new instance of SaslException. The root exception and
1617 the detailed message are null.
1620 public SaslException(String message)
1623 Constructs a default exception with a detailed message and no root
1627 public SaslException(String message,
1630 Expires November 2001 [Page 28
1632 JAVA SASL API May, 2001
1636 Constructs a new instance of SaslException with a detailed message
1637 and a root exception. For example, a SaslException might result from
1638 a problem with the callback handler, which might throw a
1639 NoSuchCallbackException if it does not support the requested
1640 callback, or throw an IOException if it had problems obtaining data
1641 for the callback. The SaslException's root exception would then be
1642 the exception thrown by the callback handler.
1647 message Possibly null additional detail about the
1650 ex A possibly null root exception that caused this
1659 Returns the cause of this exception or null if the cause is
1660 nonexistent or unknown. The cause is the throwable that caused this
1661 exception to be thrown.
1664 4.9.3 printStackTrace
1669 Prints this exception's stack trace to System.err. If this exception
1670 has a root exception, the stack trace of the root exception is also
1671 printed to System.err.
1674 printStackTrace(PrintStream ps)
1676 Prints this exception's stack trace to a print stream. If this
1677 exception has a root exception, the stack trace of the root exception
1678 is also printed to the print stream.
1681 printStackTrace(PrintWriter pw)
1683 Prints this exception's stack trace to a print writer. If this
1684 exception has a root exception, the stack trace of the root exception
1685 is also printed to the print writer.
1688 Expires November 2001 [Page 29
1690 JAVA SASL API May, 2001
1695 ps The non-null print stream to which to print.
1697 pw The non-null print writer to which to print.
1700 5. Security Considerations
1702 When SASL authentication is performed over unsecured connections, it
1703 is possible for an active attacker to spoof the server's protocol-
1704 specific indication that authentication is complete. Clients should
1705 protect against this attack by verifying the completion of
1706 authentication with the Mechanism Driver by calling the driver's
1707 isComplete() method.
1709 Additional security considerations are discussed in [SASL].
1714 Copyright (C) The Internet Society (2001). All Rights Reserved.
1716 This document and translations of it may be copied and furnished to
1717 others, and derivative works that comment on or otherwise explain it
1718 or assist in its implementation may be prepared, copied, published
1719 and distributed, in whole or in part, without restriction of any
1720 kind, provided that the above copyright notice and this paragraph are
1721 included on all such copies and derivative works. However, this
1722 document itself may not be modified in any way, such as by removing
1723 the copyright notice or references to the Internet Society or other
1724 Internet organizations, except as needed for the purpose of
1725 developing Internet standards in which case the procedures for
1726 copyrights defined in the Internet Standards process must be
1727 followed, or as required to translate it into languages other than
1730 The limited permissions granted above are perpetual and will not be
1731 revoked by the Internet Society or its successors or assigns.
1733 This document and the information contained herein is provided on an
1734 "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
1735 TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
1736 BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
1737 HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
1738 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1743 [JAAS] Java Software, Sun Microsystems, Inc., "Java Authentication
1744 and Authorization Service, "http://java.sun.com/products/jaas",
1747 Expires November 2001 [Page 30
1749 JAVA SASL API May, 2001
1753 [SASL] J. Myers, "Simple Authentication and Security Layer (SASL)",
1754 RFC 2222, October 1997
1757 8. Authors' Addresses
1761 3290 W. Bayshore Road
1768 Mail Stop UCUP02-206
1769 901 San Antonio Road
1772 Email: rosanna.lee@eng.sun.com
1777 Rob Earhart, then of Carnegie Mellon University, was a coauthor of an
1780 Scott Seligman of Sun Microsystems, Inc. contributed to the
1781 architecture and API proposed in this document.
1783 Joe Salowey of WRQ, Anthony J. Nadalin of IBM, Bob Naugle of
1784 Bluestone, and Timothy Martin of Carnegie Mellon University
1785 contributed to the contents of this revision of the draft through
1786 participation in the expert group for Java Specification Request 28 -
1787 http://java.sun.com/aboutJava/communityprocess/jsr/jsr_028_sasl.html.
1790 10. Changes from draft-weltman-java-sasl-04.txt
1792 SaslClient, SaslServer
1794 Added dispose() to allow security-sensitive information to be purged
1795 from Mechanism Drivers deterministically.
1797 Replaced getInputStream() and getOutputStream() with unwrap() and
1798 wrap(), respectively, to remove dependency on stream-based I/O.
1800 Replaced getNegotiatedQop() and getNegotiatedStrength() with the more
1801 generic getNegotiatedProperty() to support access to other negotiated
1806 Expires November 2001 [Page 31
1808 JAVA SASL API May, 2001
1812 Changed getAuthenticationId() to getAuthenticationID(),
1813 getAuthorizationId() to getAuthorizationID(), and getAuthorizedId()
1814 to getAuthorizedID(). This was to conform to the naming convention
1815 used in the rest of the API.
1818 11. Changes from draft-weltman-java-sasl-03.txt
1822 Added getClientFactories() and getServerFactories().
1823 Updated the list of standard properties.
1824 Added the use of the J2SE version 1.3 service provider guidelines for
1825 locating SaslClientFactory and SaslServerFactory implementations.
1830 Added getNegotiatedQop() and getNegotiatedStrength()
1833 SaslClientFactory and SaslServerFactory
1835 getMechanismNames() takes a properties Hashtable as argument.
1840 Added getNegotiatedQop() and getNegotiatedStrength()
1845 New class to allow SaslServer to determine if an identity may be
1846 authorized as another identity.
1849 RealmCallback and RealmChoiceCallback
1851 New classes for obtaining realm information.
1856 getRootException changed to getCause, in anticipation of a new
1857 standard Java API for nested exceptions. Also, printStackTrace prints
1858 both the current and the nested exception.
1861 12. Changes from draft-weltman-java-sasl-02.txt
1865 Expires November 2001 [Page 32
1867 JAVA SASL API May, 2001
1871 The SecurityLayer interface was removed.
1876 createInitialResponse() was removed. evaluateChallenge() accepts an
1877 empty challenge and can return an initial response.
1878 hasInitialResponse() was added to determine if the mechanism allows
1879 for an initial client response.
1882 SaslClient and SaslServer
1884 getSecurityLayer() was replaced with getInputStream() and
1887 Package names are |-delimited, not space-delimited, in the pkgs
1924 Expires November 2001 [Page 33
1926 JAVA SASL API May, 2001
1929 13. Appendix A - Sample Java LDAP program using SASL
1931 /****************************************************************
1932 It might look like this in LDAP. The Protocol Driver is
1933 implemented as part of the authenticate method of
1934 LDAPConnection. If a security layer is negotiated, the Protocol
1935 Driver creates new input and output streams that use the
1936 SaslClient to encode and decode any subsequent messages.
1937 ****************************************************************/
1939 public void authenticate( String dn,
1942 CallbackHandler cbh )
1943 throws SaslException {
1945 // Create SASL client to use for authentication
1946 SaslClient saslClnt = Sasl.createSaslClient(
1947 mechs, dn, "ldap", getHost(), props, cbh);
1949 if (saslClnt == null) {
1950 throw new SaslException("SASL client not available");
1953 String mechName = saslClnt.getMechanismName();
1955 // Get initial response, if any
1956 byte[] response = (saslClnt.hasInitialResponse() ?
1957 saslClnt.evaluateChallenge(new byte[0]) :
1961 // Create a bind request message, including the initial
1962 // response (if any), and send it off
1963 writeRequest( new LDAPSASLBindRequest( dn, mechName,
1966 // Get the server challenge
1967 LDAPSASLBindResponse msg =
1968 (LDAPSASLBindResponse)readResponse();
1970 // Authentication done?
1971 while (!saslClnt.isComplete() &&
1972 (msg.getStatus() == LDAP_SASL_BIND_IN_PROGRESS ||
1973 msg.getStatus() == LDAP_SUCCESS)) {
1975 // No, process challenge to get an appropriate next
1977 byte[] challenge = msg.getChallenge();
1978 response = saslClnt.evaluateChallenge( challenge );
1980 // May be a success message with no further response
1981 if ( msg.getStatus() == LDAP_SUCCESS) {
1983 Expires November 2001 [Page 34
1985 JAVA SASL API May, 2001
1988 if ( response != null ) {
1989 // Protocol error; supposed to be done already
1990 throw new SaslException("Protocol error in " +
1996 // Wrap the response in another bind request and send
1998 writeRequest( new LDAPSASLBindRequest( dn, mechName,
2000 msg = (LDAPSASLBindResponse)readResponse();
2003 // Make sure authentication REALLY is complete
2004 if ( !saslClnt.isComplete() ) {
2005 // Authentication session hijacked!
2006 throw new SaslException( "SASL session hijacked!" );
2009 // Check if a security layer was negotiated
2010 String qop = saslClnt.getNegotiatedProperty(Sasl.QOP);
2011 if ( qop != null && (qop.equalsIgnoreCase("auth-int") ||
2012 qop.equalsIgnoreCase("auth-conf")) ) {
2014 new SaslInputStream( saslClnt,
2017 new SaslOutputStream( saslClnt,
2018 getOutputStream() );
2042 Expires November 2001 [Page 35