/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ /** * Password Encoder for encrypting url params * * @author christian * */ package org.geoserver.web; import java.security.GeneralSecurityException; import java.util.logging.Logger; import javax.crypto.Cipher; import javax.servlet.http.HttpSession; import org.apache.wicket.protocol.http.servlet.ServletWebRequest; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.util.crypt.AbstractCrypt; import org.apache.wicket.util.crypt.ICrypt; import org.apache.wicket.util.crypt.ICryptFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.security.GeoServerSecurityManager; import org.geotools.util.logging.Logging; import org.jasypt.encryption.pbe.StandardPBEByteEncryptor; /** * Encryptor factory for apache wicket * * @author christian * */ public class GeoserverWicketEncrypterFactory implements ICryptFactory { static ICryptFactory Factory; static protected Logger LOGGER = Logging.getLogger("org.geoserver.security"); static final String ICRYPT_ATTR_NAME="__ICRYPT"; ICrypt NoCrypt = new ICrypt() { @Override public String decryptUrlSafe(String text) { return text; } @Override public String encryptUrlSafe(String plainText) { return plainText; } @Override public void setKey(String key) { } }; class CryptImpl extends AbstractCrypt { protected StandardPBEByteEncryptor enc; CryptImpl (StandardPBEByteEncryptor enc) { this.enc = enc; } @Override protected byte[] crypt(byte[] input, int mode) throws GeneralSecurityException { if (mode==Cipher.ENCRYPT_MODE) { return enc.encrypt(input); } else { return enc.decrypt(input); } } }; /** * Look up in the Spring Context for an implementation * of {@link ICryptFactory} * if nothing found use this default. * */ public static ICryptFactory get() { if (Factory!=null) return Factory; Factory = GeoServerExtensions.bean(ICryptFactory.class); if (Factory==null) Factory=new GeoserverWicketEncrypterFactory(); return Factory; } protected GeoserverWicketEncrypterFactory() { } @Override public ICrypt newCrypt() { RequestCycle cycle = RequestCycle.get(); ServletWebRequest req = (ServletWebRequest)cycle.getRequest(); HttpSession s = (HttpSession) req.getContainerRequest().getSession(false); if (s!=null) { return getEncrypterFromSession(s); } else { LOGGER.warning("No session availabe to get url parameter encrypter"); return NoCrypt; } } protected ICrypt getEncrypterFromSession(HttpSession s) { ICrypt result = (ICrypt) s.getAttribute(ICRYPT_ATTR_NAME); if (result !=null) return result; GeoServerSecurityManager manager = GeoServerApplication.get().getSecurityManager(); char[] key = manager.getRandomPassworddProvider().getRandomPasswordWithDefaultLength(); StandardPBEByteEncryptor enc = new StandardPBEByteEncryptor(); enc.setPasswordCharArray(key); // since the password is copied, we can scramble it manager.disposePassword(key); if (manager.isStrongEncryptionAvailable()) { enc.setProvider(new BouncyCastleProvider()); enc.setAlgorithm("PBEWITHSHA256AND128BITAES-CBC-BC"); } else // US export restrictions enc.setAlgorithm("PBEWITHMD5ANDDES"); result= new CryptImpl(enc); s.setAttribute(ICRYPT_ATTR_NAME, result); return result; } }