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-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.extensions; 018 019import org.forgerock.i18n.LocalizableMessage; 020import org.forgerock.opendj.server.config.server.Base64PasswordStorageSchemeCfg; 021import org.opends.server.api.PasswordStorageScheme; 022import org.forgerock.opendj.config.server.ConfigException; 023import org.forgerock.i18n.slf4j.LocalizedLogger; 024import org.opends.server.types.*; 025import org.forgerock.opendj.ldap.ResultCode; 026import org.forgerock.opendj.ldap.ByteString; 027import org.forgerock.opendj.ldap.ByteSequence; 028import org.opends.server.util.Base64; 029 030import static org.opends.messages.ExtensionMessages.*; 031import static org.opends.server.extensions.ExtensionsConstants.*; 032 033/** 034 * This class defines a Directory Server password storage scheme that will store 035 * the values in base64-encoded form. This is a reversible algorithm that 036 * offers very little actual protection -- it will merely obscure the plaintext 037 * value from the casual observer. 038 */ 039public class Base64PasswordStorageScheme 040 extends PasswordStorageScheme<Base64PasswordStorageSchemeCfg> 041{ 042 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 043 044 /** 045 * Creates a new instance of this password storage scheme. Note that no 046 * initialization should be performed here, as all initialization should be 047 * done in the <CODE>initializePasswordStorageScheme</CODE> method. 048 */ 049 public Base64PasswordStorageScheme() 050 { 051 super(); 052 } 053 054 @Override 055 public void initializePasswordStorageScheme( 056 Base64PasswordStorageSchemeCfg configuration) 057 throws ConfigException, InitializationException 058 { 059 // No initialization is required. 060 } 061 062 @Override 063 public String getStorageSchemeName() 064 { 065 return STORAGE_SCHEME_NAME_BASE64; 066 } 067 068 @Override 069 public ByteString encodePassword(ByteSequence plaintext) 070 throws DirectoryException 071 { 072 return ByteString.valueOfUtf8(Base64.encode(plaintext)); 073 } 074 075 @Override 076 public ByteString encodePasswordWithScheme(ByteSequence plaintext) 077 throws DirectoryException 078 { 079 StringBuilder buffer = new StringBuilder(); 080 buffer.append('{'); 081 buffer.append(STORAGE_SCHEME_NAME_BASE64); 082 buffer.append('}'); 083 buffer.append(Base64.encode(plaintext)); 084 085 return ByteString.valueOfUtf8(buffer); 086 } 087 088 @Override 089 public boolean passwordMatches(ByteSequence plaintextPassword, 090 ByteSequence storedPassword) 091 { 092 String userString = Base64.encode(plaintextPassword); 093 String storedString = storedPassword.toString(); 094 return userString.equals(storedString); 095 } 096 097 @Override 098 public boolean isReversible() 099 { 100 return true; 101 } 102 103 @Override 104 public ByteString getPlaintextValue(ByteSequence storedPassword) 105 throws DirectoryException 106 { 107 try 108 { 109 return ByteString.wrap(Base64.decode(storedPassword.toString())); 110 } 111 catch (Exception e) 112 { 113 logger.traceException(e); 114 115 LocalizableMessage message = ERR_PWSCHEME_CANNOT_BASE64_DECODE_STORED_PASSWORD.get( 116 storedPassword, e); 117 throw new DirectoryException(ResultCode.INVALID_CREDENTIALS, message, e); 118 } 119 } 120 121 @Override 122 public boolean supportsAuthPasswordSyntax() 123 { 124 // This storage scheme does not support the authentication password syntax. 125 return false; 126 } 127 128 @Override 129 public ByteString encodeAuthPassword(ByteSequence plaintext) 130 throws DirectoryException 131 { 132 LocalizableMessage message = 133 ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName()); 134 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); 135 } 136 137 @Override 138 public boolean authPasswordMatches(ByteSequence plaintextPassword, 139 String authInfo, String authValue) 140 { 141 // This storage scheme does not support the authentication password syntax. 142 return false; 143 } 144 145 @Override 146 public ByteString getAuthPasswordPlaintextValue(String authInfo, 147 String authValue) 148 throws DirectoryException 149 { 150 LocalizableMessage message = 151 ERR_PWSCHEME_DOES_NOT_SUPPORT_AUTH_PASSWORD.get(getStorageSchemeName()); 152 throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); 153 } 154 155 @Override 156 public boolean isStorageSchemeSecure() 157 { 158 // Base64-encoded values may be easily decoded with no key or special 159 // knowledge. 160 return false; 161 } 162}