Package org.geoserver.security.password

Source Code of org.geoserver.security.password.URLMasterPasswordProvider$SecurityProvider

/* (c) 2014 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.
*/
package org.geoserver.security.password;

import static org.geoserver.security.SecurityUtils.scramble;
import static org.geoserver.security.SecurityUtils.toBytes;
import static org.geoserver.security.SecurityUtils.toChars;
import static org.geoserver.security.password.URLMasterPasswordProviderException.URL_LOCATION_NOT_READABLE;
import static org.geoserver.security.password.URLMasterPasswordProviderException.URL_REQUIRED;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.geoserver.config.util.XStreamPersister;
import org.geoserver.security.GeoServerSecurityManager;
import org.geoserver.security.GeoServerSecurityProvider;
import org.geoserver.security.MasterPasswordProvider;
import org.geoserver.security.SecurityUtils;
import org.geoserver.security.config.SecurityNamedServiceConfig;
import org.geoserver.security.validation.SecurityConfigException;
import org.geoserver.security.validation.SecurityConfigValidator;
import org.geotools.data.DataUtilities;
import org.jasypt.encryption.pbe.StandardPBEByteEncryptor;

/**
* Master password provider that retrieves and optionally stores the master password from a url.
*
* @author Justin Deoliveira, OpenGeo
*/
public final class URLMasterPasswordProvider extends MasterPasswordProvider {

    /** base encryption key */
//    static final char[] BASE = new char[]{ 'a', 'f', '8', 'd', 'f', 's', 's', 'v', 'j', 'K', 'L',
//        '0', 'I', 'H', '(', 'a', 'd', 'f', '2', 's', '0', '0', 'd', 's', '9', 'f', '2', 'o', 'f',
//        '(', '4', ']' };

    static final char[] BASE = new char[]{ 'U','n','6','d','I','l','X','T','Q','c','L',')','$','#','q','J',
        'U','l','X','Q','U','!','n','n','p','%','U','r','5','U','u','3','5','H','`','x','P','F','r','X' };

   
    /** permutation indices, this permutation has a cycle of 169 --> more than 168 iterations have no effect */
//    static final int[] PERM = new int[]{25, 10, 5, 21, 14, 27, 23, 4, 3, 31, 16, 29, 20, 11, 0, 26,
//        24, 22, 13, 12, 1, 8, 18, 19, 7, 2, 17, 6, 9, 28, 30, 15};
    static final int[] PERM = new int[]
    {32,19,30,11,34,26,3,21,9,37,38,13,23,2,18,4,20,1,29,17,0,31,14,36,12,24,15,35,16,39,25,5,10,8,7,6,33,27,28,22 };

   
    URLMasterPasswordProviderConfig config;

    @Override
    public void initializeFromConfig(SecurityNamedServiceConfig config)
            throws IOException {
        super.initializeFromConfig(config);
        this.config = (URLMasterPasswordProviderConfig)config;
    }

    @Override
    protected char[] doGetMasterPassword() throws Exception {
        try {
            InputStream in = input(config.getURL(), getConfigDir());
            try {
                //JD: for some reason the decrypted passwd comes back sometimes with null chars
                // tacked on
                // MCR, was a problem with toBytes and toChar in SecurityUtils
                // return trimNullChars(toChars(decode(IOUtils.toByteArray(in))));
                return toChars(decode(IOUtils.toByteArray(in)));
            }
            finally {
                in.close();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void doSetMasterPassword(char[] passwd) throws Exception {
        OutputStream out = output(config.getURL(), getConfigDir());
        try {
            out.write(encode(passwd));
        }
        finally {
            out.close();
        }
    }

    File getConfigDir() throws IOException {
        return new File(getSecurityManager().getMasterPasswordProviderRoot(), getName());
    }

    byte[] encode(char[] passwd) {
       
        if (!config.isEncrypting()) {
            return toBytes(passwd);
        }

        //encrypt the password
        StandardPBEByteEncryptor encryptor = new StandardPBEByteEncryptor();

        char[] key = key();
        try {
            encryptor.setPasswordCharArray(key);
            return Base64.encodeBase64(encryptor.encrypt(toBytes(passwd)));
        }
        finally {
            scramble(key);
        }
    }

    byte[] decode(byte[] passwd) {
        if (!config.isEncrypting()) {
            return passwd;
        }

        //decrypt the password
        StandardPBEByteEncryptor encryptor = new StandardPBEByteEncryptor();
        char[] key = key();
        try {
            encryptor.setPasswordCharArray(key);
            return encryptor.decrypt(Base64.decodeBase64(passwd));
        }
        finally {
            scramble(key);
        }

    }

    char[] key() {
        //generate the key
        return SecurityUtils.permute(BASE, 32, PERM);
    }

    static OutputStream output(URL url, File configDir) throws IOException {
        //check for file url
        if ("file".equalsIgnoreCase(url.getProtocol())) {
            File f = DataUtilities.urlToFile(url);
            if (!f.isAbsolute()) {
                //make relative to config dir
                f = new File(configDir, f.getPath());
            }
            return new FileOutputStream(f);
        }
        else {
            URLConnection cx = url.openConnection();
            cx.setDoOutput(true);
            return cx.getOutputStream();
        }
    }

    static InputStream input(URL url, File configDir) throws IOException {
        //check for a file url
        if ("file".equalsIgnoreCase(url.getProtocol())) {
            File f = DataUtilities.urlToFile(url);
            //check if the file is relative
            if (!f.isAbsolute()) {
                //make it relative to the config directory for this password provider
                f = new File(configDir, f.getPath());
            }
            return new FileInputStream(f);
        }
        else {
            return url.openStream();
        }
    }

    public static class URLMasterPasswordProviderValidator extends SecurityConfigValidator {

        public URLMasterPasswordProviderValidator(GeoServerSecurityManager securityManager) {
            super(securityManager);
        }

        @Override
        public void validate(MasterPasswordProviderConfig config)
                throws SecurityConfigException {
            super.validate(config);
           
            URLMasterPasswordProviderConfig urlConfig = (URLMasterPasswordProviderConfig) config;
            URL url = urlConfig.getURL();

            if (url == null) {
                throw new URLMasterPasswordProviderException(URL_REQUIRED);
            }

            if (config.isReadOnly()) {
                //read-only, assure we can read from url
                try {
                    InputStream in = input(url,
                        new File(manager.getMasterPasswordProviderRoot(), config.getName()));
                    try {
                        in.read();
                    }
                    finally {
                        in.close();
                    }
                } catch (IOException ex) {
                    throw new URLMasterPasswordProviderException(URL_LOCATION_NOT_READABLE, url);
                }
            }
        }
    }

    public static class SecurityProvider extends GeoServerSecurityProvider {
        @Override
        public void configure(XStreamPersister xp) {
            super.configure(xp);
            xp.getXStream().alias("urlProvider", URLMasterPasswordProviderConfig.class);
        }
       
        @Override
        public Class<? extends MasterPasswordProvider> getMasterPasswordProviderClass() {
            return URLMasterPasswordProvider.class;
        }
        @Override
        public MasterPasswordProvider createMasterPasswordProvider(
            MasterPasswordProviderConfig config) throws IOException {
            return new URLMasterPasswordProvider();
        }

        @Override
        public SecurityConfigValidator createConfigurationValidator(
                GeoServerSecurityManager securityManager) {
            return new URLMasterPasswordProviderValidator(securityManager);
        }
    }

}
TOP

Related Classes of org.geoserver.security.password.URLMasterPasswordProvider$SecurityProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');