<commit_before>/*
*  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.ciphertool;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * This is a command-line tool for encrypt password of configuration file. This class reads password
 * from command line, encrypt and then write encrypted values to cipher-text.properties file
 */
public class CipherTool {

    private static Map<String, String> aliasXpathMap = new HashMap<String, String>();
    private static Map<String, String> configFileXpathMap = new HashMap<String, String>();
    private static Map<String, String> aliasPasswordMap = new HashMap<String, String>();
    private static String carbonHome;
    private static Cipher cipher;

    public static void main(String[] args) {

        init(args);
        cipher = initCipher();
        if (System.getProperty("configure") != null && System.getProperty("configure").equals("true")) {
            loadXpathValuesAndPasswordDetails();
            writeSecureVaultConfigTokens();
            createEncryptedValues();
            writeEncryptedValues();
            writeConfigurations();
        } else if (System.getProperty("change") != null && System.getProperty("change").equals("true")) {
            changePassword();
        } else {
            createEncryptedValue();
        }
    }

    /**
     * init the mode of operation of cipher tool using command line argument
     *
     * @param args command line arguments
     */
    private static void init(String[] args) {

        String osName = System.getProperty("os.name");
        File file;
        if (osName.toLowerCase().indexOf("win") == -1) {
            file = new File("." + File.separator + ".." + File.separator);
        } else {
            file = new File("." + File.separator);
        }

        try {
            System.setProperty("carbon.home", file.getCanonicalFile().toString());
        } catch (IOException e) {
            handleException("IOError while calculating CARBON_HOME directory location ", e);
        }

        for (String arg : args) {
            if (arg.equals("-help")) {
                printHelp();
                System.exit(0);
            } else if (arg.equals("-Dchange")) {
                String property = arg.substring(2);
                System.setProperty(property, "true");
            } else if (arg.equals("-Dconfigure")) {
                String property = arg.substring(2);
                System.setProperty(property, "true");
            }
        }


        carbonHome = System.getProperty("carbon.home");
        if (carbonHome == null || carbonHome.equals("")) {
            System.out.println("\nCARBON_HOME is not properly set. Please Enter CARBON_HOME again : ");
            BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            try {
                carbonHome = input.readLine();
            } catch (IOException e) {
                handleException("IOError reading command line inputs  ", e);
            } finally {
                try {
                    input.close();
                } catch (IOException e) {
                    System.err.println("Error while closing input stream");
                }
            }
        }
    }

    /**
     * print the help on command line
     */
    private static void printHelp() {

        System.out.println("\n---------Cipher Tool Help---------\n");
        System.out.println("By default, CipherTool can be used for creating encrypted value for given plaint text\n");
        System.out.println("Options :\n");

        System.out.println("\t-Dconfigure\t\t This option would allow user to secure plain text passwords in carbon configuration files." +
                           " CipherTool replace all " +
                           "the password listed in cipher-text.properties file with encrypted values " +
                           "and modify related password elements in the configuration files with secret alias names. " +
                           "Also secret-conf.properties file is modified with the default configuration data");

        System.out.println("\t-Dchange\t\t This option would allow user to change the specific password " +
                           "which has been secured\n");
    }

    /**
     * init the Cipher for encryption using the primary key store of carbon server
     *
     * @return cipher
     */
    private static Cipher initCipher() {

        String keyStoreFile = null;
        String keyType = null;
        String aliasName = null;
        String password = <PASSWORD>;
        String provider = null;
        Cipher cipher = null;

        keyStoreFile = getPrimaryKeyStoreData(CipherToolConstants.PrimaryKeyStore
                                                      .PRIMARY_KEY_LOCATION);
        keyStoreFile = carbonHome + keyStoreFile.substring((keyStoreFile
                                                                    .indexOf('}')) + 1);

        File keyStore = new File(keyStoreFile);

        if (!keyStore.exists()) {
            handleException("Primary Key Store Can not be found at Default location");
        }
        keyType = getPrimaryKeyStoreData(CipherToolConstants.PrimaryKeyStore
                                                 .PRIMARY_KEY_TYPE);
        aliasName = getPrimaryKeyStoreData(CipherToolConstants.PrimaryKeyStore
                                                   .PRIMARY_KEY_ALIAS);
        password = <PASSWORD>();

        try {
            KeyStore primaryKeyStore = getKeyStore(keyStoreFile, password, keyType, provider);
            java.security.cert.Certificate certs = primaryKeyStore.getCertificate(aliasName);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, certs);
        } catch (InvalidKeyException e) {
            handleException("Error initializing Cipher ", e);
        } catch (NoSuchAlgorithmException e) {
            handleException("Error initializing Cipher ", e);
        } catch (KeyStoreException e) {
            handleException("Error initializing Cipher ", e);
        } catch (NoSuchPaddingException e) {
            handleException("Error initializing Cipher ", e);
        }

        System.out.println("\nPrimary KeyStore of Carbon Server is initialized Successfully\n");

        return cipher;
    }

    /**
     * encrypt the plain text password
     *
     * @param cipher        init cipher
     * @param plainTextPass plain text password
     * @return encrypted password<commit_msg>Fix for CARBON-14819 : added Jayanga's fix from carbon-commons repo<commit_after>/*
*  Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.wso2.ciphertool;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * This is a command-line tool for encrypt password of configuration file. This class reads password
 * from command line, encrypt and then write encrypted values to cipher-text.properties file
 */
public class CipherTool {

