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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2006-2008 Sun Microsystems, Inc.
026 */
027 package org.opends.server.extensions;
028
029
030
031 import org.opends.messages.Message;
032 import org.opends.server.admin.std.server.Base64PasswordStorageSchemeCfg;
033 import org.opends.server.api.PasswordStorageScheme;
034 import org.opends.server.config.ConfigException;
035 import org.opends.server.loggers.debug.DebugTracer;
036 import org.opends.server.types.ByteString;
037 import org.opends.server.types.ByteStringFactory;
038 import org.opends.server.types.DebugLogLevel;
039 import org.opends.server.types.DirectoryException;
040 import org.opends.server.types.InitializationException;
041 import org.opends.server.types.ResultCode;
042 import org.opends.server.util.Base64;
043
044 import static org.opends.messages.ExtensionMessages.*;
045 import static org.opends.server.extensions.ExtensionsConstants.*;
046 import static org.opends.server.loggers.debug.DebugLogger.*;
047
048
049
050 /**
051 * This class defines a Directory Server password storage scheme that will store
052 * the values in base64-encoded form. This is a reversible algorithm that
053 * offers very little actual protection -- it will merely obscure the plaintext
054 * value from the casual observer.
055 */
056 public class Base64PasswordStorageScheme
057 extends PasswordStorageScheme<Base64PasswordStorageSchemeCfg>
058 {
059 /**
060 * The tracer object for the debug logger.
061 */
062 private static final DebugTracer TRACER = getTracer();
063
064
065
066 /**
067 * Creates a new instance of this password storage scheme. Note that no
068 * initialization should be performed here, as all initialization should be
069 * done in the <CODE>initializePasswordStorageScheme</CODE> method.
070 */
071 public Base64PasswordStorageScheme()
072 {
073 super();
074 }
075
076
077
078 /**
079 * {@inheritDoc}
080 */
081 @Override()
082 public void initializePasswordStorageScheme(
083 Base64PasswordStorageSchemeCfg configuration)
084 throws ConfigException, InitializationException
085 {
086 // No initialization is required.
087 }
088
089
090
091 /**
092 * {@inheritDoc}
093 */
094 @Override()
095 public String getStorageSchemeName()
096 {
097 return STORAGE_SCHEME_NAME_BASE64;
098 }
099
100
101
102 /**
103 * {@inheritDoc}
104 */
105 @Override()
106 public ByteString encodePassword(ByteString plaintext)
107 throws DirectoryException
108 {
109 return ByteStringFactory.create(Base64.encode(plaintext.value()));
110 }
111
112
113
114 /**
115 * {@inheritDoc}
116 */
117 @Override()
118 public ByteString encodePasswordWithScheme(ByteString plaintext)
119 throws DirectoryException
120 {
121 StringBuilder buffer = new StringBuilder();
122 buffer.append('{');
123 buffer.append(STORAGE_SCHEME_NAME_BASE64);
124 buffer.append('}');
125 buffer.append(Base64.encode(plaintext.value()));
126
127 return ByteStringFactory.create(buffer.toString());
128 }
129
130
131
132 /**
133 * {@inheritDoc}
134 */
135 @Override()
136 public boolean passwordMatches(ByteString plaintextPassword,
137 ByteString storedPassword)
138 {
139 String userString = Base64.encode(plaintextPassword.value());
140 String storedString = storedPassword.stringValue();
141 return userString.equals(storedString);
142 }
143
144
145
146 /**
147 * {@inheritDoc}
148 */
149 @Override()
150 public boolean isReversible()
151 {
152 return true;
153 }
154
155
156
157 /**
158 * {@inheritDoc}
159 */
160 @Override()
161 public ByteString getPlaintextValue(ByteString storedPassword)
162 throws DirectoryException
163 {
164 try
165 {
166 return ByteStringFactory.create(Base64.decode(
167 storedPassword.stringValue()));
168 }
169 catch (Exception e)
170 {
171 if (debugEnabled())
172 {
173 TRACER.debugCaught(DebugLogLevel.ERROR, e);
174 }
175
176 Message message = ERR_PWSCHEME_CANNOT_BASE64_DECODE_STORED_PASSWORD.get(
177 storedPassword.stringValue(), String.valueOf(e));
178 throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, message,
179 e);
180 }
181 }
182
183
184
185 /**
186 * {@inheritDoc}
187 */
188 @Override()
189 public boolean supportsAuthPasswordSyntax()
190 {
191 // This storage scheme does not support the authentication password syntax.
192 return false;
193 }
194
195
196
197 /**
198 * {@inheritDoc}
199 */
200 @Override()
201 public ByteString encodeAuthPassword(ByteString plaintext)
202 throws DirectoryException
203 {
204 Message message =
205 ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
206 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
207 }
208
209
210
211 /**
212 * {@inheritDoc}
213 */
214 @Override()
215 public boolean authPasswordMatches(ByteString plaintextPassword,
216 String authInfo, String authValue)
217 {
218 // This storage scheme does not support the authentication password syntax.
219 return false;
220 }
221
222
223
224 /**
225 * {@inheritDoc}
226 */
227 @Override()
228 public ByteString getAuthPasswordPlaintextValue(String authInfo,
229 String authValue)
230 throws DirectoryException
231 {
232 Message message =
233 ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName());
234 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message);
235 }
236
237
238
239 /**
240 * {@inheritDoc}
241 */
242 @Override()
243 public boolean isStorageSchemeSecure()
244 {
245 // Base64-encoded values may be easily decoded with no key or special
246 // knowledge.
247 return false;
248 }
249 }
250