1 /*
2 * Copyright (c) 2022 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 "ohos_web_data_base_adapter_impl.h"
17
18 #include <cinttypes>
19 #include <securec.h>
20 #include <unistd.h>
21
22 #include "application_context.h"
23 #include "nweb_log.h"
24 #include "rdb_sql_utils.h"
25
26 using namespace OHOS::NativeRdb;
27 using namespace OHOS::NWeb;
28
29 namespace {
30 static const int32_t RDB_VERSION = 1;
31 static const std::string HTTP_AUTH_DATABASE_FILE = "http_auth.db";
32
33 static const std::string ID_COL = "_id";
34 static const std::string HTTPAUTH_TABLE_NAME = "httpauth";
35 static const std::string HTTPAUTH_HOST_COL = "host";
36 static const std::string HTTPAUTH_REALM_COL = "realm";
37 static const std::string HTTPAUTH_USERNAME_COL = "username";
38 static const std::string HTTPAUTH_PASSWORD_COL = "password";
39
40 static const std::string CREATE_TABLE = "CREATE TABLE " + HTTPAUTH_TABLE_NAME
41 + " (" + ID_COL + " INTEGER PRIMARY KEY, "
42 + HTTPAUTH_HOST_COL + " TEXT, " + HTTPAUTH_REALM_COL
43 + " TEXT, " + HTTPAUTH_USERNAME_COL + " TEXT, "
44 + HTTPAUTH_PASSWORD_COL + " BLOB," + " UNIQUE ("
45 + HTTPAUTH_HOST_COL + ", " + HTTPAUTH_REALM_COL
46 + ") ON CONFLICT REPLACE);";
47
48 const std::string WEB_PATH = "/web";
49 }
50
OnCreate(OHOS::NativeRdb::RdbStore & store)51 int32_t DataBaseRdbOpenCallBack::OnCreate(OHOS::NativeRdb::RdbStore& store)
52 {
53 WVLOG_I("webdatabase rdb opened, create table: %{public}s", CREATE_TABLE.c_str());
54 return store.ExecuteSql(CREATE_TABLE);
55 }
56
OnUpgrade(OHOS::NativeRdb::RdbStore & rdbStore,int32_t currentVersion,int32_t targetVersion)57 int32_t DataBaseRdbOpenCallBack::OnUpgrade(OHOS::NativeRdb::RdbStore& rdbStore,
58 int32_t currentVersion, int32_t targetVersion)
59 {
60 WVLOG_I("webdatabase rdb upgrade");
61 return OHOS::NativeRdb::E_OK;
62 }
63
GetInstance()64 OhosWebDataBaseAdapterImpl& OhosWebDataBaseAdapterImpl::GetInstance()
65 {
66 WVLOG_I("webdatabase get data base instance");
67 static OhosWebDataBaseAdapterImpl instance;
68 return instance;
69 }
70
OhosWebDataBaseAdapterImpl(std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)71 OhosWebDataBaseAdapterImpl::OhosWebDataBaseAdapterImpl(std::shared_ptr<OHOS::NativeRdb::RdbStore> rdbStore)
72 {
73 rdbStore_ = rdbStore;
74 }
75
OhosWebDataBaseAdapterImpl()76 OhosWebDataBaseAdapterImpl::OhosWebDataBaseAdapterImpl()
77 {
78 WVLOG_I("webdatabase create rdb store");
79 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
80 OHOS::AbilityRuntime::ApplicationContext::GetApplicationContext();
81 if (context == nullptr) {
82 WVLOG_E("webdatabase get context failed");
83 return;
84 }
85
86 std::string databaseDir = context->GetCacheDir() + WEB_PATH;
87 if (access(databaseDir.c_str(), F_OK) != 0) {
88 WVLOG_I("webdatabase fail to access cache web dir:%{public}s", databaseDir.c_str());
89 return;
90 }
91
92 std::string bundleName = context->GetBundleName();
93 std::string name = HTTP_AUTH_DATABASE_FILE;
94 int32_t errorCode = E_OK;
95 std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, name, errorCode);
96 RdbStoreConfig config("");
97 config.SetPath(std::move(realPath));
98 config.SetBundleName(bundleName);
99 config.SetName(std::move(name));
100 config.SetArea(context->GetArea());
101 config.SetEncryptStatus(true);
102 WVLOG_I("webdatabase databaseDir=%{public}s", databaseDir.c_str());
103 WVLOG_I("webdatabase bundleName=%{public}s", bundleName.c_str());
104
105 int32_t errCode = NativeRdb::E_OK;
106 DataBaseRdbOpenCallBack callBack;
107 rdbStore_ = RdbHelper::GetRdbStore(config, RDB_VERSION, callBack, errCode);
108 if (rdbStore_ == nullptr) {
109 WVLOG_I("webdatabase get rdb store failed, errCode=%{public}d", errCode);
110 }
111 WVLOG_I("webdatabase create rdb store end");
112 }
113
SaveHttpAuthCredentials(const std::string & host,const std::string & realm,const std::string & username,const char * password)114 void OhosWebDataBaseAdapterImpl::SaveHttpAuthCredentials(const std::string& host, const std::string& realm,
115 const std::string& username, const char* password)
116 {
117 WVLOG_I("webdatabase save http auth info");
118 if (host.empty() || username.empty() || password == nullptr) {
119 return;
120 }
121 if (rdbStore_ == nullptr) {
122 return;
123 }
124
125 int32_t errCode;
126 int64_t outRowId;
127 std::vector<uint8_t> passwordVector(password, password + strlen(password));
128 NativeRdb::ValuesBucket valuesBucket;
129 valuesBucket.Clear();
130 valuesBucket.PutString(HTTPAUTH_HOST_COL, host);
131 valuesBucket.PutString(HTTPAUTH_REALM_COL, realm);
132 valuesBucket.PutString(HTTPAUTH_USERNAME_COL, username);
133 valuesBucket.PutBlob(HTTPAUTH_PASSWORD_COL, passwordVector);
134 (void)memset_s(&passwordVector[0], passwordVector.size(), 0, passwordVector.size());
135 errCode = rdbStore_->Insert(outRowId, HTTPAUTH_TABLE_NAME, valuesBucket);
136 if (errCode != NativeRdb::E_OK) {
137 WVLOG_E("webdatabase rdb store insert failed, errCode=%{public}d", errCode);
138 return;
139 }
140 WVLOG_I("webdatabase save http auth info end");
141 }
142
GetHttpAuthCredentials(const std::string & host,const std::string & realm,std::string & username,char * password,uint32_t passwordSize)143 void OhosWebDataBaseAdapterImpl::GetHttpAuthCredentials(const std::string& host, const std::string& realm,
144 std::string& username, char* password, uint32_t passwordSize)
145 {
146 WVLOG_I("webdatabase get username and password");
147 if (host.empty() || password == nullptr || passwordSize == 0) {
148 return;
149 }
150 if (rdbStore_ == nullptr) {
151 return;
152 }
153
154 std::vector<std::string> columns;
155 NativeRdb::AbsRdbPredicates dirAbsPred(HTTPAUTH_TABLE_NAME);
156 dirAbsPred.EqualTo(HTTPAUTH_HOST_COL, host);
157 dirAbsPred.EqualTo(HTTPAUTH_REALM_COL, realm);
158 auto resultSet = rdbStore_->Query(dirAbsPred, columns);
159 if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != NativeRdb::E_OK)) {
160 WVLOG_E("webdatabase rdb store query failed");
161 return;
162 }
163
164 int32_t columnIndex;
165 std::vector<uint8_t> passwordVector;
166 resultSet->GetColumnIndex(HTTPAUTH_USERNAME_COL, columnIndex);
167 resultSet->GetString(columnIndex, username);
168 resultSet->GetColumnIndex(HTTPAUTH_PASSWORD_COL, columnIndex);
169 resultSet->GetBlob(columnIndex, passwordVector);
170
171 if (passwordVector.size() > passwordSize - 1) {
172 WVLOG_E("webdatabase get credential fail: pwd too long");
173 return;
174 }
175 if (memcpy_s(password, passwordSize - 1, &passwordVector[0], passwordVector.size()) != EOK) {
176 WVLOG_E("webdatabase get credential fail: memcpy fail");
177 return;
178 }
179 password[passwordVector.size()] = 0;
180 (void)memset_s(&passwordVector[0], passwordVector.size(), 0, passwordVector.size());
181 }
182
ExistHttpAuthCredentials()183 bool OhosWebDataBaseAdapterImpl::ExistHttpAuthCredentials()
184 {
185 WVLOG_I("webdatabase check exist http auth info");
186 if (rdbStore_ == nullptr) {
187 return false;
188 }
189
190 int64_t outValue = 0;
191 NativeRdb::AbsRdbPredicates dirAbsPred(HTTPAUTH_TABLE_NAME);
192 if (rdbStore_->Count(outValue, dirAbsPred) != NativeRdb::E_OK) {
193 return false;
194 }
195 WVLOG_I("webdatabase exist http auth info num = %{public}" PRId64, outValue);
196 if (outValue <= 0) {
197 return false;
198 }
199 return true;
200 }
201
DeleteHttpAuthCredentials()202 void OhosWebDataBaseAdapterImpl::DeleteHttpAuthCredentials()
203 {
204 WVLOG_I("webdatabase clear all http auth info");
205 if (rdbStore_ == nullptr) {
206 return;
207 }
208 int32_t deletedRows = 0;
209 NativeRdb::AbsRdbPredicates dirAbsPred(HTTPAUTH_TABLE_NAME);
210 int32_t ret = rdbStore_->Delete(deletedRows, dirAbsPred);
211 WVLOG_I("webdatabase clear all http auth info: ret=%{public}d, deletedRows=%{public}d", ret, deletedRows);
212 return;
213 }
214