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