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()71 OhosWebDataBaseAdapterImpl::OhosWebDataBaseAdapterImpl()
72 {
73 WVLOG_I("webdatabase create rdb store");
74 std::shared_ptr<AbilityRuntime::ApplicationContext> context =
75 OHOS::AbilityRuntime::ApplicationContext::GetApplicationContext();
76 if (context == nullptr) {
77 WVLOG_E("webdatabase get context failed");
78 return;
79 }
80
81 std::string databaseDir = context->GetCacheDir() + WEB_PATH;
82 if (access(databaseDir.c_str(), F_OK) != 0) {
83 WVLOG_I("webdatabase fail to access cache web dir:%{public}s", databaseDir.c_str());
84 return;
85 }
86
87 std::string bundleName = context->GetBundleName();
88 std::string name = HTTP_AUTH_DATABASE_FILE;
89 int32_t errorCode = E_OK;
90 std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, name, errorCode);
91 RdbStoreConfig config("");
92 config.SetPath(std::move(realPath));
93 config.SetBundleName(bundleName);
94 config.SetName(std::move(name));
95 config.SetArea(context->GetArea());
96 config.SetEncryptStatus(true);
97 WVLOG_I("webdatabase databaseDir=%{public}s", databaseDir.c_str());
98 WVLOG_I("webdatabase bundleName=%{public}s", bundleName.c_str());
99
100 int32_t errCode = NativeRdb::E_OK;
101 DataBaseRdbOpenCallBack callBack;
102 rdbStore_ = RdbHelper::GetRdbStore(config, RDB_VERSION, callBack, errCode);
103 if (rdbStore_ == nullptr) {
104 WVLOG_I("webdatabase get rdb store failed, errCode=%{public}d", errCode);
105 }
106 WVLOG_I("webdatabase create rdb store end");
107 }
108
SaveHttpAuthCredentials(const std::string & host,const std::string & realm,const std::string & username,const char * password)109 void OhosWebDataBaseAdapterImpl::SaveHttpAuthCredentials(const std::string& host, const std::string& realm,
110 const std::string& username, const char* password)
111 {
112 WVLOG_I("webdatabase save http auth info");
113 if (host.empty() || username.empty() || password == nullptr) {
114 return;
115 }
116 if (rdbStore_ == nullptr) {
117 return;
118 }
119
120 int32_t errCode;
121 int64_t outRowId;
122 std::vector<uint8_t> passwordVector(password, password + strlen(password));
123 NativeRdb::ValuesBucket valuesBucket;
124 valuesBucket.Clear();
125 valuesBucket.PutString(HTTPAUTH_HOST_COL, host);
126 valuesBucket.PutString(HTTPAUTH_REALM_COL, realm);
127 valuesBucket.PutString(HTTPAUTH_USERNAME_COL, username);
128 valuesBucket.PutBlob(HTTPAUTH_PASSWORD_COL, passwordVector);
129 (void)memset_s(&passwordVector[0], passwordVector.size(), 0, passwordVector.size());
130 errCode = rdbStore_->Insert(outRowId, HTTPAUTH_TABLE_NAME, valuesBucket);
131 if (errCode != NativeRdb::E_OK) {
132 WVLOG_E("webdatabase rdb store insert failed, errCode=%{public}d", errCode);
133 return;
134 }
135 WVLOG_I("webdatabase save http auth info end");
136 }
137
GetHttpAuthCredentials(const std::string & host,const std::string & realm,std::string & username,char * password,uint32_t passwordSize)138 void OhosWebDataBaseAdapterImpl::GetHttpAuthCredentials(const std::string& host, const std::string& realm,
139 std::string& username, char* password, uint32_t passwordSize)
140 {
141 WVLOG_I("webdatabase get username and password");
142 if (host.empty() || password == nullptr || passwordSize == 0) {
143 return;
144 }
145 if (rdbStore_ == nullptr) {
146 return;
147 }
148
149 std::vector<std::string> columns;
150 NativeRdb::AbsRdbPredicates dirAbsPred(HTTPAUTH_TABLE_NAME);
151 dirAbsPred.EqualTo(HTTPAUTH_HOST_COL, host);
152 dirAbsPred.EqualTo(HTTPAUTH_REALM_COL, realm);
153 auto resultSet = rdbStore_->Query(dirAbsPred, columns);
154 if ((resultSet == nullptr) || (resultSet->GoToFirstRow() != NativeRdb::E_OK)) {
155 WVLOG_E("webdatabase rdb store query failed");
156 return;
157 }
158
159 int32_t columnIndex;
160 std::vector<uint8_t> passwordVector;
161 resultSet->GetColumnIndex(HTTPAUTH_USERNAME_COL, columnIndex);
162 resultSet->GetString(columnIndex, username);
163 resultSet->GetColumnIndex(HTTPAUTH_PASSWORD_COL, columnIndex);
164 resultSet->GetBlob(columnIndex, passwordVector);
165
166 if (passwordVector.size() > passwordSize - 1) {
167 WVLOG_E("webdatabase get credential fail: pwd too long");
168 return;
169 }
170 if (memcpy_s(password, passwordSize - 1, &passwordVector[0], passwordVector.size()) != EOK) {
171 WVLOG_E("webdatabase get credential fail: memcpy fail");
172 return;
173 }
174 password[passwordVector.size()] = 0;
175 (void)memset_s(&passwordVector[0], passwordVector.size(), 0, passwordVector.size());
176 }
177
ExistHttpAuthCredentials()178 bool OhosWebDataBaseAdapterImpl::ExistHttpAuthCredentials()
179 {
180 WVLOG_I("webdatabase check exist http auth info");
181 if (rdbStore_ == nullptr) {
182 return false;
183 }
184
185 int64_t outValue = 0;
186 NativeRdb::AbsRdbPredicates dirAbsPred(HTTPAUTH_TABLE_NAME);
187 if (rdbStore_->Count(outValue, dirAbsPred) != NativeRdb::E_OK) {
188 return false;
189 }
190 WVLOG_I("webdatabase exist http auth info num = %{public}" PRId64, outValue);
191 if (outValue <= 0) {
192 return false;
193 }
194 return true;
195 }
196
DeleteHttpAuthCredentials()197 void OhosWebDataBaseAdapterImpl::DeleteHttpAuthCredentials()
198 {
199 WVLOG_I("webdatabase clear all http auth info");
200 if (rdbStore_ == nullptr) {
201 return;
202 }
203 int32_t deletedRows = 0;
204 NativeRdb::AbsRdbPredicates dirAbsPred(HTTPAUTH_TABLE_NAME);
205 int32_t ret = rdbStore_->Delete(deletedRows, dirAbsPred);
206 WVLOG_I("webdatabase clear all http auth info: ret=%{public}d, deletedRows=%{public}d", ret, deletedRows);
207 return;
208 }
209