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