shill: limit shill profile file permissions

The shill profile file permissions must be readable and writeable
by the owner only.

BUG=chromium-os:29752
TEST=Added new checks to unit test KeyFileStoreTest.OpenClose
to verify the permissions.

Change-Id: I8907f27714fbc1bf417f38e5de4448209ab65e5e
Reviewed-on: https://gerrit.chromium.org/gerrit/20711
Reviewed-by: Paul Stewart <pstew@chromium.org>
Tested-by: Gary Morain <gmorain@chromium.org>
Commit-Ready: Gary Morain <gmorain@chromium.org>
diff --git a/key_file_store.cc b/key_file_store.cc
index 7abff99..4fefef0 100644
--- a/key_file_store.cc
+++ b/key_file_store.cc
@@ -6,6 +6,9 @@
 
 #include <base/file_util.h>
 #include <base/logging.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "shill/scope_logger.h"
 
@@ -83,11 +86,18 @@
     success = false;
   }
   if (success) {
-    int written = file_util::WriteFile(path_, data, length);
-    if (written < 0 ||
-        static_cast<unsigned int>(written) != length) {
-      LOG(ERROR) << "Failed to store key file: " << path_.value();
+    // The profile file must be accessible by the owner only.
+    int fd = creat(path_.value().c_str(), S_IRUSR | S_IWUSR);
+    if (fd < 0) {
+      LOG(ERROR) << "Failed to create key file " << path_.value();
       success = false;
+    } else {
+      int written = file_util::WriteFileDescriptor(fd, data, length);
+      if (written < 0 || (static_cast<gsize>(written) != length)) {
+        LOG(ERROR) << "Failed to store key file: " << path_.value();
+        success = false;
+      }
+      close(fd);
     }
   }
   glib_->Free(data);