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