1 /*
2 * Copyright (c) 2021 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 "param_check_utils.h"
17
18 #include "db_common.h"
19 #include "db_errno.h"
20 #include "platform_specific.h"
21 #include "log_print.h"
22
23 namespace DistributedDB {
CheckDataDir(const std::string & dataDir,std::string & canonicalDir)24 bool ParamCheckUtils::CheckDataDir(const std::string &dataDir, std::string &canonicalDir)
25 {
26 if (dataDir.empty() || (dataDir.length() > DBConstant::MAX_DATA_DIR_LENGTH)) {
27 LOGE("Invalid data directory[%zu]", dataDir.length());
28 return false;
29 }
30
31 if (OS::GetRealPath(dataDir, canonicalDir) != E_OK) {
32 return false;
33 }
34 // After normalizing the path, determine whether the path is a legal path considered by the program.
35 // There has been guaranteed by the upper layer, So there is no need trustlist set here.
36 return true;
37 }
38
IsStoreIdSafe(const std::string & storeId)39 bool ParamCheckUtils::IsStoreIdSafe(const std::string &storeId)
40 {
41 if (storeId.empty() || (storeId.length() > DBConstant::MAX_STORE_ID_LENGTH)) {
42 LOGE("Invalid store id[%zu]", storeId.length());
43 return false;
44 }
45
46 auto iter = std::find_if_not(storeId.begin(), storeId.end(),
47 [](char value) { return (std::isalnum(value) || value == '_'); });
48 if (iter != storeId.end()) {
49 LOGE("Invalid store id format");
50 return false;
51 }
52 return true;
53 }
54
CheckStoreParameter(const std::string & storeId,const std::string & appId,const std::string & userId,bool isIgnoreUserIdCheck)55 bool ParamCheckUtils::CheckStoreParameter(const std::string &storeId, const std::string &appId,
56 const std::string &userId, bool isIgnoreUserIdCheck)
57 {
58 if (!IsStoreIdSafe(storeId)) {
59 return false;
60 }
61 if (!isIgnoreUserIdCheck) {
62 if (userId.empty() || userId.length() > DBConstant::MAX_USER_ID_LENGTH) {
63 LOGE("Invalid user info[%zu][%zu]", userId.length(), appId.length());
64 return false;
65 }
66 if (userId.find(DBConstant::ID_CONNECTOR) != std::string::npos) {
67 LOGE("Invalid userId character in the store para info.");
68 return false;
69 }
70 }
71 if (appId.empty() || appId.length() > DBConstant::MAX_APP_ID_LENGTH) {
72 LOGE("Invalid app info[%zu][%zu]", userId.length(), appId.length());
73 return false;
74 }
75
76 if ((appId.find(DBConstant::ID_CONNECTOR) != std::string::npos) ||
77 (storeId.find(DBConstant::ID_CONNECTOR) != std::string::npos)) {
78 LOGE("Invalid character in the store para info.");
79 return false;
80 }
81 return true;
82 }
83
CheckEncryptedParameter(CipherType cipher,const CipherPassword & passwd)84 bool ParamCheckUtils::CheckEncryptedParameter(CipherType cipher, const CipherPassword &passwd)
85 {
86 if (cipher != CipherType::DEFAULT && cipher != CipherType::AES_256_GCM) {
87 LOGE("Invalid cipher type!");
88 return false;
89 }
90
91 return (passwd.GetSize() != 0);
92 }
93
CheckConflictNotifierType(int conflictType)94 bool ParamCheckUtils::CheckConflictNotifierType(int conflictType)
95 {
96 if (conflictType <= 0) {
97 return false;
98 }
99 // Divide the type into different types.
100 if (conflictType >= CONFLICT_NATIVE_ALL) {
101 conflictType -= CONFLICT_NATIVE_ALL;
102 }
103 if (conflictType >= CONFLICT_FOREIGN_KEY_ORIG) {
104 conflictType -= CONFLICT_FOREIGN_KEY_ORIG;
105 }
106 if (conflictType >= CONFLICT_FOREIGN_KEY_ONLY) {
107 conflictType -= CONFLICT_FOREIGN_KEY_ONLY;
108 }
109 if (conflictType != 0) {
110 return false;
111 }
112 return true;
113 }
114
CheckSecOption(const SecurityOption & secOption)115 bool ParamCheckUtils::CheckSecOption(const SecurityOption &secOption)
116 {
117 if (secOption.securityLabel > S4 || secOption.securityLabel < NOT_SET) {
118 LOGE("[DBCommon] SecurityLabel is invalid, label is [%d].", secOption.securityLabel);
119 return false;
120 }
121 if (secOption.securityFlag != 0) {
122 if ((secOption.securityLabel != S3 && secOption.securityLabel != S4) || secOption.securityFlag != SECE) {
123 LOGE("[DBCommon] SecurityFlag is invalid.");
124 return false;
125 }
126 }
127 return true;
128 }
129
CheckObserver(const Key & key,unsigned int mode)130 bool ParamCheckUtils::CheckObserver(const Key &key, unsigned int mode)
131 {
132 if (key.size() > DBConstant::MAX_KEY_SIZE) {
133 return false;
134 }
135
136 if (mode > OBSERVER_CHANGES_LOCAL_ONLY || mode < OBSERVER_CHANGES_NATIVE) {
137 return false;
138 }
139 return true;
140 }
141
IsS3SECEOpt(const SecurityOption & secOpt)142 bool ParamCheckUtils::IsS3SECEOpt(const SecurityOption &secOpt)
143 {
144 SecurityOption S3SeceOpt = {SecurityLabel::S3, SecurityFlag::SECE};
145 return (secOpt == S3SeceOpt);
146 }
147
CheckAndTransferAutoLaunchParam(const AutoLaunchParam & param,bool checkDir,SchemaObject & schemaObject,std::string & canonicalDir)148 int ParamCheckUtils::CheckAndTransferAutoLaunchParam(const AutoLaunchParam ¶m, bool checkDir,
149 SchemaObject &schemaObject, std::string &canonicalDir)
150 {
151 if ((param.option.notifier && !ParamCheckUtils::CheckConflictNotifierType(param.option.conflictType)) ||
152 (!param.option.notifier && param.option.conflictType != 0)) {
153 LOGE("[AutoLaunch] CheckConflictNotifierType is invalid.");
154 return -E_INVALID_ARGS;
155 }
156 if (!ParamCheckUtils::CheckStoreParameter(param.storeId, param.appId, param.userId)) {
157 LOGE("[AutoLaunch] CheckStoreParameter is invalid.");
158 return -E_INVALID_ARGS;
159 }
160
161 const AutoLaunchOption &option = param.option;
162 if (!ParamCheckUtils::CheckSecOption(option.secOption)) {
163 LOGE("[AutoLaunch] CheckSecOption is invalid.");
164 return -E_INVALID_ARGS;
165 }
166
167 if (option.isEncryptedDb) {
168 if (!ParamCheckUtils::CheckEncryptedParameter(option.cipher, option.passwd)) {
169 LOGE("[AutoLaunch] CheckEncryptedParameter is invalid.");
170 return -E_INVALID_ARGS;
171 }
172 }
173
174 if (!param.option.schema.empty()) {
175 schemaObject.ParseFromSchemaString(param.option.schema);
176 if (!schemaObject.IsSchemaValid()) {
177 LOGE("[AutoLaunch] ParseFromSchemaString is invalid.");
178 return -E_INVALID_SCHEMA;
179 }
180 }
181
182 if (!checkDir) {
183 canonicalDir = param.option.dataDir;
184 return E_OK;
185 }
186
187 if (!ParamCheckUtils::CheckDataDir(param.option.dataDir, canonicalDir)) {
188 LOGE("[AutoLaunch] CheckDataDir is invalid.");
189 return -E_INVALID_ARGS;
190 }
191 return E_OK;
192 }
193
GetValidCompressionRate(uint8_t compressionRate)194 uint8_t ParamCheckUtils::GetValidCompressionRate(uint8_t compressionRate)
195 {
196 // Valid when between 1 and 100. When compressionRate is invalid, change it to default rate.
197 if (compressionRate < 1 || compressionRate > DBConstant::DEFAULT_COMPTRESS_RATE) {
198 LOGD("Invalid compression rate:%u.", compressionRate);
199 compressionRate = DBConstant::DEFAULT_COMPTRESS_RATE;
200 }
201 return compressionRate;
202 }
203
CheckRelationalTableName(const std::string & tableName)204 bool ParamCheckUtils::CheckRelationalTableName(const std::string &tableName)
205 {
206 if (!DBCommon::CheckIsAlnumAndUnderscore(tableName)) {
207 return false;
208 }
209 return tableName.compare(0, DBConstant::SYSTEM_TABLE_PREFIX.size(), DBConstant::SYSTEM_TABLE_PREFIX) != 0;
210 }
211 } // namespace DistributedDB
212