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
010 * docs/licenses/cddl.txt
011 * or http://www.opensource.org/licenses/cddl1.php.
012 * See the License for the specific language governing permissions
013 * and limitations under the License.
014 *
015 * When distributing Covered Code, include this CDDL HEADER in each
016 * file and include the License file at
017 * docs/licenses/cddl.txt.  If applicable,
018 * add the following below this CDDL HEADER, with the fields enclosed
019 * by brackets "[]" replaced with your own identifying information:
020 *      Portions Copyright [yyyy] [name of copyright owner]
021 *
022 * CDDL HEADER END
023 *
024 *
025 *      Copyright 2011-2016 UnboundID Corp.
026 */
027package com.unboundid.directory.sdk.ds.api;
028
029
030
031import java.io.InputStream;
032import java.io.OutputStream;
033import java.util.Collections;
034import java.util.List;
035import java.util.Map;
036import javax.crypto.CipherInputStream;
037import javax.crypto.CipherOutputStream;
038
039import com.unboundid.directory.sdk.broker.internal.BrokerExtension;
040import com.unboundid.directory.sdk.common.internal.ExampleUsageProvider;
041import com.unboundid.directory.sdk.common.internal.Reconfigurable;
042import com.unboundid.directory.sdk.common.internal.UnboundIDExtension;
043import com.unboundid.directory.sdk.ds.config.CipherStreamProviderConfig;
044import com.unboundid.directory.sdk.ds.types.DirectoryServerContext;
045import com.unboundid.directory.sdk.ds.internal.DirectoryServerExtension;
046import com.unboundid.ldap.sdk.LDAPException;
047import com.unboundid.ldap.sdk.ResultCode;
048import com.unboundid.util.Extensible;
049import com.unboundid.util.ThreadSafety;
050import com.unboundid.util.ThreadSafetyLevel;
051import com.unboundid.util.args.ArgumentException;
052import com.unboundid.util.args.ArgumentParser;
053
054
055
056/**
057 * This class defines an API that must be implemented by extensions which
058 * provide access to cipher input streams and cipher output streams to be used
059 * by the server in order to read and write encrypted data.
060 * <BR>
061 * <H2>Configuring Cipher Stream Providers</H2>
062 * In order to configure a cipher stream provider created using this API, use a
063 * command like:
064 * <PRE>
065 *      dsconfig create-cipher-stream-provider \
066 *           --provider-name "<I>{provider-name}</I>" \
067 *           --type third-party \
068 *           --set enabled:true \
069 *           --set "extension-class:<I>{class-name}</I>" \
070 *           --set "extension-argument:<I>{name=value}</I>"
071 * </PRE>
072 * where "<I>{provider-name}</I>" is the name to use for the cipher stream
073 * provider instance, "<I>{class-name}</I>" is the fully-qualified name of the
074 * Java class that extends
075 * {@code com.unboundid.directory.sdk.ds.api.CipherStreamProvider},
076 * and "<I>{name=value}</I>" represents name-value pairs for any arguments to
077 * provide to the cipher stream provider.  If multiple arguments should be
078 * provided to the cipher stream provider, then the
079 * "<CODE>--set extension-argument:<I>{name=value}</I></CODE>" option should be
080 * provided multiple times.
081 */
082@Extensible()
083@DirectoryServerExtension()
084@BrokerExtension()
085@ThreadSafety(level=ThreadSafetyLevel.INTERFACE_THREADSAFE)
086public abstract class CipherStreamProvider
087       implements UnboundIDExtension,
088                  Reconfigurable<CipherStreamProviderConfig>,
089                  ExampleUsageProvider
090{
091  /**
092   * Creates a new instance of this cipher stream provider.  All cipher stream
093   * provider implementations must include a default constructor, but any
094   * initialization should generally be done in the
095   * {@code initializeCipherStreamProvider} method.
096   */
097  public CipherStreamProvider()
098  {
099    // No implementation is required.
100  }
101
102
103
104  /**
105   * {@inheritDoc}
106   */
107  public abstract String getExtensionName();
108
109
110
111  /**
112   * {@inheritDoc}
113   */
114  public abstract String[] getExtensionDescription();
115
116
117
118  /**
119   * {@inheritDoc}
120   */
121  public void defineConfigArguments(final ArgumentParser parser)
122         throws ArgumentException
123  {
124    // No arguments will be allowed by default.
125  }
126
127
128
129  /**
130   * Initializes this cipher stream provider.
131   *
132   * @param  serverContext  A handle to the server context for the server in
133   *                        which this extension is running.
134   * @param  config         The general configuration for this cipher stream
135   *                        provider.
136   * @param  parser         The argument parser which has been initialized from
137   *                        the configuration for this cipher stream provider.
138   *
139   * @throws  LDAPException  If a problem occurs while initializing this cipher
140   *                         stream provider.
141   */
142  public void initializeCipherStreamProvider(
143                   final DirectoryServerContext serverContext,
144                   final CipherStreamProviderConfig config,
145                   final ArgumentParser parser)
146         throws LDAPException
147  {
148    // No initialization will be performed by default.
149  }
150
151
152
153  /**
154   * {@inheritDoc}
155   */
156  public boolean isConfigurationAcceptable(
157                      final CipherStreamProviderConfig config,
158                      final ArgumentParser parser,
159                      final List<String> unacceptableReasons)
160  {
161    // No extended validation will be performed by default.
162    return true;
163  }
164
165
166
167  /**
168   * {@inheritDoc}
169   */
170  public ResultCode applyConfiguration(final CipherStreamProviderConfig config,
171                                       final ArgumentParser parser,
172                                       final List<String> adminActionsRequired,
173                                       final List<String> messages)
174  {
175    // By default, no configuration changes will be applied.  If there are any
176    // arguments, then add an admin action message indicating that the extension
177    // needs to be restarted for any changes to take effect.
178    if (! parser.getNamedArguments().isEmpty())
179    {
180      adminActionsRequired.add(
181           "No configuration change has actually been applied.  The new " +
182                "configuration will not take effect until this cipher stream " +
183                "provider is disabled and re-enabled or until the server is " +
184                "restarted.");
185    }
186
187    return ResultCode.SUCCESS;
188  }
189
190
191
192  /**
193   * Performs any cleanup which may be necessary when this cipher stream
194   * provider is to be taken out of service.
195   */
196  public void finalizeCipherStreamProvider()
197  {
198    // No implementation is required.
199  }
200
201
202
203  /**
204   * Wraps the provided input stream in a cipher input stream that can be used
205   * to decrypt data read from the given stream.
206   *
207   * @param  source  The input stream to be wrapped with a cipher input stream.
208   *
209   * @return  The cipher input stream which wraps the provided input stream.
210   *
211   * @throws  LDAPException  If a problem occurs while creating the cipher input
212   *                         stream.
213   */
214  public abstract CipherInputStream createCipherInputStream(
215                                         final InputStream source)
216         throws LDAPException;
217
218
219
220  /**
221   * Wraps the provided output stream in a cipher output stream that can be used
222   * to encrypt data written to the given stream.
223   *
224   * @param  target  The output stream to be wrapped with a cipher output
225   *                 stream.
226   *
227   * @return  The cipher output stream which wraps the provided output stream.
228   *
229   * @throws  LDAPException  If a problem occurs while creating the cipher
230   *                         output stream.
231   */
232  public abstract CipherOutputStream createCipherOutputStream(
233                                          final OutputStream target)
234         throws LDAPException;
235
236
237
238  /**
239   * {@inheritDoc}
240   */
241  public Map<List<String>,String> getExamplesArgumentSets()
242  {
243    return Collections.emptyMap();
244  }
245}