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