Increase timeout of client socket
[platform/core/appfw/pkgmgr-info.git] / src / server / certinfo_internal.c
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdbool.h>
22 #include <unistd.h>
23 #include <ctype.h>
24 #include <sys/smack.h>
25 #include <linux/limits.h>
26 #include <sys/stat.h>
27
28 #include <sqlite3.h>
29 #include <glib.h>
30
31 #include "pkgmgrinfo_basic.h"
32 #include "pkgmgrinfo_private.h"
33 #include "pkgmgrinfo_internal.h"
34 #include "pkgmgrinfo_debug.h"
35 #include "pkgmgr-info.h"
36
37 static int _pkginfo_get_cert(sqlite3 *db, int cert_id[], char *cert_info[])
38 {
39         static const char query[] =
40                         "SELECT cert_info "
41                         "FROM package_cert_index_info WHERE cert_id=?";
42         int ret;
43         sqlite3_stmt *stmt;
44         int i;
45
46         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
47         if (ret != SQLITE_OK) {
48                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
49                 return PMINFO_R_ERROR;
50         }
51
52         for (i = 0; i < MAX_CERT_TYPE; i++) {
53                 ret = sqlite3_bind_int(stmt, 1, cert_id[i]);
54                 if (ret != SQLITE_OK) {
55                         sqlite3_finalize(stmt);
56                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
57                         return PMINFO_R_ERROR;
58                 }
59
60                 ret = sqlite3_step(stmt);
61                 if (ret == SQLITE_DONE) {
62                         sqlite3_reset(stmt);
63                         sqlite3_clear_bindings(stmt);
64                         continue;
65                 } else if (ret != SQLITE_ROW) {
66                         _LOGE("step failed: %s", sqlite3_errmsg(db));
67                         sqlite3_finalize(stmt);
68                         return PMINFO_R_ERROR;
69                 }
70
71                 _save_column_str(stmt, 0, &cert_info[i]);
72                 sqlite3_reset(stmt);
73                 sqlite3_clear_bindings(stmt);
74         }
75
76         sqlite3_finalize(stmt);
77
78         return PMINFO_R_OK;
79 }
80
81 static int _pkginfo_get_certid(sqlite3 *db, const char *pkgid, int cert_id[])
82 {
83         static const char query[] =
84                         "SELECT author_root_cert, author_im_cert, "
85                         "author_signer_cert, dist_root_cert, "
86                         "dist_im_cert, dist_signer_cert, dist2_root_cert, "
87                         "dist2_im_cert, dist2_signer_cert "
88                         "FROM package_cert_info WHERE package=?";
89         int ret;
90         sqlite3_stmt *stmt;
91         int idx;
92
93         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
94         if (ret != SQLITE_OK) {
95                 _LOGE("prepare failed: %s", sqlite3_errmsg(db));
96                 return PMINFO_R_ERROR;
97         }
98
99         ret = sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC);
100         if (ret != SQLITE_OK) {
101                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
102                 sqlite3_finalize(stmt);
103                 return PMINFO_R_ERROR;
104         }
105
106         ret = sqlite3_step(stmt);
107         if (ret == SQLITE_DONE) {
108                 sqlite3_finalize(stmt);
109                 return PMINFO_R_ENOENT;
110         } else if (ret != SQLITE_ROW) {
111                 _LOGE("step failed: %s", sqlite3_errmsg(db));
112                 sqlite3_finalize(stmt);
113                 return PMINFO_R_ERROR;
114         }
115
116         idx = 0;
117         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_ROOT_CERT]);
118         _save_column_int(stmt, idx++,
119                         &cert_id[PMINFO_AUTHOR_INTERMEDIATE_CERT]);
120         _save_column_int(stmt, idx++, &cert_id[PMINFO_AUTHOR_SIGNER_CERT]);
121         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_ROOT_CERT]);
122         _save_column_int(stmt, idx++,
123                         &cert_id[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT]);
124         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR_SIGNER_CERT]);
125         _save_column_int(stmt, idx++, &cert_id[PMINFO_DISTRIBUTOR2_ROOT_CERT]);
126         _save_column_int(stmt, idx++,
127                         &cert_id[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT]);
128         _save_column_int(stmt, idx++,
129                         &cert_id[PMINFO_DISTRIBUTOR2_SIGNER_CERT]);
130
131         sqlite3_finalize(stmt);
132
133         return PMINFO_R_OK;
134 }
135
136 static int _pkginfo_get_certinfo(sqlite3 *db,
137                 const char *pkgid, pkgmgr_certinfo_x *info)
138 {
139         int ret;
140
141         ret = _pkginfo_get_certid(db, pkgid, info->cert_id);
142         if (ret != PMINFO_R_OK)
143                 return ret;
144
145         ret = _pkginfo_get_cert(db, info->cert_id, info->cert_info);
146         if (ret != PMINFO_R_OK)
147                 return ret;
148
149         return PMINFO_R_OK;
150 }
151
152 API int certinfo_internal_get(sqlite3 *db, const char *pkgid, uid_t uid,
153                 pkgmgrinfo_certinfo_h certinfo)
154 {
155         int ret;
156         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)certinfo;
157
158         if (db == NULL || pkgid == NULL || certinfo == NULL)
159                 return PMINFO_R_EINVAL;
160         ret = _pkginfo_get_certinfo(db, pkgid, info);
161         if (ret != PMINFO_R_OK)
162                 _LOGE("failed to get certinfo of %s ", pkgid);
163
164         return ret;
165 }
166
167 static int _pkginfo_save_cert_index_info(sqlite3 *db, char *cert_info[])
168 {
169         static const char query[] =
170                         "INSERT OR REPLACE INTO package_cert_index_info "
171                         "(cert_info, cert_id, cert_ref_count) "
172                         "VALUES ( "
173                         " ?, "
174                         " (SELECT cert_id FROM package_cert_index_info "
175                         "  WHERE cert_info=?), "
176                         " COALESCE( "
177                         "  ((SELECT cert_ref_count FROM package_cert_index_info "
178                         "    WHERE cert_info=?) + 1), 1))";
179         int ret;
180         sqlite3_stmt *stmt;
181         int i;
182         int idx;
183
184         ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
185         if (ret != SQLITE_OK) {
186                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
187                 return PMINFO_R_ERROR;
188         }
189
190         for (i = 0; i < MAX_CERT_TYPE; i++) {
191                 if (cert_info[i] == NULL)
192                         continue;
193                 idx = 1;
194                 ret = sqlite3_bind_text(stmt, idx++,
195                                 cert_info[i], -1, SQLITE_STATIC);
196                 if (ret != SQLITE_OK) {
197                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
198                         sqlite3_finalize(stmt);
199                         return PMINFO_R_ERROR;
200                 }
201                 ret = sqlite3_bind_text(stmt, idx++,
202                                 cert_info[i], -1, SQLITE_STATIC);
203                 if (ret != SQLITE_OK) {
204                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
205                         sqlite3_finalize(stmt);
206                         return PMINFO_R_ERROR;
207                 }
208                 ret = sqlite3_bind_text(stmt, idx++,
209                                 cert_info[i], -1, SQLITE_STATIC);
210                 if (ret != SQLITE_OK) {
211                         _LOGE("bind failed: %s", sqlite3_errmsg(db));
212                         sqlite3_finalize(stmt);
213                         return PMINFO_R_ERROR;
214                 }
215
216                 ret = sqlite3_step(stmt);
217                 if (ret != SQLITE_DONE) {
218                         _LOGE("step failed: %s", sqlite3_errmsg(db));
219                         sqlite3_finalize(stmt);
220                         return PMINFO_R_ERROR;
221                 }
222
223                 sqlite3_reset(stmt);
224                 sqlite3_clear_bindings(stmt);
225         }
226
227         sqlite3_finalize(stmt);
228
229         return PMINFO_R_OK;
230 }
231
232 static int _pkginfo_save_cert_info(sqlite3 *db,
233                 const char *pkgid, char *cert_info[])
234 {
235         static const char query_insert[] =
236                         "INSERT INTO package_cert_info (package, package_count,"
237                         " author_root_cert, author_im_cert, author_signer_cert,"
238                         " dist_root_cert, dist_im_cert, dist_signer_cert,"
239                         " dist2_root_cert, dist2_im_cert, dist2_signer_cert) "
240                         "VALUES(?, 1,"
241                         " (SELECT cert_id FROM package_cert_index_info"
242                         "       WHERE cert_info=?),"
243                         " (SELECT cert_id FROM package_cert_index_info"
244                         "       WHERE cert_info=?),"
245                         " (SELECT cert_id FROM package_cert_index_info"
246                         "       WHERE cert_info=?),"
247                         " (SELECT cert_id FROM package_cert_index_info"
248                         "       WHERE cert_info=?),"
249                         " (SELECT cert_id FROM package_cert_index_info"
250                         "       WHERE cert_info=?),"
251                         " (SELECT cert_id FROM package_cert_index_info"
252                         "       WHERE cert_info=?),"
253                         " (SELECT cert_id FROM package_cert_index_info"
254                         "       WHERE cert_info=?),"
255                         " (SELECT cert_id FROM package_cert_index_info"
256                         "       WHERE cert_info=?),"
257                         " (SELECT cert_id FROM package_cert_index_info"
258                         "       WHERE cert_info=?))";
259         static const char query_update[] =
260                         "UPDATE package_cert_info "
261                         "SET package_count = package_count + 1 "
262                         "WHERE package=?";
263         int ret;
264         sqlite3_stmt *stmt;
265         int i;
266         int idx;
267
268         ret = sqlite3_prepare_v2(db, query_insert,
269                         strlen(query_insert), &stmt, NULL);
270         if (ret != SQLITE_OK) {
271                 _LOGE("prepare error: %s", sqlite3_errmsg(db));
272                 return PMINFO_R_ERROR;
273         }
274
275         idx = 1;
276         ret = sqlite3_bind_text(stmt, idx++, pkgid, -1, SQLITE_STATIC);
277         if (ret != SQLITE_OK) {
278                 _LOGE("bind failed: %s", sqlite3_errmsg(db));
279                 sqlite3_finalize(stmt);
280                 return PMINFO_R_ERROR;
281         }
282
283         for (i = 0; i < MAX_CERT_TYPE; i++) {
284                 if (sqlite3_bind_text(stmt, idx++,
285                                 cert_info[i], -1, SQLITE_STATIC)) {
286                         _LOGE("bind error: %s", sqlite3_errmsg(db));
287                         sqlite3_finalize(stmt);
288                         return PMINFO_R_ERROR;
289                 }
290         }
291
292         ret = sqlite3_step(stmt);
293         sqlite3_finalize(stmt);
294         if (ret == SQLITE_CONSTRAINT) {
295                 ret = sqlite3_prepare_v2(db, query_update,
296                                 strlen(query_update), &stmt, NULL);
297                 if (ret != SQLITE_OK) {
298                         _LOGE("prepare error: %s", sqlite3_errmsg(db));
299                         return PMINFO_R_ERROR;
300                 }
301
302                 if (sqlite3_bind_text(stmt, 1, pkgid, -1, SQLITE_STATIC)) {
303                         _LOGE("bind error: %s", sqlite3_errmsg(db));
304                         sqlite3_finalize(stmt);
305                         return PMINFO_R_ERROR;
306                 }
307
308                 ret = sqlite3_step(stmt);
309                 sqlite3_finalize(stmt);
310         }
311
312         if (ret != SQLITE_DONE) {
313                 _LOGE("step error: %s", sqlite3_errmsg(db));
314                 return PMINFO_R_ERROR;
315         }
316
317         return PMINFO_R_OK;
318 }
319
320 API int certinfo_internal_set(sqlite3 *db, const char *pkgid,
321                 pkgmgrinfo_instcertinfo_h handle, uid_t uid)
322 {
323         int ret;
324         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)handle;
325
326         if (db == NULL || pkgid == NULL || handle == NULL) {
327                 _LOGE("invalid parameter");
328                 return PMINFO_R_EINVAL;
329         }
330
331         ret = sqlite3_exec(db, "BEGIN DEFERRED", NULL, NULL, NULL);
332         if (ret != SQLITE_OK) {
333                 _LOGE("failed to begin transaction");
334                 return PMINFO_R_ERROR;
335         }
336
337         if (_pkginfo_save_cert_index_info(db, info->cert_info)) {
338                 _LOGE("failed to save cert index info, rollback now");
339                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
340                 if (ret != SQLITE_OK)
341                         LOGE("Rollback is failed. error(%s)",
342                                         sqlite3_errmsg(db));
343                 return PMINFO_R_ERROR;
344         }
345
346         if (_pkginfo_save_cert_info(db, pkgid, info->cert_info)) {
347                 _LOGE("failed to save cert info, rollback now");
348                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
349                 if (ret != SQLITE_OK)
350                         LOGE("Rollback is failed. error(%s)",
351                                         sqlite3_errmsg(db));
352                 return PMINFO_R_ERROR;
353         }
354
355         ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
356         if (ret != SQLITE_OK) {
357                 _LOGE("failed to commit transaction, rollback now");
358                 ret = sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL);
359                 if (ret != SQLITE_OK)
360                         LOGE("Rollback is failed. error(%s)",
361                                         sqlite3_errmsg(db));
362                 return PMINFO_R_ERROR;
363         }
364
365
366         return PMINFO_R_OK;
367 }