diff options
author | Paul Lawrence <paullawrence@google.com> | 2015-04-29 16:24:25 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-29 16:24:25 +0000 |
commit | efd93b16b36d2aecc994c282317f37729bab7357 (patch) | |
tree | b19169278c19643d7df88c43659a020e54ef6e67 | |
parent | cf461bced1ef97331e808ab0fb994a6ada93f2eb (diff) | |
parent | 377cd1957172c19ee21baa3d6bda0840f1ce020d (diff) | |
download | extras-master-soong.tar.gz |
Merge "Securely encrypt the master key"master-soong
-rw-r--r-- | ext4_utils/Android.mk | 2 | ||||
-rw-r--r-- | ext4_utils/e4crypt_static.c | 147 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt.cpp | 172 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt_init_extensions.cpp | 165 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt_init_extensions.h | 15 | ||||
-rw-r--r-- | ext4_utils/key_control.cpp | 44 | ||||
-rw-r--r-- | ext4_utils/key_control.h (renamed from ext4_utils/ext4_crypt.h) | 25 | ||||
-rw-r--r-- | ext4_utils/unencrypted_properties.cpp | 31 | ||||
-rw-r--r-- | ext4_utils/unencrypted_properties.h | 23 |
9 files changed, 221 insertions, 403 deletions
diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk index 08088863..31a4b711 100644 --- a/ext4_utils/Android.mk +++ b/ext4_utils/Android.mk @@ -53,8 +53,8 @@ include $(BUILD_HOST_EXECUTABLE) # libext4_utils_src_files += \ + key_control.cpp \ ext4_crypt.cpp \ - e4crypt_static.c \ unencrypted_properties.cpp ifneq ($(HOST_OS),windows) diff --git a/ext4_utils/e4crypt_static.c b/ext4_utils/e4crypt_static.c deleted file mode 100644 index 1a62ce4a..00000000 --- a/ext4_utils/e4crypt_static.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2015 Google, Inc. - */ - -#define TAG "ext4_utils" - -#include <dirent.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include <sys/xattr.h> -#include <sys/syscall.h> -#include <sys/stat.h> - -#include <cutils/klog.h> - -#include "ext4_crypt.h" - -/* keyring keyctl commands */ -#define KEYCTL_SETPERM 5 /* set permissions for a key in a keyring */ -#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */ -#define KEYCTL_SEARCH 10 /* search for a key in a keyring */ - -#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy" -#define EXT4_KEYREF_DELIMITER ((char)'.') - -/* Validate that all path items are available and accessible. */ -static int is_path_valid(const char *path) -{ - if (access(path, W_OK)) { - KLOG_ERROR(TAG, "Can't access %s: %s\n",strerror(errno), path); - return 0; - } - - return 1; -} - -/* Checks whether the policy provided is valid */ -static int is_keyref_valid(const char *keyref) -{ - char *period = 0; - size_t key_location_len = 0; - - /* Key ref must have a key and location delimiter character. */ - period = strchr(keyref, EXT4_KEYREF_DELIMITER); - if (!period) { - return 0; - } - - /* period must be >= keyref. */ - key_location_len = period - keyref; - - if (strncmp(keyref, "@t", key_location_len) == 0 || - strncmp(keyref, "@p", key_location_len) == 0 || - strncmp(keyref, "@s", key_location_len) == 0 || - strncmp(keyref, "@u", key_location_len) == 0 || - strncmp(keyref, "@g", key_location_len) == 0 || - strncmp(keyref, "@us", key_location_len) == 0) - return 1; - - return 0; -} - -static int is_dir_empty(const char *dirname) -{ - int n = 0; - struct dirent *d; - DIR *dir; - - dir = opendir(dirname); - while ((d = readdir(dir)) != NULL) { - if (strcmp(d->d_name, "lost+found") == 0) { - // Skip lost+found directory - } else if (++n > 2) { - break; - } - } - closedir(dir); - return n <= 2; -} - -int do_policy_set(const char *directory, const char *policy) -{ - struct stat st; - ssize_t ret; - - if (!is_keyref_valid(policy)) { - KLOG_ERROR(TAG, "Policy has invalid format.\n"); - return -EINVAL; - } - - if (!is_path_valid(directory)) { - return -EINVAL; - } - - stat(directory, &st); - if (!S_ISDIR(st.st_mode)) { - KLOG_ERROR(TAG, "Can only set policy on a directory (%s)\n", directory); - return -EINVAL; - } - - if (!is_dir_empty(directory)) { - KLOG_ERROR(TAG, "Can only set policy on an empty directory (%s)\n", directory); - return -EINVAL; - } - - ret = lsetxattr(directory, XATTR_NAME_ENCRYPTION_POLICY, policy, - strlen(policy), 0); - - if (ret) { - KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n", - directory, strerror(errno)); - return -EINVAL; - } - - KLOG_INFO(TAG, "Encryption policy for %s is set to %s\n", directory, policy); - return 0; -} - -static long keyctl(int cmd, ...) -{ - va_list va; - unsigned long arg2, arg3, arg4, arg5; - - va_start(va, cmd); - arg2 = va_arg(va, unsigned long); - arg3 = va_arg(va, unsigned long); - arg4 = va_arg(va, unsigned long); - arg5 = va_arg(va, unsigned long); - va_end(va); - return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); -} - -key_serial_t add_key(const char *type, - const char *description, - const void *payload, - size_t plen, - key_serial_t ringid) -{ - return syscall(__NR_add_key, type, description, payload, plen, ringid); -} - -long keyctl_setperm(key_serial_t id, int permissions) -{ - return keyctl(KEYCTL_SETPERM, id, permissions); -} diff --git a/ext4_utils/ext4_crypt.cpp b/ext4_utils/ext4_crypt.cpp index bb573323..7d3dc91e 100644 --- a/ext4_utils/ext4_crypt.cpp +++ b/ext4_utils/ext4_crypt.cpp @@ -1,120 +1,132 @@ -#define TAG "ext4_utils" +/* + * Copyright (c) 2015 Google, Inc. + */ -#include "ext4_crypt.h" +#define TAG "ext4_utils" -#include <string> -#include <fstream> -#include <map> +#include "ext4_crypt_init_extensions.h" +#include <dirent.h> #include <errno.h> -#include <sys/mount.h> +#include <string.h> +#include <unistd.h> + +#include <sys/xattr.h> +#include <sys/syscall.h> +#include <sys/stat.h> #include <cutils/klog.h> -#include <cutils/properties.h> #include "unencrypted_properties.h" -namespace { - std::map<std::string, std::string> s_password_store; -} - -bool e4crypt_non_default_key(const char* dir) -{ - int type = e4crypt_get_password_type(dir); +#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy" +#define EXT4_KEYREF_DELIMITER ((char)'.') - // ext4enc:TODO Use consts, not 1 here - return type != -1 && type != 1; -} +// ext4enc:TODO Include structure from somewhere sensible +// MUST be in sync with ext4_crypto.c in kernel +#define EXT4_MAX_KEY_SIZE 76 +struct ext4_encryption_key { + uint32_t mode; + char raw[EXT4_MAX_KEY_SIZE]; + uint32_t size; +}; -int e4crypt_get_password_type(const char* path) +/* Validate that all path items are available and accessible. */ +static int is_path_valid(const char *path) { - UnencryptedProperties props(path); - if (props.Get<std::string>(properties::key).empty()) { - KLOG_INFO(TAG, "No master key, so not ext4enc\n"); - return -1; + if (access(path, W_OK)) { + KLOG_ERROR(TAG, "Can't access %s: %s\n",strerror(errno), path); + return 0; } - return props.Get<int>(properties::type, 1); + return 1; } -int e4crypt_change_password(const char* path, int crypt_type, - const char* password) +/* Checks whether the policy provided is valid */ +static int is_keyref_valid(const char *keyref) { - // ext4enc:TODO Encrypt master key with password securely. Store hash of - // master key for validation - UnencryptedProperties props(path); - if ( props.Set(properties::password, password) - && props.Set(properties::type, crypt_type)) - return 0; - return -1; -} + char *period = 0; + size_t key_location_len = 0; -int e4crypt_crypto_complete(const char* path) -{ - KLOG_INFO(TAG, "ext4 crypto complete called on %s\n", path); - if (UnencryptedProperties(path).Get<std::string>(properties::key).empty()) { - KLOG_INFO(TAG, "No master key, so not ext4enc\n"); - return -1; + /* Key ref must have a key and location delimiter character. */ + period = strchr(keyref, EXT4_KEYREF_DELIMITER); + if (!period) { + return 0; } + /* period must be >= keyref. */ + key_location_len = period - keyref; + + if (strncmp(keyref, "@t", key_location_len) == 0 || + strncmp(keyref, "@p", key_location_len) == 0 || + strncmp(keyref, "@s", key_location_len) == 0 || + strncmp(keyref, "@u", key_location_len) == 0 || + strncmp(keyref, "@g", key_location_len) == 0 || + strncmp(keyref, "@us", key_location_len) == 0) + return 1; + return 0; } -int e4crypt_check_passwd(const char* path, const char* password) +static int is_dir_empty(const char *dirname) { - UnencryptedProperties props(path); - if (props.Get<std::string>(properties::key).empty()) { - KLOG_INFO(TAG, "No master key, so not ext4enc\n"); - return -1; - } - - auto actual_password = props.Get<std::string>(properties::password); - - if (actual_password == password) { - s_password_store[path] = password; - return 0; - } else { - return -1; + int n = 0; + struct dirent *d; + DIR *dir; + + dir = opendir(dirname); + while ((d = readdir(dir)) != NULL) { + if (strcmp(d->d_name, "lost+found") == 0) { + // Skip lost+found directory + } else if (++n > 2) { + break; + } } + closedir(dir); + return n <= 2; } -int e4crypt_restart(const char* path) +int do_policy_set(const char *directory, const char *policy) { - int rc = 0; + struct stat st; + ssize_t ret; - KLOG_INFO(TAG, "ext4 restart called on %s\n", path); - property_set("vold.decrypt", "trigger_reset_main"); - KLOG_INFO(TAG, "Just asked init to shut down class main\n"); - sleep(2); + if (!is_keyref_valid(policy)) { + KLOG_ERROR(TAG, "Policy has invalid format.\n"); + return -EINVAL; + } - std::string tmp_path = std::string() + path + "/tmp_mnt"; + if (!is_path_valid(directory)) { + return -EINVAL; + } - // ext4enc:TODO add retry logic - rc = umount(tmp_path.c_str()); - if (rc) { - KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n", - tmp_path.c_str(), rc, strerror(errno)); - return rc; + stat(directory, &st); + if (!S_ISDIR(st.st_mode)) { + KLOG_ERROR(TAG, "Can only set policy on a directory (%s)\n", directory); + return -EINVAL; } - // ext4enc:TODO add retry logic - rc = umount(path); - if (rc) { - KLOG_ERROR(TAG, "umount %s failed with rc %d, msg %s\n", - path, rc, strerror(errno)); - return rc; + if (!is_dir_empty(directory)) { + KLOG_ERROR(TAG, "Can only set policy on an empty directory (%s)\n", + directory); + return -EINVAL; } + ret = lsetxattr(directory, XATTR_NAME_ENCRYPTION_POLICY, policy, + strlen(policy), 0); + + if (ret) { + KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n", + directory, strerror(errno)); + return -EINVAL; + } + + KLOG_INFO(TAG, "Encryption policy for %s is set to %s\n", directory, policy); return 0; } -const char* e4crypt_get_password(const char* path) +bool e4crypt_non_default_key(const char* dir) { - // ext4enc:TODO scrub password after timeout - auto i = s_password_store.find(path); - if (i == s_password_store.end()) { - return 0; - } else { - return i->second.c_str(); - } + UnencryptedProperties props(dir); + return props.Get<int>(properties::is_default, 1) != 1; } diff --git a/ext4_utils/ext4_crypt_init_extensions.cpp b/ext4_utils/ext4_crypt_init_extensions.cpp index 284437f9..3b7df6dd 100644 --- a/ext4_utils/ext4_crypt_init_extensions.cpp +++ b/ext4_utils/ext4_crypt_init_extensions.cpp @@ -1,12 +1,10 @@ #define TAG "ext4_utils" -#include "ext4_crypt.h" +#include "ext4_crypt_init_extensions.h" #include <string> -#include <fstream> -#include <iomanip> -#include <sstream> +#include <dirent.h> #include <errno.h> #include <sys/mount.h> #include <sys/stat.h> @@ -16,29 +14,26 @@ #include <cutils/sockets.h> #include <poll.h> +#include "key_control.h" #include "unencrypted_properties.h" -// ext4enc:TODO Include structure from somewhere sensible -// MUST be in sync with ext4_crypto.c in kernel -#define EXT4_MAX_KEY_SIZE 76 -struct ext4_encryption_key { - uint32_t mode; - char raw[EXT4_MAX_KEY_SIZE]; - uint32_t size; -}; - -static const std::string keyring = "@s"; static const std::string arbitrary_sequence_number = "42"; -static const int vold_command_timeout_ms = 10 * 1000; - -static key_serial_t device_keyring = -1; +static const int vold_command_timeout_ms = 60 * 1000; static std::string vold_command(std::string const& command) { KLOG_INFO(TAG, "Running command %s\n", command.c_str()); - int sock = socket_local_client("vold", + int sock = -1; + + while (true) { + sock = socket_local_client("vold", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); + if (sock >= 0) { + break; + } + usleep(10000); + } if (sock < 0) { KLOG_INFO(TAG, "Cannot open vold, failing command\n"); @@ -97,52 +92,35 @@ static std::string vold_command(std::string const& command) int e4crypt_create_device_key(const char* dir, int ensure_dir_exists(const char*)) { + // Already encrypted with password? If so bail + std::string temp_folder = std::string() + dir + "/tmp_mnt"; + DIR* temp_dir = opendir(temp_folder.c_str()); + if (temp_dir) { + closedir(temp_dir); + return 0; + } + // Make sure folder exists. Use make_dir to set selinux permissions. KLOG_INFO(TAG, "Creating test device key\n"); - UnencryptedProperties props(dir); - if (ensure_dir_exists(props.GetPath().c_str())) { + if (ensure_dir_exists(UnencryptedProperties::GetPath(dir).c_str())) { KLOG_ERROR(TAG, "Failed to create %s with error %s\n", - props.GetPath().c_str(), strerror(errno)); + UnencryptedProperties::GetPath(dir).c_str(), + strerror(errno)); return -1; } - if (props.Get<std::string>(properties::key).empty()) { - // Create new key since it doesn't already exist - std::ifstream urandom("/dev/urandom", std::ifstream::binary); - if (!urandom) { - KLOG_ERROR(TAG, "Failed to open /dev/urandom\n"); - return -1; - } - - // ext4enc:TODO Don't hardcode 32 - std::string key_material(32, '\0'); - urandom.read(&key_material[0], key_material.length()); - if (!urandom) { - KLOG_ERROR(TAG, "Failed to read random bytes\n"); - return -1; - } - - if (!props.Set(properties::key, key_material)) { - KLOG_ERROR(TAG, "Failed to write key material\n"); - return -1; - } - } - - if (!props.Remove(properties::ref)) { - KLOG_ERROR(TAG, "Failed to remove key ref\n"); - return -1; - } + auto result = vold_command("cryptfs enablefilecrypto"); + // ext4enc:TODO proper error handling + KLOG_INFO(TAG, "enablefilecrypto returned with result %s\n", + result.c_str()); return 0; } int e4crypt_install_keyring() { - device_keyring = add_key("keyring", - "e4crypt", - 0, - 0, - KEY_SPEC_SESSION_KEYRING); + key_serial_t device_keyring = add_key("keyring", "e4crypt", 0, 0, + KEY_SPEC_SESSION_KEYRING); if (device_keyring == -1) { KLOG_ERROR(TAG, "Failed to create keyring\n"); @@ -162,83 +140,6 @@ int e4crypt_install_keyring() return 0; } -int e4crypt_install_key(const char* dir) -{ - UnencryptedProperties props(dir); - auto key = props.Get<std::string>(properties::key); - - // Get password to decrypt as needed - if (e4crypt_non_default_key(dir)) { - std::string result = vold_command("cryptfs getpw"); - // result is either - // 200 0 -1 - // or - // 200 0 {{sensitive}} 0001020304 - // where 0001020304 is hex encoding of password - std::istringstream i(result); - std::string bit; - i >> bit; - if (bit != "200") { - KLOG_ERROR(TAG, "Expecting 200\n"); - return -1; - } - - i >> bit; - if (bit != arbitrary_sequence_number) { - KLOG_ERROR(TAG, "Expecting %s\n", arbitrary_sequence_number.c_str()); - return -1; - } - - i >> bit; - if (bit != "{{sensitive}}") { - KLOG_INFO(TAG, "Not encrypted\n"); - return -1; - } - - i >> bit; - } - - // Add key to keyring - ext4_encryption_key ext4_key = {0, {0}, 0}; - if (key.length() > sizeof(ext4_key.raw)) { - KLOG_ERROR(TAG, "Key too long\n"); - return -1; - } - - ext4_key.mode = 0; - memcpy(ext4_key.raw, &key[0], key.length()); - ext4_key.size = key.length(); - - // ext4enc:TODO Use better reference not 1234567890 - key_serial_t key_id = add_key("logon", "ext4-key:1234567890", - (void*)&ext4_key, sizeof(ext4_key), - device_keyring); - - if (key_id == -1) { - KLOG_ERROR(TAG, "Failed to insert key into keyring with error %s\n", - strerror(errno)); - return -1; - } - - KLOG_INFO(TAG, "Added key %d to keyring %d in process %d\n", - key_id, device_keyring, getpid()); - - // ext4enc:TODO set correct permissions - long result = keyctl_setperm(key_id, 0x3f3f3f3f); - if (result) { - KLOG_ERROR(TAG, "KEYCTL_SETPERM failed with error %ld\n", result); - return -1; - } - - // Save reference to key so we can set policy later - if (!props.Set(properties::ref, "ext4-key:1234567890")) { - KLOG_ERROR(TAG, "Cannot save key reference\n"); - return -1; - } - - return 0; -} - int e4crypt_set_directory_policy(const char* dir) { // Only set policy on first level /data directories @@ -250,12 +151,12 @@ int e4crypt_set_directory_policy(const char* dir) } UnencryptedProperties props("/data"); - std::string ref = props.Get<std::string>(properties::ref); - std::string policy = keyring + "." + ref; + std::string policy = props.Get<std::string>(properties::ref); KLOG_INFO(TAG, "Setting policy %s\n", policy.c_str()); int result = do_policy_set(dir, policy.c_str()); if (result) { - KLOG_ERROR(TAG, "Setting policy on %s failed!\n", dir); + KLOG_ERROR(TAG, "Setting %s policy on %s failed!\n", + policy.c_str(), dir); return -1; } diff --git a/ext4_utils/ext4_crypt_init_extensions.h b/ext4_utils/ext4_crypt_init_extensions.h new file mode 100644 index 00000000..17f5b2e0 --- /dev/null +++ b/ext4_utils/ext4_crypt_init_extensions.h @@ -0,0 +1,15 @@ +#include <sys/cdefs.h> +#include <stdbool.h> + +__BEGIN_DECLS + +// These functions assume they are being called from init +// They will not operate properly outside of init +int e4crypt_install_keyring(); +int e4crypt_create_device_key(const char* path, + int ensure_dir_exists(const char* dir)); +int e4crypt_set_directory_policy(const char* path); +bool e4crypt_non_default_key(const char* path); +int do_policy_set(const char *directory, const char *policy); + +__END_DECLS diff --git a/ext4_utils/key_control.cpp b/ext4_utils/key_control.cpp new file mode 100644 index 00000000..3d775b7f --- /dev/null +++ b/ext4_utils/key_control.cpp @@ -0,0 +1,44 @@ +#include "key_control.h" + +#include <stdarg.h> +#include <unistd.h> +#include <sys/syscall.h> + +/* keyring keyctl commands */ +#define KEYCTL_SETPERM 5 /* set permissions for a key in a keyring */ +#define KEYCTL_UNLINK 9 /* unlink a key from a keyring */ +#define KEYCTL_SEARCH 10 /* search for a key in a keyring */ + +static long keyctl(int cmd, ...) +{ + va_list va; + unsigned long arg2, arg3, arg4, arg5; + + va_start(va, cmd); + arg2 = va_arg(va, unsigned long); + arg3 = va_arg(va, unsigned long); + arg4 = va_arg(va, unsigned long); + arg5 = va_arg(va, unsigned long); + va_end(va); + return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5); +} + +key_serial_t add_key(const char *type, + const char *description, + const void *payload, + size_t plen, + key_serial_t ringid) +{ + return syscall(__NR_add_key, type, description, payload, plen, ringid); +} + +long keyctl_setperm(key_serial_t id, int permissions) +{ + return keyctl(KEYCTL_SETPERM, id, permissions); +} + +long keyctl_search(key_serial_t ringid, const char *type, + const char *description, key_serial_t destringid) +{ + return keyctl(KEYCTL_SEARCH, ringid, type, description, destringid); +} diff --git a/ext4_utils/ext4_crypt.h b/ext4_utils/key_control.h index cc692735..8e6e32ba 100644 --- a/ext4_utils/ext4_crypt.h +++ b/ext4_utils/key_control.h @@ -1,28 +1,7 @@ -#include <stdbool.h> #include <sys/cdefs.h> #include <sys/types.h> __BEGIN_DECLS -// These functions assume they are being called from init -// They will not operate properly outside of init -int e4crypt_install_keyring(); -int e4crypt_install_key(const char* dir); -int e4crypt_create_device_key(const char* dir, - int ensure_dir_exists(const char* dir)); - -// General functions -bool e4crypt_non_default_key(const char* dir); -int e4crypt_set_directory_policy(const char* dir); -int e4crypt_main(int argc, char* argv[]); -int e4crypt_change_password(const char* path, int crypt_type, - const char* password); -int e4crypt_get_password_type(const char* path); -int e4crypt_crypto_complete(const char* dir); -int e4crypt_check_passwd(const char* dir, const char* password); -const char* e4crypt_get_password(const char* dir); -int e4crypt_restart(const char* dir); - -// Key functions. ext4enc:TODO Move to own file // ext4enc:TODO - get these keyring standard definitions from proper system file // keyring serial number type @@ -44,7 +23,7 @@ key_serial_t add_key(const char *type, long keyctl_setperm(key_serial_t id, int permissions); -// Set policy on directory -int do_policy_set(const char *directory, const char *policy); +long keyctl_search(key_serial_t ringid, const char *type, + const char *description, key_serial_t destringid); __END_DECLS diff --git a/ext4_utils/unencrypted_properties.cpp b/ext4_utils/unencrypted_properties.cpp index bef7c57b..5086c64b 100644 --- a/ext4_utils/unencrypted_properties.cpp +++ b/ext4_utils/unencrypted_properties.cpp @@ -1,12 +1,12 @@ #include "unencrypted_properties.h" #include <sys/stat.h> +#include <dirent.h> namespace properties { const char* key = "key"; const char* ref = "ref"; - const char* type = "type"; - const char* password = "password"; + const char* is_default = "is_default"; } namespace @@ -14,9 +14,20 @@ namespace const char* unencrypted_folder = "unencrypted"; } +std::string UnencryptedProperties::GetPath(const char* device) +{ + return std::string() + device + "/" + unencrypted_folder; +} + UnencryptedProperties::UnencryptedProperties(const char* device) - : folder_(std::string() + device + "/" + unencrypted_folder) + : folder_(GetPath(device)) { + DIR* dir = opendir(folder_.c_str()); + if (dir) { + closedir(dir); + } else { + folder_.clear(); + } } UnencryptedProperties::UnencryptedProperties() @@ -24,7 +35,7 @@ UnencryptedProperties::UnencryptedProperties() } template<> std::string UnencryptedProperties::Get(const char* name, - std::string default_value) + std::string default_value) const { if (!OK()) return default_value; std::ifstream i(folder_ + "/" + name, std::ios::binary); @@ -56,18 +67,18 @@ template<> bool UnencryptedProperties::Set(const char* name, std::string const& return !o.fail(); } -UnencryptedProperties UnencryptedProperties::GetChild(const char* name) +UnencryptedProperties UnencryptedProperties::GetChild(const char* name) const { - UnencryptedProperties e4p; - if (!OK()) return e4p; + UnencryptedProperties up; + if (!OK()) return up; std::string directory(folder_ + "/" + name); if (mkdir(directory.c_str(), 700) == -1 && errno != EEXIST) { - return e4p; + return up; } - e4p.folder_ = directory; - return e4p; + up.folder_ = directory; + return up; } bool UnencryptedProperties::Remove(const char* name) diff --git a/ext4_utils/unencrypted_properties.h b/ext4_utils/unencrypted_properties.h index 80f41df4..d0f6da1a 100644 --- a/ext4_utils/unencrypted_properties.h +++ b/ext4_utils/unencrypted_properties.h @@ -5,8 +5,7 @@ namespace properties { extern const char* key; extern const char* ref; - extern const char* type; - extern const char* password; + extern const char* is_default; } /** @@ -18,34 +17,38 @@ namespace properties { class UnencryptedProperties { public: + // Get path of folder. Must create before using any properties + // This is to allow proper setting of SELinux policy + static std::string GetPath(const char* device); + // Opens properties folder on named device. - // If folder does not exist, construction will succeed, but all + // If folder does not exist, OK will return false, all // getters will return default properties and setters will fail. UnencryptedProperties(const char* device); // Get named object. Return default if object does not exist or error. - template<typename t> t Get(const char* name, t default_value = t()); + template<typename t> t Get(const char* name, t default_value = t()) const; // Set named object. Return true if success, false otherwise template<typename t> bool Set(const char* name, t const& value); // Get child properties - UnencryptedProperties GetChild(const char* name); + UnencryptedProperties GetChild(const char* name) const; // Remove named object bool Remove(const char* name); - // Get path of folder - std::string const& GetPath() const {return folder_;} + // Does folder exist? + bool OK() const; + private: UnencryptedProperties(); - bool OK() const; std::string folder_; }; template<typename t> t UnencryptedProperties::Get(const char* name, - t default_value) + t default_value) const { if (!OK()) return default_value; t value = default_value; @@ -64,7 +67,7 @@ template<typename t> bool UnencryptedProperties::Set(const char* name, // Specialized getters/setters for strings template<> std::string UnencryptedProperties::Get(const char* name, - std::string default_value); + std::string default_value) const; template<> bool UnencryptedProperties::Set(const char* name, std::string const& value); |