2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
20 #include <dd-deviced.h>
21 #include <dd-control.h>
23 #include <klay/process.h>
24 #include <klay/exception.h>
25 #include <klay/filesystem.h>
26 #include <klay/dbus/variant.h>
27 #include <klay/dbus/connection.h>
29 #include <dpm/pil/policy-context.h>
30 #include <dpm/pil/policy-model.h>
31 #include <dpm/pil/policy-storage.h>
32 #include <dpm/pil/launchpad.h>
36 const std::string APPID_DEVICE_ENCRYPTION = "org.tizen.ode";
37 const std::string APPID_LOCKSCREEN = "org.tizen.lockscreen";
39 const std::string PROG_FACTORY_RESET = "/usr/bin/dbus-send";
40 const std::vector<std::string> wipeCommand = {
45 "--dest=com.samsung.factoryreset",
46 "/com/samsung/factoryreset",
47 "com.samsung.factoryreset.start.setting"
50 bool checkEncryptionState(const char* key, bool encrypt)
52 char *value = ::vconf_get_str(key);
54 ERROR("Failed to read internal storage encryption state");
58 std::string state(value);
61 if (state != "unencrypted") {
62 ERROR("Storage might be already encrypted or it has error");
66 if (state != "encrypted") {
67 ERROR("Storage might be already decrypted or it has error");
75 bool getEncryptionState(const char* key)
77 char *state = ::vconf_get_str(key);
79 throw runtime::Exception("Failed to read internal storage encryption state");
82 std::string expected("encrypted");
83 if (expected == state) {
92 int launchApplication(const std::string& name, const Bundle& bundle)
95 Launchpad launchpad(rmi::Service::getPeerUid());
96 if (launchpad.isRunning(name)) {
97 launchpad.resume(name);
101 launchpad.launch(name, bundle);
102 } catch (runtime::Exception& e) {
103 ERROR("Failed to start application: " << name);
111 std::vector<std::string> getStorageDeviceList(const std::string& type)
115 std::vector<std::string> storages;
117 dbus::Connection &systemDBus = dbus::Connection::getSystem();
118 const dbus::Variant &var = systemDBus.methodcall("org.tizen.system.storage",
119 "/Org/Tizen/System/Storage/Block/Manager",
120 "org.tizen.system.storage.BlockManager",
123 "(a(issssssisibii))",
126 dbus::VariantIterator it;
127 var.get("(a(issssssisibii))", &it);
128 while (it.get("(issssssisibii)",
129 &intparams[0], // block type: 0 - scsi, 1 : mmc
130 &strparams[0], // devnode
131 &strparams[1], // syspath
132 &strparams[2], // usage
133 &strparams[3], // fs type
134 &strparams[4], // fs version
135 &strparams[5], // fs uuid enc
136 &intparams[1], // readonly: 0 - rw, 1 - ro
137 &strparams[6], // mount point
138 &intparams[2], // state: 0 - unmount, 1 - mount
139 &intparams[3], // primary: 0 - flase, 1 - true
140 &intparams[4], // flags: 1 - unmounted
141 // 2 - broken filesystem
145 &intparams[5])) { // strage id
146 storages.push_back(strrchr(strparams[0], '/') + 1);
147 for (int i = 0; i < 7; i++) {
149 ::free(strparams[i]);
157 void requestDeviceFormat(const std::string& devnode, int option)
160 dbus::Connection &systemDBus = dbus::Connection::getSystem();
161 systemDBus.methodcall("org.tizen.system.storage",
162 "/Org/Tizen/System/Storage/Block/Devices/" + devnode,
163 "org.tizen.system.storage.Block",
168 option).get("(i)", &ret);
170 throw runtime::Exception("Failed to format " + devnode);
176 class Security : public AbstractPolicyProvider {
179 WIPE_INTERNAL_STORAGE = (1 << 0), /**< Wipe internal memory */
180 WIPE_EXTERNAL_STORAGE = (1 << 1), /**< Wipe external memory */
188 int wipeData(int id);
190 int setInternalStorageEncryption(bool encrypt);
191 bool isInternalStorageEncrypted();
192 int setExternalStorageEncryption(bool encrypt);
193 bool isExternalStorageEncrypted();
200 Security::~Security()
204 int Security::lockoutScreen()
206 return launchApplication(APPID_LOCKSCREEN, Bundle());
209 int Security::setInternalStorageEncryption(bool encrypt)
211 if (!checkEncryptionState(VCONFKEY_ODE_CRYPTO_STATE, encrypt)) {
216 bundle.add("viewtype", encrypt ? "ENCRYPT_DEVICE" : "DECRYPT_DEVICE");
217 return launchApplication(APPID_DEVICE_ENCRYPTION, bundle);
220 bool Security::isInternalStorageEncrypted()
222 return getEncryptionState(VCONFKEY_ODE_CRYPTO_STATE);
225 int Security::setExternalStorageEncryption(bool encrypt)
227 if (!checkEncryptionState(VCONFKEY_SDE_CRYPTO_STATE, encrypt)) {
232 bundle.add("viewtype", encrypt ? "ENCRYPT_SD_CARD" : "DECRYPT_SD_CARD");
233 return launchApplication(APPID_DEVICE_ENCRYPTION, bundle);
236 bool Security::isExternalStorageEncrypted()
238 return getEncryptionState(VCONFKEY_SDE_CRYPTO_STATE);
241 int Security::wipeData(int id)
243 auto worker = [id, this]() {
244 if (id & WIPE_EXTERNAL_STORAGE) {
246 std::vector<std::string> devices = getStorageDeviceList("mmc");
247 for (const std::string& devnode : devices) {
248 std::cout << "Erase device: " << devnode << std::endl;
249 requestDeviceFormat(devnode, 1);
250 std::cout << "Erase device: " << devnode << " completed" << std::endl;
252 } catch(runtime::Exception& e) {
253 ERROR("Failed to enforce external storage policy");
258 if (id & WIPE_INTERNAL_STORAGE) {
259 runtime::Process proc(PROG_FACTORY_RESET, wipeCommand);
260 if (proc.execute() == -1) {
261 ERROR("Failed to launch factory-reset");
269 std::thread deviceWiper(worker);
270 deviceWiper.detach();
277 #define PRIVILEGE_SECURITY "http://tizen.org/privilege/dpm.security"
278 #define PRIVILEGE_WIPE "http://tizen.org/privilege/dpm.wipe"
279 #define PRIVILEGE_LOCK "http://tizen.org/privilege/dpm.lock"
281 AbstractPolicyProvider *PolicyFactory(PolicyControlContext& context)
283 Security *policy = new Security();
285 context.expose(policy, PRIVILEGE_SECURITY, (int)(Security::setInternalStorageEncryption)(bool));
286 context.expose(policy, PRIVILEGE_SECURITY, (int)(Security::setExternalStorageEncryption)(bool));
287 context.expose(policy, PRIVILEGE_WIPE, (int)(Security::wipeData)(int));
288 context.expose(policy, PRIVILEGE_LOCK, (int)(Security::lockoutScreen)());
290 context.expose(policy, "", (bool)(Security::isInternalStorageEncrypted)());
291 context.expose(policy, "", (bool)(Security::isExternalStorageEncrypted)());