blob: cce5ea7b17b8e607d01f7c10f6a19884d3983e2b [file] [log] [blame]
Darin Petkov083047b2011-06-23 20:42:48 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/key_file_store.h"
6
7#include <base/file_util.h>
8#include <base/logging.h>
9
10using std::set;
11using std::string;
12
13namespace shill {
14
Darin Petkov86964e02011-06-29 13:49:28 -070015KeyFileStore::KeyFileStore(GLib *glib)
16 : glib_(glib),
17 crypto_(glib),
18 key_file_(NULL) {}
Darin Petkov083047b2011-06-23 20:42:48 -070019
20KeyFileStore::~KeyFileStore() {
21 ReleaseKeyFile();
22}
23
24void KeyFileStore::ReleaseKeyFile() {
25 if (key_file_) {
26 glib_->KeyFileFree(key_file_);
27 key_file_ = NULL;
28 }
29}
30
31bool KeyFileStore::Open() {
32 CHECK(!path_.empty());
33 CHECK(!key_file_);
Darin Petkov86964e02011-06-29 13:49:28 -070034 crypto_.Init();
Darin Petkov083047b2011-06-23 20:42:48 -070035 key_file_ = glib_->KeyFileNew();
36 int64 file_size = 0;
37 if (!file_util::GetFileSize(path_, &file_size) || file_size == 0) {
38 LOG(INFO) << "Creating a new key file at " << path_.value();
39 return true;
40 }
41 GError *error = NULL;
42 if (glib_->KeyFileLoadFromFile(
43 key_file_,
44 path_.value().c_str(),
45 static_cast<GKeyFileFlags>(G_KEY_FILE_KEEP_COMMENTS |
46 G_KEY_FILE_KEEP_TRANSLATIONS),
47 &error)) {
48 return true;
49 }
50 LOG(ERROR) << "Failed to load key file from " << path_.value() << ": "
51 << glib_->ConvertErrorToMessage(error);
52 ReleaseKeyFile();
53 return false;
54}
55
56bool KeyFileStore::Close() {
57 CHECK(key_file_);
58 GError *error = NULL;
59 gsize length = 0;
60 gchar *data = glib_->KeyFileToData(key_file_, &length, &error);
61 ReleaseKeyFile();
62
63 bool success = true;
64 if (path_.empty()) {
65 LOG(ERROR) << "Empty key file path.";
66 success = false;
67 }
68 if (success && (!data || error)) {
69 LOG(ERROR) << "Failed to convert key file to string: "
70 << glib_->ConvertErrorToMessage(error);
71 success = false;
72 }
73 if (success && file_util::WriteFile(path_, data, length) != length) {
74 LOG(ERROR) << "Failed to store key file: " << path_.value();
75 success = false;
76 }
77 glib_->Free(data);
78 return success;
79}
80
81set<string> KeyFileStore::GetGroups() {
82 CHECK(key_file_);
83 gsize length = 0;
84 gchar **groups = g_key_file_get_groups(key_file_, &length);
85 if (!groups) {
86 LOG(ERROR) << "Unable to obtain groups.";
87 return set<string>();
88 }
89 set<string> group_set(groups, groups + length);
90 glib_->Strfreev(groups);
91 return group_set;
92}
93
94bool KeyFileStore::ContainsGroup(const string &group) {
95 CHECK(key_file_);
96 return glib_->KeyFileHasGroup(key_file_, group.c_str());
97}
98
99bool KeyFileStore::DeleteKey(const string &group, const string &key) {
100 CHECK(key_file_);
101 GError *error = NULL;
102 glib_->KeyFileRemoveKey(key_file_, group.c_str(), key.c_str(), &error);
103 if (error) {
104 LOG(ERROR) << "Failed to delete (" << group << ":" << key << "): "
105 << glib_->ConvertErrorToMessage(error);
106 return false;
107 }
108 return true;
109}
110
111bool KeyFileStore::DeleteGroup(const string &group) {
112 CHECK(key_file_);
113 GError *error = NULL;
114 glib_->KeyFileRemoveGroup(key_file_, group.c_str(), &error);
115 if (error) {
Darin Petkov86964e02011-06-29 13:49:28 -0700116 LOG(ERROR) << "Failed to delete group " << group << ": "
Darin Petkov083047b2011-06-23 20:42:48 -0700117 << glib_->ConvertErrorToMessage(error);
118 return false;
119 }
120 return true;
121}
122
123bool KeyFileStore::GetString(const string &group,
124 const string &key,
125 string *value) {
126 CHECK(key_file_);
127 GError *error = NULL;
128 gchar *data =
129 glib_->KeyFileGetString(key_file_, group.c_str(), key.c_str(), &error);
130 if (!data) {
131 LOG(ERROR) << "Failed to lookup (" << group << ":" << key << "): "
132 << glib_->ConvertErrorToMessage(error);
133 return false;
134 }
135 if (value) {
136 *value = data;
137 }
138 glib_->Free(data);
139 return true;
140}
141
142bool KeyFileStore::SetString(const string &group,
143 const string &key,
144 const string &value) {
145 CHECK(key_file_);
146 glib_->KeyFileSetString(key_file_, group.c_str(), key.c_str(), value.c_str());
147 return true;
148}
149
150bool KeyFileStore::GetBool(const string &group,
151 const string &key,
152 bool *value) {
153 CHECK(key_file_);
154 GError *error = NULL;
155 gboolean data =
156 glib_->KeyFileGetBoolean(key_file_, group.c_str(), key.c_str(), &error);
157 if (error) {
158 LOG(ERROR) << "Failed to lookup (" << group << ":" << key << "): "
159 << glib_->ConvertErrorToMessage(error);
160 return false;
161 }
162 if (value) {
163 *value = data;
164 }
165 return true;
166}
167
168bool KeyFileStore::SetBool(const string &group, const string &key, bool value) {
169 CHECK(key_file_);
170 glib_->KeyFileSetBoolean(key_file_,
171 group.c_str(),
172 key.c_str(),
173 value ? TRUE : FALSE);
174 return true;
175}
176
177bool KeyFileStore::GetInt(const string &group, const string &key, int *value) {
178 CHECK(key_file_);
179 GError *error = NULL;
180 gint data =
181 glib_->KeyFileGetInteger(key_file_, group.c_str(), key.c_str(), &error);
182 if (error) {
183 LOG(ERROR) << "Failed to lookup (" << group << ":" << key << "): "
184 << glib_->ConvertErrorToMessage(error);
185 return false;
186 }
187 if (value) {
188 *value = data;
189 }
190 return true;
191}
192
193bool KeyFileStore::SetInt(const string &group, const string &key, int value) {
194 CHECK(key_file_);
195 glib_->KeyFileSetInteger(key_file_, group.c_str(), key.c_str(), value);
196 return true;
197}
198
Darin Petkov86964e02011-06-29 13:49:28 -0700199bool KeyFileStore::GetCryptedString(const string &group,
200 const string &key,
201 string *value) {
202 if (!GetString(group, key, value)) {
203 return false;
204 }
205 if (value) {
206 *value = crypto_.Decrypt(*value);
207 }
208 return true;
209}
210
211bool KeyFileStore::SetCryptedString(const string &group,
212 const string &key,
213 const string &value) {
214 return SetString(group, key, crypto_.Encrypt(value));
215}
216
Darin Petkov083047b2011-06-23 20:42:48 -0700217} // namespace shill