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