Skip to content
This repository has been archived by the owner on Jul 26, 2022. It is now read-only.

Commit

Permalink
Create a machine dependent private key
Browse files Browse the repository at this point in the history
  • Loading branch information
cr0 committed Sep 27, 2014
1 parent 59b7859 commit d606d7a
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 99 deletions.
160 changes: 80 additions & 80 deletions syncany-lib/src/main/java/org/syncany/config/UserConfig.java
@@ -1,6 +1,6 @@
/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com>
* 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
Expand All @@ -17,6 +17,7 @@
*/
package org.syncany.config;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
Expand All @@ -26,8 +27,6 @@
import java.util.List;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.syncany.config.to.DaemonConfigTO;
import org.syncany.config.to.FolderTO;
import org.syncany.config.to.UserConfigTO;
Expand All @@ -38,138 +37,138 @@

/**
* 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.
*
* 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.
*
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 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_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 String USER_KEYSTORE_FILE = "keystore.jks";
public static final int PRIVATE_KEY_LENGTH = 32;

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

private static File userTrustStoreFile;
private static KeyStore userTrustStore;
private static KeyStore userTrustStore;

private static File userKeyStoreFile;
private static KeyStore userKeyStore;
private static KeyStore userKeyStore;

private static boolean preventStandby;

static {
init();
}

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

public static File getUserConfigDir() {
public static File getUserConfigDir() {
return userConfigDir;
}

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 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.
// 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();
userPluginLibDir = new File(userConfigDir, USER_PLUGINS_LIB_DIR);

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);
loadAndInitUserConfigFile(userConfigFile);
}
else {
System.out.println("First launch, creating a secrect key (could take a sec)...");
writeExampleUserConfigFile(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();
}
Expand All @@ -178,102 +177,103 @@ private static void loadAndInitUserConfigFile(File userConfigFile) {
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 {
userConfigTO.setPrivateKey(CipherUtil.createMasterKey(CipherUtil.createRandomAlphabeticString(PRIVATE_KEY_LENGTH)));
UserConfigTO.save(userConfigTO, userConfigFile);
}
catch (Exception e) {
// Don't care!
}
}

// Daemon XML config methods

public static DaemonConfigTO createAndWriteDefaultDaemonConfig(File daemonConfigFile) {
public static DaemonConfigTO createAndWriteDefaultDaemonConfig(File daemonConfigFile) {
return createAndWriteDaemonConfig(daemonConfigFile, new ArrayList<FolderTO>());
}

public static DaemonConfigTO createAndWriteExampleDaemonConfig(File daemonConfigFile) {
File defaultFolder = new File(System.getProperty("user.home"), UserConfig.DEFAULT_FOLDER);
FolderTO defaultFolderTO = new FolderTO();
defaultFolderTO.setPath(defaultFolder.getAbsolutePath());
defaultFolderTO.setWatchOptions(new WatchOperationOptions());
return createAndWriteDaemonConfig(daemonConfigFile, Arrays.asList(new FolderTO[] { defaultFolderTO }));
public static DaemonConfigTO createAndWriteExampleDaemonConfig(File daemonConfigFile) {
File defaultFolder = new File(System.getProperty("user.home"), UserConfig.DEFAULT_FOLDER);

FolderTO defaultFolderTO = new FolderTO();
defaultFolderTO.setPath(defaultFolder.getAbsolutePath());
defaultFolderTO.setWatchOptions(new WatchOperationOptions());

return createAndWriteDaemonConfig(daemonConfigFile, Arrays.asList(new FolderTO[] { defaultFolderTO }));
}

public static DaemonConfigTO createAndWriteDaemonConfig(File configFile, List<FolderTO> folders) {
UserTO defaultUserTO = new UserTO();
public static DaemonConfigTO createAndWriteDaemonConfig(File configFile, List<FolderTO> folders) {
UserTO defaultUserTO = new UserTO();
defaultUserTO.setUsername(UserConfig.USER_ADMIN);
defaultUserTO.setPassword(CipherUtil.createRandomAlphabeticString(12));

ArrayList<UserTO> users = new ArrayList<>();
users.add(defaultUserTO);

DaemonConfigTO defaultDaemonConfigTO = new DaemonConfigTO();
defaultDaemonConfigTO.setFolders(new ArrayList<>(folders));
defaultDaemonConfigTO.setFolders(new ArrayList<>(folders));
defaultDaemonConfigTO.setUsers(users);

try {
DaemonConfigTO.save(defaultDaemonConfigTO, configFile);
}
catch (Exception e) {
// Don't care!
}

return defaultDaemonConfigTO;
}

// 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);
userKeyStore = initKeyStore(userKeyStoreFile);
}

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

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

trustStoreInputStream.close();
}
}
else {
keyStore.load(null, new char[0]); // Initialize empty store
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);
}
}
}
}
6 changes: 3 additions & 3 deletions syncany-lib/src/main/java/org/syncany/config/to/ConfigTO.java
Expand Up @@ -17,6 +17,9 @@
*/
package org.syncany.config.to;

import javax.crypto.spec.SecretKeySpec;
import java.io.File;

import org.simpleframework.xml.Element;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.Root;
Expand All @@ -29,9 +32,6 @@
import org.syncany.crypto.SaltedSecretKey;
import org.syncany.util.StringUtil;

import javax.crypto.spec.SecretKeySpec;
import java.io.File;

/**
* The config transfer object is used to create and load the local config
* file from/to XML. The config file contains local config settings of a client,
Expand Down

0 comments on commit d606d7a

Please sign in to comment.