    private static Map<String, String> aliasXpathMap = new HashMap<String, String>();
    private static Map<String, String> configFileXpathMap = new HashMap<String, String>();
    private static Map<String, String> aliasPasswordMap = new HashMap<String, String>();
    private static String carbonHome;
    private static Cipher cipher;

    public static void main(String[] args) {

        init(args);
        cipher = initCipher();
        if (System.getProperty("configure") != null && System.getProperty("configure").equals("true")) {
            loadXpathValuesAndPasswordDetails();
            writeSecureVaultConfigTokens();
            createEncryptedValues();
            writeEncryptedValues();
            writeConfigurations();
        } else if (System.getProperty("change") != null && System.getProperty("change").equals("true")) {
            changePassword();
        } else {
            createEncryptedValue();
        }
    }

    /**
     * init the mode of operation of cipher tool using command line argument
     *
     * @param args command line arguments
     */
    private static void init(String[] args) {

        String osName = System.getProperty("os.name");
        File file;
        if (osName.toLowerCase().indexOf("win") == -1) {
            file = new File("." + File.separator + ".." + File.separator);
        } else {
            file = new File("." + File.separator);
        }

        try {
            System.setProperty("carbon.home", file.getCanonicalFile().toString());
        } catch (IOException e) {
            handleException("IOError while calculating CARBON_HOME directory location ", e);
        }

        for (String arg : args) {
            if (arg.equals("-help")) {
                printHelp();
                System.exit(0);
            } else if (arg.equals("-Dchange")) {
                String property = arg.substring(2);
                System.setProperty(property, "true");
            } else if (arg.equals("-Dconfigure")) {
                String property = arg.substring(2);
                System.setProperty(property, "true");
            } else if (arg.startsWith("-Dpassword=")) {
                String property = arg.substring(11);
                System.setProperty("password", property);
            }
        }


        carbonHome = System.getProperty("carbon.home");
        if (carbonHome == null || carbonHome.equals("")) {
            System.out.println("\nCARBON_HOME is not properly set. Please Enter CARBON_HOME again : ");
            BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            try {
                carbonHome = input.readLine();
            } catch (IOException e) {
                handleException("IOError reading command line inputs  ", e);
            } finally {
                try {
                    input.close();
                } catch (IOException e) {
                    System.err.println("Error while closing input stream");
                }
            }
        }
    }

    /**
     * print the help on command line
     */
    private static void printHelp() {

        System.out.println("\n---------Cipher Tool Help---------\n");
        System.out.println("By default, CipherTool can be used for creating encrypted value for given plaint text\n");
        System.out.println("Options :\n");

        System.out.println("\t-Dconfigure\t\t This option would allow user to secure plain text passwords in carbon configuration files." +
                           " CipherTool replace all " +
                           "the password listed in cipher-text.properties file with encrypted values " +
                           "and modify related password elements in the configuration files with secret alias names. " +
                           "Also secret-conf.properties file is modified with the default configuration data");

        System.out.println("\t-Dchange\t\t This option would allow user to change the specific password " +
                           "which has been secured\n");
        System.out.println(
                "\t-Dpassword=<password>\t This option would allow user to provide the password as a command line " +
                "argument. NOTE: Providing the password in command line arguments list is not recommended.\n");
    }

    /**
     * init the Cipher for encryption using the primary key store of carbon server
     *
     * @return cipher
     */
    private static Cipher initCipher() {

        String keyStoreFile = null;
        String keyType = null;
        String aliasName = null;
        String password = <PASSWORD>;
        String provider = null;
        Cipher cipher = null;

        keyStoreFile = getPrimaryKeyStoreData(CipherToolConstants.PrimaryKeyStore
                                                      .PRIMARY_KEY_LOCATION);
        keyStoreFile = carbonHome + keyStoreFile.substring((keyStoreFile
                                                                    .indexOf('}')) + 1);

        File keyStore = new File(keyStoreFile);

        if (!keyStore.exists()) {
            handleException("Primary Key Store Can not be found at Default location");
        }
        keyType = getPrimaryKeyStoreData(CipherToolConstants.PrimaryKeyStore
                                                 .PRIMARY_KEY_TYPE);
        aliasName = getPrimaryKeyStoreData(CipherToolConstants.PrimaryKeyStore
                                                   .PRIMARY_KEY_ALIAS);
        if (System.getProperty("password") != null && System.getProperty("password").length() > 0) {
            password = System.getProperty("password");
        } else {
            password = <PASSWORD>();
        }

        try {
            KeyStore primaryKeyStore = getKeyStore(keyStoreFile, password, keyType, provider);
            java.security.cert.Certificate certs = primaryKeyStore.getCertificate(aliasName);
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, certs);
        } catch (InvalidKeyException e) {
            handleException("Error initializing Cipher ", e);
        } catch (NoSuchAlgorithmException e) {
            handleException("Error initializing Cipher ", e);
        } catch (KeyStoreException e) {
            handleException("Error initializing Cipher ", e);
        } catch (NoSuchPaddingException e) {
            handleException("Error initializing Cipher ", e);
        }

        System.out.println("\nPrimary KeyStore of Carbon Server is initialized Successfully\n");

        return cipher;
    }

    /**
     * encrypt the plain text password
     *
     * @param cipher        init cipher
     * @param plainTextPass plain text password
     * @return encrypted password
{'fraction_non_alphanumeric': 0.09825815096025012, 'fraction_numerical': 0.0033497096918267085, 'mean_word_length': 2.4191639625882804, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 28}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1454656', 'n_tokens_mistral': 4567, 'n_tokens_neox': 4419, 'n_words': 1289}