1 /*
2  * Copyright (C) 2021-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <functional>
17 #include <iostream>
18 #include <map>
19 #include <string>
20 #include <vector>
21 
22 #include "client/storage_manager_client.h"
23 #include "storage_daemon_client.h"
24 #include "storage_service_log.h"
25 #include "utils/file_utils.h"
26 
27 constexpr int32_t ARG_CNT_2 = 2;
28 constexpr size_t INDEX_1 = 1;
29 constexpr size_t INDEX_2 = 2;
30 
31 #ifdef SDC_TEST_ENABLE
32 constexpr int32_t ARG_CNT_4 = 4;
33 constexpr int32_t ARG_CNT_5 = 5;
34 constexpr int32_t ARG_CNT_6 = 6;
35 constexpr size_t INDEX_3 = 3;
36 constexpr size_t INDEX_4 = 4;
37 constexpr size_t INDEX_5 = 5;
38 #endif
39 
InitGlobalKey(const std::vector<std::string> & args)40 static int32_t InitGlobalKey(const std::vector<std::string> &args)
41 {
42     (void)args;
43     return OHOS::StorageDaemon::StorageDaemonClient::InitGlobalKey();
44 }
45 
InitMainUser(const std::vector<std::string> & args)46 static int32_t InitMainUser(const std::vector<std::string> &args)
47 {
48     (void)args;
49     return OHOS::StorageDaemon::StorageDaemonClient::InitGlobalUserKeys();
50 }
51 
52 #ifdef SDC_TEST_ENABLE
GenerateUserKeys(const std::vector<std::string> & args)53 static int32_t GenerateUserKeys(const std::vector<std::string> &args)
54 {
55     if (args.size() < ARG_CNT_5) {
56         LOGE("Parameter nums is less than 5, please retry");
57         return -EINVAL;
58     }
59     uint32_t userId;
60     uint32_t flags;
61     // 3 means take the fourth argument of args, 4 means take the fifth argument of args
62     if ((OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) ||
63         (OHOS::StorageDaemon::StringToUint32(args[INDEX_4], flags) == false)) {
64         LOGE("Parameter input error, please retry");
65         return -EINVAL;
66     }
67     return OHOS::StorageDaemon::StorageDaemonClient::GenerateUserKeys(userId, flags);
68 }
69 
PrepareUserSpace(const std::vector<std::string> & args)70 static int32_t PrepareUserSpace(const std::vector<std::string> &args)
71 {
72     if (args.size() < ARG_CNT_5) {
73         LOGE("Parameter nums is less than 5, please retry");
74         return -EINVAL;
75     }
76     uint32_t userId;
77     uint32_t flags;
78     // 3 means take the fourth argument of args, 4 means take the fifth argument of args
79     if ((OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) ||
80         (OHOS::StorageDaemon::StringToUint32(args[INDEX_4], flags) == false)) {
81         LOGE("Parameter input error, please retry");
82         return -EINVAL;
83     }
84     return OHOS::StorageDaemon::StorageDaemonClient::PrepareUserDirs(userId, flags);
85 }
86 
DeleteUserKeys(const std::vector<std::string> & args)87 static int32_t DeleteUserKeys(const std::vector<std::string> &args)
88 {
89     if (args.size() < ARG_CNT_4) {
90         LOGE("Parameter nums is less than 4, please retry");
91         return -EINVAL;
92     }
93     uint32_t userId;
94     // 3 means take the fourth argument of args
95     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
96         LOGE("Parameter input error, please retry");
97         return -EINVAL;
98     }
99     return OHOS::StorageDaemon::StorageDaemonClient::DeleteUserKeys(userId);
100 }
101 
DestroyUserSpace(const std::vector<std::string> & args)102 static int32_t DestroyUserSpace(const std::vector<std::string> &args)
103 {
104     if (args.size() < ARG_CNT_5) {
105         LOGE("Parameter nums is less than 5, please retry");
106         return -EINVAL;
107     }
108     uint32_t userId;
109     uint32_t flags;
110     // 3 means take the fourth argument of args, 4 means take the fifth argument of args
111     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false ||
112         OHOS::StorageDaemon::StringToUint32(args[INDEX_4], flags) == false) {
113         LOGE("Parameter input error, please retry");
114         return -EINVAL;
115     }
116     return OHOS::StorageDaemon::StorageDaemonClient::DestroyUserDirs(userId, flags);
117 }
118 
UpdateUserAuth(const std::vector<std::string> & args)119 static int32_t UpdateUserAuth(const std::vector<std::string> &args)
120 {
121     if (args.size() < ARG_CNT_5) {
122         LOGE("Parameter nums is less than 5, please retry");
123         return -EINVAL;
124     }
125     uint32_t userId;
126     // 3 means take the fourth argument of args
127     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
128         LOGE("Parameter input error, please retry");
129         return -EINVAL;
130     }
131 
132     // 4 means take the fifth argument of args, 5 means take the sixth argument of args
133     if (args.size() == ARG_CNT_6) {
134         std::vector<uint8_t> oldSecret(args[INDEX_4].begin(), args[INDEX_4].end());
135         std::vector<uint8_t> newSecret(args[INDEX_5].begin(), args[INDEX_5].end());
136         return OHOS::StorageDaemon::StorageDaemonClient::UpdateUserAuth(userId, 0, {}, oldSecret, newSecret);
137     }
138     std::vector<uint8_t> newSecret(args[INDEX_4].begin(), args[INDEX_4].end());
139     return OHOS::StorageDaemon::StorageDaemonClient::UpdateUserAuth(userId, 0, {}, {}, newSecret);
140 }
141 
ActiveUserKey(const std::vector<std::string> & args)142 static int32_t ActiveUserKey(const std::vector<std::string> &args)
143 {
144     if (args.size() < ARG_CNT_4) {
145         LOGE("Parameter nums is less than 4, please retry");
146         return -EINVAL;
147     }
148     uint32_t userId;
149     // 3 means take the fourth argument of args
150     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
151         LOGE("Parameter input error, please retry");
152         return -EINVAL;
153     }
154     // 4 means take the fifth argument of args
155     if (args.size() == ARG_CNT_5) {
156         std::vector<uint8_t> secret(args[INDEX_4].begin(), args[INDEX_4].end());
157         return OHOS::StorageDaemon::StorageDaemonClient::ActiveUserKey(userId, {}, secret);
158     }
159     return OHOS::StorageDaemon::StorageDaemonClient::ActiveUserKey(userId, {}, {});
160 }
161 
InactiveUserKey(const std::vector<std::string> & args)162 static int32_t InactiveUserKey(const std::vector<std::string> &args)
163 {
164     if (args.size() < ARG_CNT_4) {
165         LOGE("Parameter nums is less than 4, please retry");
166         return -EINVAL;
167     }
168     uint32_t userId;
169     // 3 means take the fourth argument of args
170     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
171         LOGE("Parameter input error, please retry");
172         return -EINVAL;
173     }
174     return OHOS::StorageDaemon::StorageDaemonClient::InactiveUserKey(userId);
175 }
176 
LockUserScreen(const std::vector<std::string> & args)177 static int32_t LockUserScreen(const std::vector<std::string> &args)
178 {
179     if (args.size() < ARG_CNT_4) {
180         LOGE("Parameter nums is less than 4, please retry");
181         return -EINVAL;
182     }
183     uint32_t userId;
184     // 3 means take the fourth argument of args
185     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
186         LOGE("Parameter input error, please retry");
187         return -EINVAL;
188     }
189     return OHOS::StorageDaemon::StorageDaemonClient::LockUserScreen(userId);
190 }
191 
UnlockUserScreen(const std::vector<std::string> & args)192 static int32_t UnlockUserScreen(const std::vector<std::string> &args)
193 {
194     if (args.size() < ARG_CNT_4) {
195         LOGE("Parameter nums is less than 4, please retry");
196         return -EINVAL;
197     }
198     uint32_t userId;
199     // 3 means take the fourth argument of args
200     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
201         LOGE("Parameter input error, please retry");
202         return -EINVAL;
203     }
204     // 4 means take the fifth argument of args
205     if (args.size() == ARG_CNT_5) {
206         std::vector<uint8_t> secret(args[INDEX_4].begin(), args[INDEX_4].end());
207         return OHOS::StorageDaemon::StorageDaemonClient::UnlockUserScreen(userId, {}, secret);
208     }
209     return OHOS::StorageDaemon::StorageDaemonClient::UnlockUserScreen(userId, {}, {});
210 }
211 
GetFileEncryptStatus(const std::vector<std::string> & args)212 int32_t GetFileEncryptStatus(const std::vector<std::string> &args)
213 {
214     if (args.size() < ARG_CNT_5) {
215         LOGE("Parameter nums is less than 4, please retry");
216         return -EINVAL;
217     }
218     uint32_t userId;
219     // 3 means take the fourth argument of args
220     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
221         LOGE("Parameter input error, please retry");
222         return -EINVAL;
223     }
224     uint32_t judge;
225     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_4], judge) == false) {
226         LOGE("Parameter input error, please retry");
227         return -EINVAL;
228     }
229     bool isEncrypted = true;
230     bool judgeFlag = judge != 0;
231     return OHOS::StorageDaemon::StorageDaemonClient::GetFileEncryptStatus(userId, isEncrypted, judgeFlag);
232 }
233 
EnableFscrypt(const std::vector<std::string> & args)234 static int32_t EnableFscrypt(const std::vector<std::string> &args)
235 {
236     if (args.size() < ARG_CNT_4) {
237         LOGE("Parameter nums is less than 4, please retry");
238         return -EINVAL;
239     }
240     auto option = args[INDEX_3]; // cmd no.3 param is the option
241     return OHOS::StorageDaemon::StorageDaemonClient::FscryptEnable(option);
242 }
243 
UpdateKeyContext(const std::vector<std::string> & args)244 static int32_t UpdateKeyContext(const std::vector<std::string> &args)
245 {
246     if (args.size() < ARG_CNT_4) {
247         LOGE("Parameter nums is less than 4, please retry");
248         return -EINVAL;
249     }
250     uint32_t userId;
251     // 3 means take the fourth argument of args
252     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
253         LOGE("Parameter input error, please retry");
254         return -EINVAL;
255     }
256     return OHOS::StorageDaemon::StorageDaemonClient::UpdateKeyContext(userId);
257 }
258 
GenerateAppkey(const std::vector<std::string> & args)259 static int32_t GenerateAppkey(const std::vector<std::string> &args)
260 {
261     if (args.size() < ARG_CNT_4) {
262         LOGE("Parameter nums is less than 4, please retry");
263         return -EINVAL;
264     }
265     uint32_t userId;
266     // 3 means take the fourth argument of args
267     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
268         LOGE("Parameter input error, please retry");
269         return -EINVAL;
270     }
271     uint32_t hashId = 0;
272     std::string keyId;
273     return OHOS::StorageDaemon::StorageDaemonClient::GenerateAppkey(userId, hashId, keyId);
274 }
275 
DeleteAppkey(const std::vector<std::string> & args)276 static int32_t DeleteAppkey(const std::vector<std::string> &args)
277 {
278     if (args.size() < ARG_CNT_4) {
279         LOGE("Parameter nums is less than 4, please retry");
280         return -EINVAL;
281     }
282     uint32_t userId;
283     // 3 means take the fourth argument of args
284     if (OHOS::StorageDaemon::StringToUint32(args[INDEX_3], userId) == false) {
285         LOGE("Parameter input error, please retry");
286         return -EINVAL;
287     }
288     std::string keyId = args[INDEX_4];
289     return OHOS::StorageDaemon::StorageDaemonClient::DeleteAppkey(userId, keyId);
290 }
291 #endif
292 
293 static const auto g_fscryptCmdHandler = std::map<std::string,
294     std::function<int32_t(const std::vector<std::string> &)>> {
295     {"init_global_key", InitGlobalKey},
296     {"init_main_user", InitMainUser},
297 #ifdef SDC_TEST_ENABLE
298     {"generate_user_keys", GenerateUserKeys},
299     {"prepare_user_space", PrepareUserSpace},
300     {"delete_user_keys", DeleteUserKeys},
301     {"destroy_user_space", DestroyUserSpace},
302     {"update_user_auth", UpdateUserAuth},
303     {"active_user_key", ActiveUserKey},
304     {"inactive_user_key", InactiveUserKey},
305     {"enable", EnableFscrypt},
306     {"update_key_context", UpdateKeyContext},
307     {"lock_user_screen", LockUserScreen},
308     {"unlock_user_screen", UnlockUserScreen},
309     {"generate_app_key", GenerateAppkey},
310     {"delete_app_key", DeleteAppkey},
311     {"Get_unlock_status", GetFileEncryptStatus},
312 #endif
313 };
314 
HandleFileCrypt(const std::string & cmd,const std::vector<std::string> & args)315 static int HandleFileCrypt(const std::string &cmd, const std::vector<std::string> &args)
316 {
317     LOGI("fscrypt cmd: %{public}s", cmd.c_str());
318 
319     auto handler = g_fscryptCmdHandler.find(cmd);
320     if (handler == g_fscryptCmdHandler.end()) {
321         LOGE("Unknown fscrypt cmd: %{public}s", cmd.c_str());
322         return -EINVAL;
323     }
324     auto ret = handler->second(args);
325     if (ret != 0) {
326         LOGE("fscrypt cmd: %{public}s failed, ret: %{public}d", cmd.c_str(), ret);
327     } else {
328         LOGI("fscrypt cmd: %{public}s success", cmd.c_str());
329     }
330     return ret;
331 }
332 
main(int argc,char ** argv)333 int main(int argc, char **argv)
334 {
335     LOGI("sdc start");
336     std::vector<std::string> args(argv, argv + argc);
337 
338     if (argc < ARG_CNT_2) {
339         LOGE("usage: sdc <subsystem> [cmd]");
340         return 0;
341     }
342 
343     int ret = 0;
344     // no.1 param is the cmd
345     if (args[INDEX_1] == "filecrypt") {
346         ret = HandleFileCrypt(args[INDEX_2], args); // no.2 param is the cmd
347     } else {
348         LOGE("Unknown subsystem: %{public}s", args[INDEX_1].c_str()); // no.1 param is the cmd
349         ret = -EINVAL;
350     }
351 
352     LOGI("sdc end");
353     std::cout << "ret: " << ret << std::endl;
354     return ret;
355 }
356