001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014 ForgeRock AS
026 */
027package org.opends.server.api;
028import org.forgerock.i18n.LocalizableMessage;
029
030
031
032import java.util.List;
033
034import org.opends.server.admin.std.server.PasswordStorageSchemeCfg;
035import org.forgerock.opendj.config.server.ConfigException;
036import org.opends.server.types.*;
037import org.forgerock.opendj.ldap.ByteString;
038import org.forgerock.opendj.ldap.ByteSequence;
039
040
041/**
042 * This class defines the set of methods and structures that must be
043 * implemented by a Directory Server module that implements a password
044 * storage scheme.  Each subclass may only implement a single password
045 * storage scheme type.
046 *
047 * @param  <T>  The type of configuration handled by this
048 *              password storage scheme
049 */
050@org.opends.server.types.PublicAPI(
051     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
052     mayInstantiate=false,
053     mayExtend=true,
054     mayInvoke=false)
055public abstract class
056       PasswordStorageScheme <T extends PasswordStorageSchemeCfg>
057{
058  /**
059   * Initializes this password storage scheme handler based on the
060   * information in the provided configuration entry.  It should also
061   * register itself with the Directory Server for the particular
062   * storage scheme that it will manage.
063   *
064   * @param  configuration  The configuration entry that contains the
065   *                        information to use to initialize this
066   *                        password storage scheme handler.
067   *
068   * @throws  ConfigException  If an unrecoverable problem arises in
069   *                           the process of performing the
070   *                           initialization.
071   *
072   * @throws  InitializationException  If a problem occurs during
073   *                                   initialization that is not
074   *                                   related to the server
075   *                                   configuration.
076   */
077  public abstract void initializePasswordStorageScheme(
078         T configuration)
079         throws ConfigException, InitializationException;
080
081
082
083  /**
084   * Indicates whether the provided configuration is acceptable for
085   * this password storage scheme.  It should be possible to call this
086   * method on an uninitialized password storage scheme instance in
087   * order to determine whether the password storage scheme would be
088   * able to use the provided configuration.
089   * <BR><BR>
090   * Note that implementations which use a subclass of the provided
091   * configuration class will likely need to cast the configuration
092   * to the appropriate subclass type.
093   *
094   * @param  configuration        The password storage scheme
095   *                              configuration for which to make the
096   *                              determination.
097   * @param  unacceptableReasons  A list that may be used to hold the
098   *                              reasons that the provided
099   *                              configuration is not acceptable.
100   *
101   * @return  {@code true} if the provided configuration is acceptable
102   *          for this password storage scheme, or {@code false} if
103   *          not.
104   */
105  public boolean isConfigurationAcceptable(
106                      PasswordStorageSchemeCfg configuration,
107                      List<LocalizableMessage> unacceptableReasons)
108  {
109    // This default implementation does not perform any special
110    // validation.  It should be overridden by password storage scheme
111    // implementations that wish to perform more detailed validation.
112    return true;
113  }
114
115
116
117  /**
118   * Performs any necessary finalization that might be required when
119   * this password storage scheme is no longer needed (e.g., the
120   * scheme is disabled or the server is shutting down).
121   */
122  public void finalizePasswordStorageScheme()
123  {
124    // No implementation required by default.
125  }
126
127
128
129  /**
130   * Retrieves the name of the password storage scheme provided by
131   * this handler.
132   *
133   * @return  The name of the password storage scheme provided by this
134   *          handler.
135   */
136  public abstract String getStorageSchemeName();
137
138
139
140  /**
141   * Encodes the provided plaintext password for this storage scheme,
142   * without the name of the associated scheme.  Note that the
143   * provided plaintext password should not be altered in any way.
144   *
145   * @param  plaintext  The plaintext version of the password.
146   *
147   * @return  The password that has been encoded using this storage
148   *          scheme.
149   *
150   * @throws  DirectoryException  If a problem occurs while
151   *                              processing.
152   */
153  public abstract ByteString encodePassword(ByteSequence plaintext)
154         throws DirectoryException;
155
156
157
158  /**
159   * Encodes the provided plaintext password for this storage scheme,
160   * prepending the name of the scheme in curly braces.  Note that the
161   * provided plaintext password should not be altered in any way.
162   *
163   * @param  plaintext  The plaintext version of the password.
164   *
165   * @return  The encoded password, including the name of the storage
166   *          scheme.
167   *
168   * @throws  DirectoryException  If a problem occurs while
169   *                              processing.
170   */
171  public abstract ByteString encodePasswordWithScheme(
172                                  ByteSequence plaintext)
173         throws DirectoryException;
174
175
176
177
178  /**
179   * Indicates whether the provided plaintext password included in a
180   * bind request matches the given stored value.  The provided stored
181   * value should not include the scheme name in curly braces.
182   *
183   * @param  plaintextPassword  The plaintext password provided by the
184   *                            user as part of a simple bind attempt.
185   * @param  storedPassword     The stored password to compare against
186   *                            the provided plaintext password.
187   *
188   * @return  {@code true} if the provided plaintext password matches
189   *          the provided stored password, or {@code false} if not.
190   */
191  public abstract boolean passwordMatches(
192                               ByteSequence plaintextPassword,
193                               ByteSequence storedPassword);
194
195
196
197  /**
198   * Indicates whether this password storage scheme supports the
199   * ability to interact with values using the authentication password
200   * syntax defined in RFC 3112.
201   *
202   * @return  {@code true} if this password storage scheme supports
203   *          the ability to interact with values using the
204   *          authentication password syntax, or {@code false} if it
205   *          does not.
206   */
207  public abstract boolean supportsAuthPasswordSyntax();
208
209
210
211  /**
212   * Retrieves the scheme name that should be used with this password
213   * storage scheme when it is used in the context of the
214   * authentication password syntax.  This default implementation will
215   * return the same value as the {@code getStorageSchemeName} method.
216   *
217   * @return  The scheme name that should be used with this password
218   *          storage scheme when it is used in the context of the
219   *          authentication password syntax.
220   */
221  public String getAuthPasswordSchemeName()
222  {
223    return getStorageSchemeName();
224  }
225
226
227
228  /**
229   * Encodes the provided plaintext password for this storage scheme
230   * using the authentication password syntax defined in RFC 3112.
231   * Note that the provided plaintext password should not be altered
232   * in any way.
233   *
234   * @param  plaintext  The plaintext version of the password.
235   *
236   * @return  The password that has been encoded in the authentication
237   *          password syntax.
238   *
239   * @throws  DirectoryException  If a problem occurs while processing
240   *                              of if this storage scheme does not
241   *                              support the authentication password
242   *                              syntax.
243   */
244  public abstract ByteString encodeAuthPassword(
245      ByteSequence plaintext) throws DirectoryException;
246
247
248
249  /**
250   * Indicates whether the provided plaintext password matches the
251   * encoded password using the authentication password syntax with
252   * the given authInfo and authValue components.
253   *
254   * @param  plaintextPassword  The plaintext password provided by the
255   *                            user.
256   * @param  authInfo           The authInfo component of the password
257   *                            encoded in the authentication password
258   *                            syntax.
259   * @param  authValue          The authValue component of the
260   *                            password encoded in the authentication
261   *                            password syntax.
262   *
263   * @return  {@code true} if the provided plaintext password matches
264   *          the encoded password according to the authentication
265   *          password info syntax, or {@code false} if it does not or
266   *          this storage scheme does not support the authentication
267   *          password syntax.
268   */
269  public abstract boolean authPasswordMatches(
270                               ByteSequence plaintextPassword,
271                               String authInfo, String authValue);
272
273
274
275  /**
276   * Indicates whether this storage scheme is reversible (i.e., it is
277   * possible to obtain the original plaintext value from the stored
278   * password).
279   *
280   * @return  {@code true} if this is a reversible password storage
281   *          scheme, or {@code false} if it is not.
282   */
283  public abstract boolean isReversible();
284
285
286
287  /**
288   * Retrieves the original plaintext value for the provided stored
289   * password.  Note that this should only be called if
290   * {@code isReversible} returns {@code true}.
291   *
292   * @param  storedPassword  The password for which to obtain the
293   *                         plaintext value.  It should not include
294   *                         the scheme name in curly braces.
295   *
296   * @return  The plaintext value for the provided stored password.
297   *
298   * @throws  DirectoryException  If it is not possible to obtain the
299   *                              plaintext value for the provided
300   *                              stored password.
301   */
302  public abstract ByteString getPlaintextValue(
303                                  ByteSequence storedPassword)
304         throws DirectoryException;
305
306
307
308  /**
309   * Retrieves the original plaintext value for the provided password
310   * stored in the authPassword syntax.  Note that this should only be
311   * called if {@code isReversible} returns {@code true}.
312   *
313   * @param  authInfo   The authInfo component of the password encoded
314   *                    in the authentication password syntax.
315   * @param  authValue  The authValue component of the password
316   *                    encoded in the authentication password syntax.
317   *
318   * @return  The plaintext value for the provided stored password.
319   *
320   * @throws  DirectoryException  If it is not possible to obtain the
321   *                              plaintext value for the provided
322   *                              stored password, or if this storage
323   *                              scheme does not support the
324   *                              authPassword syntax..
325   */
326  public abstract ByteString getAuthPasswordPlaintextValue(
327                                  String authInfo, String authValue)
328         throws DirectoryException;
329
330
331
332  /**
333   * Indicates whether this password storage scheme should be
334   * considered "secure".  If the encoding used for this scheme does
335   * not obscure the value at all, or if it uses a method that is
336   * trivial to reverse (e.g., base64), then it should not be
337   * considered secure.
338   * <BR><BR>
339   * This may be used to determine whether a password may be included
340   * in a set of search results, including the possibility of
341   * overriding access controls in the case that access controls would
342   * allow the password to be returned but the password is considered
343   * too insecure to reveal.
344   *
345   * @return  {@code false} if it may be trivial to discover the
346   *          original plain-text password from the encoded form, or
347   *          {@code true} if the scheme offers sufficient protection
348   *          that revealing the encoded password will not easily
349   *          reveal the corresponding plain-text value.
350   */
351  public abstract boolean isStorageSchemeSecure();
352}
353