OSDN Git Service

DO NOT MERGE Securely encrypt the master key
authorPaul Lawrence <paullawrence@google.com>
Tue, 28 Apr 2015 22:13:04 +0000 (22:13 +0000)
committerPaul Lawrence <paullawrence@google.com>
Fri, 29 May 2015 17:35:33 +0000 (17:35 +0000)
(cherry-picked from commit 377cd1957172c19ee21baa3d6bda0840f1ce020d)

Move all key management into vold
Reuse vold's existing key management through the crypto footer
to manage the device wide keys.

Use ro.crypto.type flag to determine crypto type, which prevents
any issues when running in block encrypted mode, as well as speeding
up boot in block or no encryption.

This is one of four changes to enable this functionality:
  https://android-review.googlesource.com/#/c/148586/
  https://android-review.googlesource.com/#/c/148604/
  https://android-review.googlesource.com/#/c/148606/
  https://android-review.googlesource.com/#/c/148607/

Bug: 18151196

Change-Id: I7a4ef3f3a937c45ff18f17c9ad1398293a8630f3

ext4_utils/Android.mk
ext4_utils/e4crypt_static.c [deleted file]
ext4_utils/ext4_crypt.cpp
ext4_utils/ext4_crypt_init_extensions.cpp
ext4_utils/ext4_crypt_init_extensions.h [new file with mode: 0644]
ext4_utils/key_control.cpp [new file with mode: 0644]
ext4_utils/key_control.h [moved from ext4_utils/ext4_crypt.h with 50% similarity]
ext4_utils/unencrypted_properties.cpp
ext4_utils/unencrypted_properties.h

index 0808886..31a4b71 100644 (file)
@@ -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 (file)
index 1a62ce4..0000000
+++ /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);
-}
index bb57332..7d3dc91 100644 (file)
-#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;
 }
index 284437f..3b7df6d 100644 (file)
@@ -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>
 #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 (file)
index 0000000..17f5b2e
--- /dev/null
@@ -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 (file)
index 0000000..3d775b7
--- /dev/null
@@ -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);
+}
similarity index 50%
rename from ext4_utils/ext4_crypt.h
rename to ext4_utils/key_control.h
index cc69273..8e6e32b 100644 (file)
@@ -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
index bef7c57..5086c64 100644 (file)
@@ -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)
index 80f41df..d0f6da1 100644 (file)
@@ -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);