1 /* ClientMechanism.java --
2    Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
3 
4 This file is a part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 USA
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version.  */
37 
38 
39 package gnu.javax.crypto.sasl;
40 
41 import gnu.java.security.Registry;
42 
43 import java.util.HashMap;
44 import java.util.Map;
45 
46 import javax.security.auth.callback.CallbackHandler;
47 import javax.security.sasl.Sasl;
48 import javax.security.sasl.SaslClient;
49 import javax.security.sasl.SaslException;
50 
51 /**
52  * A base class to facilitate implementing SASL client-side mechanisms.
53  */
54 public abstract class ClientMechanism
55     implements SaslClient
56 {
57   /** Name of this mechanism. */
58   protected String mechanism;
59   /** The authorisation identity. */
60   protected String authorizationID;
61   /** Name of protocol using this mechanism. */
62   protected String protocol;
63   /** Name of server to authenticate to. */
64   protected String serverName;
65   /** Properties of qualities desired for this mechanism. */
66   protected Map properties;
67   /** Callback handler to use with this mechanism instance. */
68   protected CallbackHandler handler;
69   /** Channel binding data to use with this mechanism instance. */
70   protected byte[] channelBinding;
71   /** Whether authentication phase is completed (true) or not (false). */
72   protected boolean complete = false;
73   /** The state of the authentication automaton. */
74   protected int state = -1;
75 
ClientMechanism(final String mechanism)76   protected ClientMechanism(final String mechanism)
77   {
78     super();
79 
80     this.mechanism = mechanism;
81     this.state = -1;
82   }
83 
initMechanism()84   protected abstract void initMechanism() throws SaslException;
85 
resetMechanism()86   protected abstract void resetMechanism() throws SaslException;
87 
evaluateChallenge(byte[] challenge)88   public abstract byte[] evaluateChallenge(byte[] challenge)
89       throws SaslException;
90 
hasInitialResponse()91   public abstract boolean hasInitialResponse();
92 
isComplete()93   public boolean isComplete()
94   {
95     return complete;
96   }
97 
unwrap(final byte[] incoming, final int offset, final int len)98   public byte[] unwrap(final byte[] incoming, final int offset, final int len)
99       throws SaslException
100   {
101     if (! isComplete())
102       throw new IllegalMechanismStateException();
103     return this.engineUnwrap(incoming, offset, len);
104   }
105 
wrap(final byte[] outgoing, final int offset, final int len)106   public byte[] wrap(final byte[] outgoing, final int offset, final int len)
107       throws SaslException
108   {
109     if (! isComplete())
110       throw new IllegalMechanismStateException();
111     return this.engineWrap(outgoing, offset, len);
112   }
113 
getMechanismName()114   public String getMechanismName()
115   {
116     return mechanism;
117   }
118 
getNegotiatedProperty(final String propName)119   public Object getNegotiatedProperty(final String propName)
120   {
121     if (! isComplete())
122       throw new IllegalStateException();
123     if (Sasl.QOP.equals(propName))
124       return getNegotiatedQOP();
125     if (Sasl.STRENGTH.equals(propName))
126       return getNegotiatedStrength();
127     if (Sasl.SERVER_AUTH.equals(propName))
128       return getNegotiatedServerAuth();
129     if (Sasl.MAX_BUFFER.equals(propName))
130       return getNegotiatedMaxBuffer();
131     if (Sasl.RAW_SEND_SIZE.equals(propName))
132       return getNegotiatedRawSendSize();
133     if (Sasl.POLICY_NOPLAINTEXT.equals(propName))
134       return getNegotiatedPolicyNoPlainText();
135     if (Sasl.POLICY_NOACTIVE.equals(propName))
136       return getNegotiatedPolicyNoActive();
137     if (Sasl.POLICY_NODICTIONARY.equals(propName))
138       return getNegotiatedPolicyNoDictionary();
139     if (Sasl.POLICY_NOANONYMOUS.equals(propName))
140       return getNegotiatedPolicyNoAnonymous();
141     if (Sasl.POLICY_FORWARD_SECRECY.equals(propName))
142       return getNegotiatedPolicyForwardSecrecy();
143     if (Sasl.POLICY_PASS_CREDENTIALS.equals(propName))
144       return getNegotiatedPolicyPassCredentials();
145     if (Sasl.REUSE.equals(propName))
146       return getReuse();
147     return null;
148   }
149 
dispose()150   public void dispose() throws SaslException
151   {
152   }
153 
getAuthorizationID()154   public String getAuthorizationID()
155   {
156     return authorizationID;
157   }
158 
getNegotiatedQOP()159   protected String getNegotiatedQOP()
160   {
161     return Registry.QOP_AUTH;
162   }
163 
getNegotiatedStrength()164   protected String getNegotiatedStrength()
165   {
166     return Registry.STRENGTH_LOW;
167   }
168 
getNegotiatedServerAuth()169   protected String getNegotiatedServerAuth()
170   {
171     return Registry.SERVER_AUTH_FALSE;
172   }
173 
getNegotiatedMaxBuffer()174   protected String getNegotiatedMaxBuffer()
175   {
176     return null;
177   }
178 
getNegotiatedRawSendSize()179   protected String getNegotiatedRawSendSize()
180   {
181     return String.valueOf(Registry.SASL_BUFFER_MAX_LIMIT);
182   }
183 
getNegotiatedPolicyNoPlainText()184   protected String getNegotiatedPolicyNoPlainText()
185   {
186     return null;
187   }
188 
getNegotiatedPolicyNoActive()189   protected String getNegotiatedPolicyNoActive()
190   {
191     return null;
192   }
193 
getNegotiatedPolicyNoDictionary()194   protected String getNegotiatedPolicyNoDictionary()
195   {
196     return null;
197   }
198 
getNegotiatedPolicyNoAnonymous()199   protected String getNegotiatedPolicyNoAnonymous()
200   {
201     return null;
202   }
203 
getNegotiatedPolicyForwardSecrecy()204   protected String getNegotiatedPolicyForwardSecrecy()
205   {
206     return null;
207   }
208 
getNegotiatedPolicyPassCredentials()209   protected String getNegotiatedPolicyPassCredentials()
210   {
211     return null;
212   }
213 
getReuse()214   protected String getReuse()
215   {
216     return Registry.REUSE_FALSE;
217   }
218 
engineUnwrap(final byte[] incoming, final int offset, final int len)219   protected byte[] engineUnwrap(final byte[] incoming, final int offset,
220                                 final int len) throws SaslException
221   {
222     final byte[] result = new byte[len];
223     System.arraycopy(incoming, offset, result, 0, len);
224     return result;
225   }
226 
engineWrap(final byte[] outgoing, final int offset, final int len)227   protected byte[] engineWrap(final byte[] outgoing, final int offset,
228                               final int len) throws SaslException
229   {
230     final byte[] result = new byte[len];
231     System.arraycopy(outgoing, offset, result, 0, len);
232     return result;
233   }
234 
235   /**
236    * Initialises the mechanism with designated attributes. Permissible names and
237    * values are mechanism specific.
238    *
239    * @param attributes a set of name-value pairs that describes the desired
240    *          future behaviour of this instance.
241    * @throws IllegalMechanismStateException if the instance is already
242    *           initialised.
243    * @throws SaslException if an exception occurs during the process.
244    */
init(final Map attributes)245   public void init(final Map attributes) throws SaslException
246   {
247     if (state != -1)
248       throw new IllegalMechanismStateException("init()");
249     if (properties == null)
250       properties = new HashMap();
251     else
252       properties.clear();
253     if (attributes != null)
254       {
255         authorizationID = (String) attributes.get(Registry.SASL_AUTHORISATION_ID);
256         protocol = (String) attributes.get(Registry.SASL_PROTOCOL);
257         serverName = (String) attributes.get(Registry.SASL_SERVER_NAME);
258         handler = (CallbackHandler) attributes.get(Registry.SASL_CALLBACK_HANDLER);
259         channelBinding = (byte[]) attributes.get(Registry.SASL_CHANNEL_BINDING);
260         properties.putAll(attributes);
261       }
262     else
263       handler = null;
264 
265     if (authorizationID == null)
266       authorizationID = "";
267     if (protocol == null)
268       protocol = "";
269     if (serverName == null)
270       serverName = "";
271     if (channelBinding == null)
272       channelBinding = new byte[0];
273     initMechanism();
274     complete = false;
275     state = 0;
276   }
277 
278   /**
279    * Resets the mechanism instance for re-initialisation and use with other
280    * characteristics.
281    *
282    * @throws SaslException if an exception occurs during the process.
283    */
reset()284   public void reset() throws SaslException
285   {
286     resetMechanism();
287     properties.clear();
288     authorizationID = protocol = serverName = null;
289     channelBinding = null;
290     complete = false;
291     state = -1;
292   }
293 }
294