aboutsummaryrefslogtreecommitdiffstats
path: root/SoftHSMv2/src/lib/common/SimpleConfigLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SoftHSMv2/src/lib/common/SimpleConfigLoader.cpp')
-rw-r--r--SoftHSMv2/src/lib/common/SimpleConfigLoader.cpp352
1 files changed, 352 insertions, 0 deletions
diff --git a/SoftHSMv2/src/lib/common/SimpleConfigLoader.cpp b/SoftHSMv2/src/lib/common/SimpleConfigLoader.cpp
new file mode 100644
index 0000000..3212d82
--- /dev/null
+++ b/SoftHSMv2/src/lib/common/SimpleConfigLoader.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2010 .SE, The Internet Infrastructure Foundation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*****************************************************************************
+ SimpleConfigLoader.cpp
+
+ Loads the configuration from the configuration file.
+ *****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <algorithm>
+#include <limits.h>
+#ifdef _WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+#endif
+#include "config.h"
+#if defined(HAVE_GETPWUID_R)
+# include <sys/types.h>
+# include <pwd.h>
+#endif
+#include "SimpleConfigLoader.h"
+#include "log.h"
+#include "Configuration.h"
+
+// Initialise the one-and-only instance
+#ifdef HAVE_CXX11
+std::unique_ptr<SimpleConfigLoader> SimpleConfigLoader::instance(nullptr);
+#else
+std::auto_ptr<SimpleConfigLoader> SimpleConfigLoader::instance(NULL);
+#endif
+
+// Return the one-and-only instance
+SimpleConfigLoader* SimpleConfigLoader::i()
+{
+ if (instance.get() == NULL)
+ {
+ instance.reset(new SimpleConfigLoader());
+ }
+
+ return instance.get();
+}
+
+// Constructor
+SimpleConfigLoader::SimpleConfigLoader()
+{
+}
+
+// Load the configuration
+bool SimpleConfigLoader::loadConfiguration()
+{
+ char* configPath = getConfigPath();
+
+ FILE* fp = fopen(configPath,"r");
+
+ if (fp == NULL)
+ {
+ ERROR_MSG("Could not open the config file: %s", configPath);
+ free(configPath);
+ return false;
+ }
+ free(configPath);
+
+ char fileBuf[1024];
+
+ // Format in config file
+ //
+ // <name> = <value>
+ // # Line is ignored
+
+ size_t line = 0;
+ while (fgets(fileBuf, sizeof(fileBuf), fp) != NULL)
+ {
+ line++;
+
+ // End the string at the first comment or newline
+ fileBuf[strcspn(fileBuf, "#\n\r")] = '\0';
+
+ // Skip empty lines
+ if (fileBuf[0] == '\0')
+ {
+ continue;
+ }
+
+ // Get the first part of the line
+ char* name = strtok(fileBuf, "=");
+ if (name == NULL)
+ {
+ WARNING_MSG("Bad format on line %lu, skip", (unsigned long)line);
+ continue;
+ }
+
+ // Trim the name
+ char* trimmedName = trimString(name);
+ if (trimmedName == NULL)
+ {
+ WARNING_MSG("Bad format on line %lu, skip", (unsigned long)line);
+ continue;
+ }
+
+ // Get the second part of the line
+ char* value = strtok(NULL, "=");
+ if(value == NULL) {
+ WARNING_MSG("Bad format on line %lu, skip", (unsigned long)line);
+ free(trimmedName);
+ continue;
+ }
+
+ // Trim the value
+ char* trimmedValue = trimString(value);
+ if (trimmedValue == NULL)
+ {
+ WARNING_MSG("Bad format on line %lu, skip", (unsigned long)line);
+ free(trimmedName);
+ continue;
+ }
+
+ // Save name,value
+ std::string stringName(trimmedName);
+ std::string stringValue(trimmedValue);
+ free(trimmedName);
+ free(trimmedValue);
+
+ switch (Configuration::i()->getType(stringName))
+ {
+ case CONFIG_TYPE_STRING:
+ Configuration::i()->setString(stringName, stringValue);
+ break;
+ case CONFIG_TYPE_INT:
+ Configuration::i()->setInt(stringName, atoi(stringValue.c_str()));
+ break;
+ case CONFIG_TYPE_BOOL:
+ bool boolValue;
+ if (string2bool(stringValue, &boolValue))
+ {
+ Configuration::i()->setBool(stringName, boolValue);
+ }
+ else
+ {
+ WARNING_MSG("The value %s is not a boolean", stringValue.c_str());
+ }
+ break;
+ case CONFIG_TYPE_UNSUPPORTED:
+ default:
+ WARNING_MSG("The following configuration is not supported: %s = %s",
+ stringName.c_str(), stringValue.c_str());
+ break;
+ }
+ }
+
+ fclose(fp);
+
+ return true;
+}
+
+// Get the boolean value from a string
+bool SimpleConfigLoader::string2bool(std::string stringValue, bool* boolValue)
+{
+ // Convert to lowercase
+ std::transform(stringValue.begin(), stringValue.end(), stringValue.begin(), tolower);
+
+ if (stringValue.compare("true") == 0)
+ {
+ *boolValue = true;
+ return true;
+ }
+
+ if (stringValue.compare("false") == 0)
+ {
+ *boolValue = false;
+ return true;
+ }
+
+ return false;
+}
+
+#define CONFIG_FILE ".config/softhsm2/softhsm2.conf"
+
+/* Returns a user-specific path for configuration.
+ */
+static char *get_user_path(void)
+{
+#ifdef _WIN32
+ char path[512];
+ const char *home_drive = getenv("HOMEDRIVE");
+ const char *home_path = getenv("HOMEPATH");
+
+ if (home_drive && home_path) {
+ snprintf(path, sizeof(path), "%s%s\\softhsm2.conf", home_drive, home_path);
+
+ if (_access(path, 0) == 0)
+ return strdup(path);
+ }
+ goto fail;
+#else
+ char path[_POSIX_PATH_MAX];
+ const char *home_dir = getenv("HOME");
+
+ if (home_dir != NULL && home_dir[0] != 0) {
+ snprintf(path, sizeof(path), "%s/" CONFIG_FILE, home_dir);
+ if (access(path, R_OK) == 0)
+ return strdup(path);
+ else
+ goto fail;
+ }
+
+# if defined(HAVE_GETPWUID_R)
+ if (home_dir == NULL || home_dir[0] == '\0') {
+ struct passwd *pwd;
+ struct passwd _pwd;
+ int ret;
+ char tmp[512];
+
+ ret = getpwuid_r(getuid(), &_pwd, tmp, sizeof(tmp), &pwd);
+ if (ret == 0 && pwd != NULL) {
+ snprintf(path, sizeof(path), "%s/" CONFIG_FILE, pwd->pw_dir);
+ if (access(path, R_OK) == 0)
+ return strdup(path);
+ else
+ goto fail;
+ }
+ }
+# endif
+#endif
+
+ fail:
+ return NULL;
+}
+
+static char *get_env_var_path(void)
+{
+#ifdef _WIN32
+
+ LPSTR value = NULL;
+ DWORD size = 0;
+
+ size = GetEnvironmentVariableA("SOFTHSM2_CONF", value, size);
+ if (size == 0) {
+ return NULL;
+ }
+
+ value = (LPSTR) malloc(size);
+ if (NULL == value) {
+ return NULL;
+ }
+
+ if (GetEnvironmentVariableA("SOFTHSM2_CONF", value, size) != (size - 1)) {
+ free(value);
+ return NULL;
+ }
+
+ return value;
+
+#else
+
+ char *value = getenv("SOFTHSM2_CONF");
+
+ if (value == NULL) {
+ return value;
+ } else {
+ return strdup(value);
+ }
+
+#endif
+}
+
+char* SimpleConfigLoader::getConfigPath()
+{
+ char* configPath = get_env_var_path();
+ char* tpath;
+
+ if (configPath != NULL)
+ {
+ return configPath;
+ }
+ else
+ {
+ tpath = get_user_path();
+ if (tpath != NULL)
+ {
+ return tpath;
+ }
+ }
+
+ return strdup(DEFAULT_SOFTHSM2_CONF);
+}
+
+char* SimpleConfigLoader::trimString(char* text)
+{
+ if (text == NULL)
+ {
+ return NULL;
+ }
+
+ int startPos = 0;
+ int endPos = strlen(text) - 1;
+
+ // Find the first position without a space
+ while (startPos <= endPos && isspace((int)*(text + startPos)))
+ {
+ startPos++;
+ }
+ // Find the last position without a space
+ while (startPos <= endPos && isspace((int)*(text + endPos)))
+ {
+ endPos--;
+ }
+
+ // We must have a valid string
+ int length = endPos - startPos + 1;
+ if (length <= 0)
+ {
+ return NULL;
+ }
+
+ // Create the trimmed text
+ char* trimmedText = (char*)malloc(length + 1);
+ if (trimmedText == NULL)
+ {
+ return NULL;
+ }
+ trimmedText[length] = '\0';
+ memcpy(trimmedText, text + startPos, length);
+
+ return trimmedText;
+}