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