Package org.syncany.config

Source Code of org.syncany.config.UserConfig

/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.syncany.config;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.util.Map;

import org.syncany.config.to.UserConfigTO;
import org.syncany.crypto.CipherUtil;
import org.syncany.crypto.SaltedSecretKey;
import org.syncany.util.EnvironmentUtil;

/**
* Represents the configuration parameters and application user directory
* of the currently logged in user, including system properties that will be
* set with every application start.
*
* @author Philipp C. Heckel <philipp.heckel@gmail.com>
*/
public class UserConfig {
  /*
   * Note:
   *    This class can't have any logging methods, because the init() method is called
   *    BEFORE the logging initialization. All errors must be printed to STDERR.
   */

  // Daemon-specific config
  public static final String DAEMON_FILE = "daemon.xml";
  public static final String DAEMON_EXAMPLE_FILE = "daemon-example.xml";
  public static final String DEFAULT_FOLDER = "Syncany";
  public static final String USER_ADMIN = "admin";
  public static final String USER_CLI = "CLI";

  // These fields are not final to enable a PluginOperationTest
  private static File USER_APP_DIR_WINDOWS = new File(System.getenv("APPDATA") + "\\Syncany");
  private static File USER_APP_DIR_UNIX_LIKE = new File(System.getProperty("user.home") + "/.config/syncany");
  private static final String USER_LOG_DIR = "logs";
  private static final String USER_PLUGINS_LIB_DIR = "plugins/lib";
  private static final String USER_PLUGINS_USERDATA_DIR_FORMAT = "plugins/userdata/%s";
  private static final String USER_CONFIG_FILE = "userconfig.xml";
  private static final String USER_TRUSTSTORE_FILE = "truststore.jks";
  private static final String USER_KEYSTORE_FILE = "keystore.jks";
  private static final int USER_CONFIG_ENCRYPTION_KEY_LENGTH = 32;

  private static File userConfigDir;
  private static File userLogDir;
  private static File userPluginLibDir;
  private static File userConfigFile;

  private static File userTrustStoreFile;
  private static KeyStore userTrustStore;

  private static File userKeyStoreFile;
  private static KeyStore userKeyStore;

  private static boolean preventStandby;
  private static SaltedSecretKey configEncryptionKey;

  static {
    init();
  }

  public static void init() {
    if (userConfigDir == null) {
      initUserAppDirs();
      initUserConfig();
      initUserTrustStore();
      initUserKeyStore();
    }
  }

  public static File getUserConfigDir() {
    return userConfigDir;
  }

  public static File getUserLogDir() {
    return userLogDir;
  }

  public static File getUserPluginLibDir() {
    return userPluginLibDir;
  }

  public static File getUserPluginsUserdataDir(String pluginId) {
    File pluginConfigDir = new File(userConfigDir, String.format(USER_PLUGINS_USERDATA_DIR_FORMAT, pluginId));
    pluginConfigDir.mkdirs();

    return pluginConfigDir;
  }

  public static File getUserConfigFile() {
    return userConfigFile;
  }

  public static boolean preventStandbyEnabled() {
    return preventStandby;
  }

  public static SaltedSecretKey getConfigEncryptionKey() {
    return configEncryptionKey;
  }

  public static KeyStore getUserTrustStore() {
    // Note: This method might not be used by the main project modules,
    // but it might be used by plugins. Do not remove unless you are
    // sure that it is not needed.

    return userTrustStore;
  }

  public static KeyStore getUserKeyStore() {
    return userKeyStore;
  }

  public static void storeTrustStore() {
    storeKeyStore(userTrustStore, userTrustStoreFile);
  }

  public static void storeUserKeyStore() {
    storeKeyStore(userKeyStore, userKeyStoreFile);
  }

  public static SSLContext createUserSSLContext() throws Exception {
    return CipherUtil.createSSLContext(userKeyStore, userTrustStore);
  }

  // General initialization methods

  private static void initUserAppDirs() {
    userConfigDir = (EnvironmentUtil.isWindows()) ? USER_APP_DIR_WINDOWS : USER_APP_DIR_UNIX_LIKE;
    userConfigDir.mkdirs();

    userLogDir = new File(userConfigDir, USER_LOG_DIR);
    userLogDir.mkdirs();

    userPluginLibDir = new File(userConfigDir, USER_PLUGINS_LIB_DIR);
    userPluginLibDir.mkdirs();
  }

  private static void initUserConfig() {
    userConfigFile = new File(userConfigDir, USER_CONFIG_FILE);

    if (userConfigFile.exists()) {
      loadAndInitUserConfigFile(userConfigFile);
    }
    else {
      writeExampleUserConfigFile(userConfigFile);
      loadAndInitUserConfigFile(userConfigFile);
    }
  }

  private static void loadAndInitUserConfigFile(File userConfigFile) {
    try {
      UserConfigTO userConfigTO = UserConfigTO.load(userConfigFile);

      // System properties
      for (Map.Entry<String, String> systemProperty : userConfigTO.getSystemProperties().entrySet()) {
        System.setProperty(systemProperty.getKey(), systemProperty.getValue());
      }

      // Other options
      preventStandby = userConfigTO.preventStandbyEnabled();
      configEncryptionKey = userConfigTO.getConfigEncryptionKey();
    }
    catch (ConfigException e) {
      System.err.println("ERROR: " + e.getMessage());
      System.err.println("       Ignoring user config file!");
      System.err.println();
    }
  }

  private static void writeExampleUserConfigFile(File userConfigFile) {
    UserConfigTO userConfigTO = new UserConfigTO();

    userConfigTO.getSystemProperties().put("example.property", "This is a demo property. You can delete it.");
    userConfigTO.getSystemProperties().put("syncany.rocks", "Yes, it does!");

    try {
      System.out.println("First launch, creating a secret key (could take a sec)...");
      SaltedSecretKey configEncryptionKey = CipherUtil.createMasterKey(CipherUtil.createRandomAlphabeticString(USER_CONFIG_ENCRYPTION_KEY_LENGTH));

      userConfigTO.setConfigEncryptionKey(configEncryptionKey);
      userConfigTO.save(userConfigFile);
    }
    catch (Exception e) {
      // Don't care!
    }
  }

  // Key store / Trust store methods

  private static void initUserTrustStore() {
    userTrustStoreFile = new File(userConfigDir, USER_TRUSTSTORE_FILE);
    userTrustStore = initKeyStore(userTrustStoreFile);
  }

  private static void initUserKeyStore() {
    userKeyStoreFile = new File(userConfigDir, USER_KEYSTORE_FILE);
    userKeyStore = initKeyStore(userKeyStoreFile);
  }

  private static KeyStore initKeyStore(File keyStoreFile) {
    try {
      KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());

      if (keyStoreFile.exists()) {
        FileInputStream trustStoreInputStream = new FileInputStream(keyStoreFile);
        keyStore.load(trustStoreInputStream, new char[0]);

        trustStoreInputStream.close();
      }
      else {
        keyStore.load(null, new char[0]); // Initialize empty store
      }

      return keyStore;
    }
    catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  private static void storeKeyStore(KeyStore keyStore, File keyStoreFile) {
    try {
      FileOutputStream trustStoreOutputStream = new FileOutputStream(keyStoreFile);
      keyStore.store(trustStoreOutputStream, new char[0]);

      trustStoreOutputStream.close();
    }
    catch (Exception e) {
      throw new RuntimeException("Cannot store key/truststore to file " + keyStoreFile, e);
    }
  }
}
TOP

Related Classes of org.syncany.config.UserConfig

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.