/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.internal.wc; import java.util.ArrayList; import java.util.Collections; import org.tmatesoft.svn.core.internal.util.SVNHashMap; import java.util.Iterator; import java.util.List; import java.util.Map; /** * @version 1.0 * @author TMate Software Ltd. */ public abstract class SVNPasswordCipher { public static final String SIMPLE_CIPHER_TYPE = "simple"; public static final String WINCRYPT_CIPHER_TYPE = "wincrypt"; private static final SVNPasswordCipher EMPTY_CIPHER = new CompositePasswordCipher(Collections.EMPTY_LIST, SIMPLE_CIPHER_TYPE); private static final SVNPasswordCipher SIMPLE_CIPHER = new CompositePasswordCipher(Collections.EMPTY_LIST, SIMPLE_CIPHER_TYPE); private static final SVNPasswordCipher WINCRYPT_CIPHER = new SVNWinCryptPasswordCipher(); private static Map ourInstances = new SVNHashMap(); private static String ourDefaultType = SIMPLE_CIPHER_TYPE; static { ourInstances.put(SIMPLE_CIPHER_TYPE, SIMPLE_CIPHER); if (SVNWinCryptPasswordCipher.isEnabled()) { ourInstances.put(WINCRYPT_CIPHER_TYPE, WINCRYPT_CIPHER); ourDefaultType = WINCRYPT_CIPHER_TYPE; } } public static SVNPasswordCipher getInstance(String type) { if (type == null) { return EMPTY_CIPHER; } synchronized (ourInstances) { if (ourInstances.containsKey(type)) { return (SVNPasswordCipher) ourInstances.get(type); } } return EMPTY_CIPHER; } public static boolean hasCipher(String type) { synchronized (ourInstances) { return type != null && ourInstances.containsKey(type); } } public static void setDefaultCipherType(String type) { synchronized (ourInstances) { ourDefaultType = type; } } public static String getDefaultCipherType() { synchronized (ourInstances) { if (ourDefaultType != null) { return ourDefaultType; } else if (!ourInstances.isEmpty()) { ourDefaultType = (String) ourInstances.keySet().iterator().next(); return ourDefaultType; } } return SIMPLE_CIPHER_TYPE; } public static void registerCipher(String type, SVNPasswordCipher cipher) { if (type != null && cipher != null) { synchronized (ourInstances) { if (ourInstances.containsKey(type)) { ((CompositePasswordCipher) ourInstances.get(type)).addCipher(cipher); } else { cipher = new CompositePasswordCipher(cipher); ourInstances.put(type, cipher); } } } } protected SVNPasswordCipher() { } public abstract char[] encrypt(char[] rawData); public abstract char[] decrypt(char[] encyrptedData); public abstract String getCipherType(); private static class CompositePasswordCipher extends SVNPasswordCipher { private List myCiphers; private String myCipherType; private CompositePasswordCipher(List chiphers, String cipherType) { myCiphers = chiphers; myCipherType = cipherType; } public CompositePasswordCipher(SVNPasswordCipher chipher) { myCiphers = new ArrayList(); myCiphers.add(chipher); } public synchronized void addCipher(SVNPasswordCipher chipher) { myCiphers.add(chipher); } public synchronized char[] decrypt(char[] encryptedData) { for (Iterator chiphers = myCiphers.iterator(); chiphers.hasNext();) { SVNPasswordCipher chipher = (SVNPasswordCipher) chiphers.next(); encryptedData = chipher.decrypt(encryptedData); } return encryptedData; } public synchronized char[] encrypt(char[] rawData) { for (Iterator chiphers = myCiphers.iterator(); chiphers.hasNext();) { SVNPasswordCipher chipher = (SVNPasswordCipher) chiphers.next(); rawData = chipher.encrypt(rawData); } return rawData; } public String getCipherType() { return myCipherType; } } }