001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.pwd;
016    
017    import com.liferay.portal.PwdEncryptorException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.CharPool;
021    import com.liferay.portal.kernel.util.PropsKeys;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.util.PropsValues;
026    
027    /**
028     * @author Tomas Polesovsky
029     */
030    public class LegacyAlgorithmAwarePasswordEncryptor
031            extends BasePasswordEncryptor {
032    
033            public String[] getSupportedAlgorithmTypes() {
034                    return _parentPasswordEncryptor.getSupportedAlgorithmTypes();
035            }
036    
037            public void setParentPasswordEncryptor(
038                    PasswordEncryptor defaultPasswordEncryptor) {
039    
040                    _parentPasswordEncryptor = defaultPasswordEncryptor;
041            }
042    
043            @Override
044            protected String doEncrypt(
045                            String algorithm, String plainTextPassword,
046                            String encryptedPassword)
047                    throws PwdEncryptorException {
048    
049                    if (Validator.isNull(
050                                    PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY)) {
051    
052                            if (_log.isDebugEnabled()) {
053                                    _log.debug(
054                                            "Skipping passwords upgrade scheme because " +
055                                                    PropsKeys.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY +
056                                                            " is blank");
057                            }
058    
059                            return _parentPasswordEncryptor.encrypt(
060                                    algorithm, plainTextPassword, encryptedPassword);
061                    }
062    
063                    if (_log.isDebugEnabled()) {
064                            String message =
065                                    "Using legacy detection scheme for algorithm " + algorithm +
066                                            " with current password ";
067    
068                            if (Validator.isNull(encryptedPassword)) {
069                                    message += "empty";
070                            }
071                            else {
072                                    message += "provided";
073                            }
074    
075                            _log.debug(message);
076                    }
077    
078                    boolean prependAlgorithm = true;
079    
080                    if (Validator.isNotNull(encryptedPassword) &&
081                            (encryptedPassword.charAt(0) != CharPool.OPEN_CURLY_BRACE)) {
082    
083                            algorithm = PropsValues.PASSWORDS_ENCRYPTION_ALGORITHM_LEGACY;
084    
085                            prependAlgorithm = false;
086    
087                            if (_log.isDebugEnabled()) {
088                                    _log.debug("Using legacy algorithm " + algorithm);
089                            }
090                    }
091                    else if (Validator.isNotNull(encryptedPassword) &&
092                                     (encryptedPassword.charAt(0) == CharPool.OPEN_CURLY_BRACE)) {
093    
094                            int index = encryptedPassword.indexOf(CharPool.CLOSE_CURLY_BRACE);
095    
096                            if (index > 0) {
097                                    algorithm = encryptedPassword.substring(1, index);
098    
099                                    encryptedPassword = encryptedPassword.substring(index + 1);
100                            }
101    
102                            if (_log.isDebugEnabled()) {
103                                    _log.debug("Upgraded password to use algorithm " + algorithm);
104                            }
105                    }
106    
107                    String newEncryptedPassword = _parentPasswordEncryptor.encrypt(
108                            algorithm, plainTextPassword, encryptedPassword);
109    
110                    if (!prependAlgorithm) {
111                            if (_log.isDebugEnabled()) {
112                                    _log.debug(
113                                            "Generated password without algorithm prefix using " +
114                                                    algorithm);
115                            }
116    
117                            return newEncryptedPassword;
118                    }
119    
120                    if (_log.isDebugEnabled()) {
121                            _log.debug(
122                                    "Generated password with algorithm prefix using " + algorithm);
123                    }
124    
125                    StringBundler sb = new StringBundler(4);
126    
127                    sb.append(StringPool.OPEN_CURLY_BRACE);
128                    sb.append(getAlgorithmName(algorithm));
129                    sb.append(StringPool.CLOSE_CURLY_BRACE);
130                    sb.append(newEncryptedPassword);
131    
132                    return sb.toString();
133            }
134    
135            protected String getAlgorithmName(String algorithm) {
136                    int index = algorithm.indexOf(CharPool.SLASH);
137    
138                    if (index > 0) {
139                            return algorithm.substring(0, index);
140                    }
141    
142                    return algorithm;
143            }
144    
145            private static Log _log = LogFactoryUtil.getLog(
146                    LegacyAlgorithmAwarePasswordEncryptor.class);
147    
148            private PasswordEncryptor _parentPasswordEncryptor;
149    
150    }