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