/* * Part of the CCNx Java Library. * * Copyright (C) 2008-2012 Palo Alto Research Center, Inc. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. * This library 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 * Lesser General Public License for more details. You should have received * a copy of the GNU Lesser General Public License along with this library; * if not, write to the Free Software Foundation, Inc., 51 Franklin Street, * Fifth Floor, Boston, MA 02110-1301 USA. */ package org.ccnx.ccn.config; import org.ccnx.ccn.impl.support.Log; import org.ccnx.ccn.protocol.Component; import org.ccnx.ccn.protocol.ContentName; import org.ccnx.ccn.protocol.MalformedContentNameStringException; /** * A class encapsulating user-specific configuration information and default variable values. * Eventually this will be handled more sensibly by a user configuration file. This is likely * to change extensively as the user model evolves. */ public class UserConfiguration { /** * Our eventual configuration file location. */ protected static final String DEFAULT_CONFIGURATION_FILE_NAME = "ccnx_config.bin"; protected static final String DEFAULT_KEYSTORE_FILE_NAME = ".ccnx_keystore"; protected static final String DEFAULT_KEY_CACHE_FILE_NAME = "secure_key_cache.bin"; protected static final String KEY_DIRECTORY = "keyCache"; protected static final String ADDRESSBOOK_FILE_NAME = "ccnx_addressbook.xml"; protected static final String CCNX_DEFAULT_NAMESPACE = "/ccnx.org"; protected static final Component DEFAULT_USER_NAMESPACE_MARKER = new Component("Users"); protected static final Component DEFAULT_KEY_NAMESPACE_MARKER = new Component("Keys"); /** * Currently very cheezy keystore handling. Will improve when we can actually use * java 1.6-only features. */ protected static final String DEFAULT_KEYSTORE_PASSWORD = "Th1s1sn0t8g00dp8ssw0rd."; protected static final int DEFAULT_KEY_LENGTH = 1024; protected static final String DEFAULT_KEY_ALG = "RSA"; /** * Change to all lower case. Most OSes turn out to be non case-sensitive * for this, but not all. */ protected static final String DEFAULT_KEY_ALIAS = "ccnxuser"; protected static final String DEFAULT_KEYSTORE_TYPE = "PKCS12"; // "JCEKS"; // want JCEKS, but don't want to force keystore regeneration yet /** * Default prefix to use, e.g. for user information if not overridden by local stuff. */ protected static final String CCNX_DEFAULT_NAMESPACE_PROPERTY = "org.ccnx.config.CCNxNamespace"; protected static final String CCNX_DEFAULT_NAMESPACE_ENVIRONMENT_VARIABLE = "CCNX_NAMESPACE"; /** * Default value of user configuration directory name -- this is not * the full path, merely the directory name itself; by default we interpret * the directory name as <user_home>/.ccnx. * @return */ protected static final String CCNX_DEFAULT_USER_CONFIG_DIR_NAME = ".ccnx"; /** * Directory (subdirectory of User.home) where all user metadata is kept. * Property/environment variable to set the user configuration directory (full path). */ protected static final String CCNX_USER_CONFIG_DIR_PROPERTY = "org.ccnx.config.CCNxDir"; protected static final String CCNX_USER_CONFIG_DIR_ENVIRONMENT_VARIABLE = "CCNX_DIR"; /** * User friendly name, by default user.name Java property */ protected static final String CCNX_USER_NAME_PROPERTY = "org.ccnx.config.UserName"; protected static final String CCNX_USER_NAME_ENVIRONMENT_VARIABLE = "CCNX_USER_NAME"; /** * User namespace, by default ccnxNamespace()/<DEFAULT_USER_NAMESPACE_MARKER>/userName(); * the user namespace prefix will be set to the value given here -- so the user * namespace will be userNamespacePrefix()/<DEFAULT_USER_NAMESPACE_MARKER>/<user name> * for either a user name we are given or our default user name. */ protected static final String CCNX_USER_NAMESPACE_PREFIX_PROPERTY = "org.ccnx.config.UserNamespacePrefix"; protected static final String CCNX_USER_NAMESPACE_PREFIX_ENVIRONMENT_VARIABLE = "CCNX_USER_NAMESPACE_PREFIX"; /** * User namespace, by default ccnxNamespace()/<DEFAULT_USER_NAMESPACE_MARKER>/userName(); * the user namespace will be set to the value given here -- we don't add the * user namespace marker or userName(). */ protected static final String CCNX_USER_NAMESPACE_PROPERTY = "org.ccnx.config.UserNamespace"; protected static final String CCNX_USER_NAMESPACE_ENVIRONMENT_VARIABLE = "CCNX_USER_NAMESPACE"; /** * Property and variable to set the keystore file name to something other than the default .ccnx_keystore * (the directory is handled separately, as the CCNX_USER_CONFIG_DIRECTORY...) */ protected static final String CCNX_KEYSTORE_FILENAME_PROPERTY = "org.ccnx.config.KeystoreFilename"; protected static final String CCNX_KEYSTORE_FILENAME_ENVIRONMENT_VARIABLE = "CCNX_KEYSTORE_FILENAME"; /** * Property and variable to set the keystore password to something other than the default; * can also be overridden in calls to the key manager constructor. */ protected static final String CCNX_KEYSTORE_PASSWORD_PROPERTY = "org.ccnx.config.KeystorePassword"; protected static final String CCNX_KEYSTORE_PASSWORD_ENVIRONMENT_VARIABLE = "CCNX_KEYSTORE_PASSWORD"; /** * Property and variable to set the keystore file name to something other than the default ccnx_user.conf * (the directory is handled separately, as the CCNX_USER_CONFIG_DIRECTORY...) */ protected static final String CCNX_CONFIGURATION_FILENAME_PROPERTY = "org.ccnx.config.ConfigurationFilename"; protected static final String CCNX_CONFIGURATION_FILENAME_ENVIRONMENT_VARIABLE = "CCNX_CONFIG_FILENAME"; /** * Property and variable to set the key locator to use for the default key. Need something * more complicated, probably read from a configuration file. But this will get us started. * Parse this as "key locator for the default key", not "the default value for the key locator". */ protected static final String CCNX_DEFAULT_KEY_LOCATOR_PROPERTY = "org.ccnx.config.DefaultKeyLocator"; protected static final String CCNX_DEFAULT_KEY_LOCATOR_ENVIRONMENT_VARIABLE = "CCNX_DEFAULT_KEY_LOCATOR"; /** * Property and variable to control whether we publish keys or not. */ protected static final String CCNX_PUBLISH_KEYS_PROPERTY = "org.ccnx.config.PublishKeys"; protected static final String CCNX_PUBLISH_KEYS_ENVIRONMENT_VARIABLE = "CCNX_PUBLISH_KEYS"; /** * Property and variable to control whether we load/can set user's key-related configuration * (key locators, key cache, etc). Key cache saving and loading is additionally handled * below -- both this variable and that one need to be set to true to automatically save * and load the key cache; if CCNX_SAVE_KEY_CACHE_CONFIGURATION_PROPERTY is true but this * CCNX_USE_KEY_CONFIGURATION_PROPERTY is false, then users can manually save and load the * key cache, but it will not be handled automatically on startup. * */ protected static final String CCNX_USE_KEY_CONFIGURATION_PROPERTY = "org.ccnx.config.UseKeyConfiguration"; protected static final String CCNX_USE_KEY_CONFIGURATION_ENVIRONMENT_VARIABLE = "CCNX_USE_KEY_CONFIGURATION"; /** * Variable to control whether key cache is saved on request and reloaded on startup. * See CCNX_USE_KEY_CONFIGURATION_PROPERTY. */ protected static final String CCNX_SAVE_KEY_CACHE_PROPERTY = "org.ccnx.config.SaveKeyCache"; protected static final String CCNX_SAVE_KEY_CACHE_ENVIRONMENT_VARIABLE = "CCNX_SAVE_KEY_CACHE"; protected static final String DEFAULT_SAVE_KEY_CACHE_SETTING = SystemConfiguration.STRING_FALSE; // default to off for now. /** * Value of CCN directory. */ protected static String _userConfigurationDir; /** * User name. By default value of user.name property. */ protected static String _userName; /** * CCNx (control) prefix. */ protected static ContentName _defaultNamespace; /** * User prefix (e.g. for keys). By default, the user namespace prefix together with user information. */ protected static ContentName _userNamespace; /** * User namespace prefix (e.g. for keys). By default, the CCNX prefix */ protected static ContentName _userNamespacePrefix; /** * Keystore file name. This is the name of the actual file, without the directory. */ protected static String _keystoreFileName; /** * Keystore password, if not default. Yes we know this is bad; it's * on our list of things to improve. */ protected static String _keystorePassword; /** * Configuration file name. This is the name of the actual file, without the directory. */ protected static String _configurationFileName; /** * Do we publish keys by default? */ protected static Boolean _publishKeys; /** * Do we load stored state about cached secret keys, key locators (credentials) to * use, and so on? Setting this to false can prevent interactions between unit tests * and the user's internal configuration data. If false, we also prevent writing * to configuration state. */ protected static Boolean _useKeyConfiguration; /** * Do we automatically save and load the key cache as part of the configuration data? * (Automatic loading of key cache happens only if _useKeyConfiguration is also true.) */ protected static Boolean _saveAndLoadKeyCache; protected static final String USER_DIR = System.getProperty("user.home"); public static String FILE_SEP = System.getProperty("file.separator"); public static void setUserName(String name) { _userName = name; } public static String userName() { if (null == _userName) { _userName = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_USER_NAME_PROPERTY, CCNX_USER_NAME_ENVIRONMENT_VARIABLE, System.getProperty("user.name")); } return _userName; } public static void setUserConfigurationDirectory(String path) { _userConfigurationDir = path; } public static String userConfigurationDirectory() { if (null == _userConfigurationDir) { _userConfigurationDir = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_USER_CONFIG_DIR_PROPERTY, CCNX_USER_CONFIG_DIR_ENVIRONMENT_VARIABLE, USER_DIR + FILE_SEP + CCNX_DEFAULT_USER_CONFIG_DIR_NAME); if (null == _userConfigurationDir) _userConfigurationDir = USER_DIR + FILE_SEP + CCNX_DEFAULT_USER_CONFIG_DIR_NAME; } return _userConfigurationDir; } public static void setDefaultNamespacePrefix(String defaultNamespacePrefix) throws MalformedContentNameStringException { _defaultNamespace = (null == defaultNamespacePrefix) ? null : ContentName.fromNative(defaultNamespacePrefix); } public static ContentName defaultNamespace() { if (null == _defaultNamespace) { String defaultNamespaceString = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_DEFAULT_NAMESPACE_PROPERTY, CCNX_DEFAULT_NAMESPACE_ENVIRONMENT_VARIABLE, CCNX_DEFAULT_NAMESPACE); try { _defaultNamespace = ContentName.fromNative(defaultNamespaceString); } catch (MalformedContentNameStringException e) { Log.severe("Attempt to configure invalid default CCNx namespace: {0}!", defaultNamespaceString); throw new RuntimeException("Attempt to configure invalid default CCNx namespace: " + defaultNamespaceString + "!"); } } return _defaultNamespace; } public static void setUserNamespace(String userNamespace) throws MalformedContentNameStringException { _userNamespace = (null == userNamespace) ? null : ContentName.fromNative(userNamespace); } public static ContentName userNamespace() { if (null == _userNamespace) { String userNamespaceString = SystemConfiguration.retrievePropertyOrEnvironmentVariable( CCNX_USER_NAMESPACE_PROPERTY, CCNX_USER_NAMESPACE_ENVIRONMENT_VARIABLE, null); if (null != userNamespaceString) { try { _userNamespace = ContentName.fromNative(userNamespaceString); } catch (MalformedContentNameStringException e) { Log.severe("Attempt to configure invalid default user namespace: {0}!", userNamespaceString); throw new RuntimeException("Attempt to configure invalid default user namespace: " + userNamespaceString + "!"); } } else { _userNamespace = userNamespace(userName()); } } return _userNamespace; } /** * User the userNamespacePrefix() to generate a namespace for a particular user * @param userName * @return */ public static ContentName userNamespace(String userName) { if (null == userName) { userName = userName(); } return new ContentName(userNamespacePrefix(), userName); } public static void setUserNamespacePrefix(String userNamespacePrefix) throws MalformedContentNameStringException { _userNamespacePrefix = (null == userNamespacePrefix) ? null : ContentName.fromNative(userNamespacePrefix); } public static ContentName userNamespacePrefix() { if (null == _userNamespacePrefix) { String userNamespacePrefixString = SystemConfiguration.retrievePropertyOrEnvironmentVariable( CCNX_USER_NAMESPACE_PREFIX_PROPERTY, CCNX_USER_NAMESPACE_PREFIX_ENVIRONMENT_VARIABLE, null); if (null != userNamespacePrefixString) { try { _userNamespacePrefix = ContentName.fromNative(userNamespacePrefixString); } catch (MalformedContentNameStringException e) { Log.severe("Attempt to configure invalid default user namespace prefix: {0}!", userNamespacePrefixString); throw new RuntimeException("Attempt to configure invalid default user namespace prefix: " + userNamespacePrefixString + "!"); } } else { _userNamespacePrefix = new ContentName(defaultNamespace(), DEFAULT_USER_NAMESPACE_MARKER); } } return _userNamespacePrefix; } public static void setKeystoreFileName(String fileName) { _keystoreFileName = fileName; } public static String keystoreFileName() { if (null == _keystoreFileName) { _keystoreFileName = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_KEYSTORE_FILENAME_PROPERTY, CCNX_KEYSTORE_FILENAME_ENVIRONMENT_VARIABLE, DEFAULT_KEYSTORE_FILE_NAME); } return _keystoreFileName; } public static String configurationFileName() { if (null == _configurationFileName) { _configurationFileName = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_CONFIGURATION_FILENAME_PROPERTY, CCNX_CONFIGURATION_FILENAME_ENVIRONMENT_VARIABLE, DEFAULT_CONFIGURATION_FILE_NAME); } return _configurationFileName; } public static String keyCacheFileName() { return DEFAULT_KEY_CACHE_FILE_NAME; } public static void setKeystorePassword(String password) { _keystorePassword = password; } public static String keystorePassword() { if (null == _keystorePassword) { _keystorePassword = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_KEYSTORE_PASSWORD_PROPERTY, CCNX_KEYSTORE_PASSWORD_ENVIRONMENT_VARIABLE, DEFAULT_KEYSTORE_PASSWORD); } return _keystorePassword; } /** * Don't provide a mechanism to set this here; this is actually configured on the KeyManagers. * Just provide a means for them to pull in property/environment/configuration file parameters. * @return */ public static String defaultKeyLocator() { return SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_DEFAULT_KEY_LOCATOR_PROPERTY, CCNX_DEFAULT_KEY_LOCATOR_ENVIRONMENT_VARIABLE, null); } public static boolean useKeyConfiguration() { if (null == _useKeyConfiguration) { String strPublish = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_USE_KEY_CONFIGURATION_PROPERTY, CCNX_USE_KEY_CONFIGURATION_ENVIRONMENT_VARIABLE, SystemConfiguration.STRING_TRUE); _useKeyConfiguration = strPublish.equalsIgnoreCase(SystemConfiguration.STRING_TRUE); } return _useKeyConfiguration; } /** * Do we save the key cache when asked, and retrieve it on startup? * @return */ public static boolean saveAndLoadKeyCache() { if (null == _saveAndLoadKeyCache) { // Set default to be false, until we have turned on key cache encryption String strPublish = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_SAVE_KEY_CACHE_PROPERTY, CCNX_SAVE_KEY_CACHE_ENVIRONMENT_VARIABLE, DEFAULT_SAVE_KEY_CACHE_SETTING); _saveAndLoadKeyCache = strPublish.equalsIgnoreCase(SystemConfiguration.STRING_TRUE); } return _saveAndLoadKeyCache; } public static void setSaveAndLoadKeyCache(boolean saveKeyCache) { _saveAndLoadKeyCache = saveKeyCache; } public static boolean publishKeys() { if (null == _publishKeys) { String strPublish = SystemConfiguration.retrievePropertyOrEnvironmentVariable(CCNX_PUBLISH_KEYS_PROPERTY, CCNX_PUBLISH_KEYS_ENVIRONMENT_VARIABLE, SystemConfiguration.STRING_TRUE); _publishKeys = strPublish.equalsIgnoreCase(SystemConfiguration.STRING_TRUE); } return _publishKeys; } public static void setPublishKeys(boolean publish) { _publishKeys = publish; } public static String keyRepositoryDirectory() { return userConfigurationDirectory() + FILE_SEP + KEY_DIRECTORY; } public static String addressBookFileName() { return userConfigurationDirectory() + FILE_SEP + ADDRESSBOOK_FILE_NAME; } public static String defaultKeyAlgorithm() { return DEFAULT_KEY_ALG; } public static String defaultKeyAlias() { return DEFAULT_KEY_ALIAS; } public static String defaultKeystoreType() { return DEFAULT_KEYSTORE_TYPE; } public static int defaultKeyLength() { return DEFAULT_KEY_LENGTH; } public static Component defaultKeyNamespaceMarker() { return DEFAULT_KEY_NAMESPACE_MARKER; } }