Fix db open functions
[platform/core/appfw/pkgmgr-info.git] / src / pkgmgrinfo_certinfo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5 #include <unistd.h>
6 #include <sys/types.h>
7
8 #include <sqlite3.h>
9 #include <glib.h>
10
11 #include <db-util.h>
12
13 #include "pkgmgr-info.h"
14 #include "pkgmgrinfo_debug.h"
15 #include "pkgmgrinfo_private.h"
16 #include "pkgmgr_parser.h"
17
18 typedef struct _pkgmgr_certinfo_x {
19         int for_all_users;
20         char *pkgid;
21         char *cert_value;
22         char *cert_info[MAX_CERT_TYPE]; /*certificate info*/
23         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
24 } pkgmgr_certinfo_x;
25
26 typedef struct _pkgmgr_instcertinfo_x {
27         char *pkgid;
28         char *cert_info[MAX_CERT_TYPE]; /*certificate data*/
29         int is_new[MAX_CERT_TYPE];              /*whether already exist in table or not*/
30         int ref_count[MAX_CERT_TYPE];           /*reference count of certificate data*/
31         int cert_id[MAX_CERT_TYPE];             /*certificate ID in index table*/
32 } pkgmgr_instcertinfo_x;
33
34 typedef struct _pkgmgr_certindexinfo_x {
35         int cert_id;
36         int cert_ref_count;
37 } pkgmgr_certindexinfo_x;
38
39 typedef struct _pkgmgr_cert_x {
40         char *pkgid;
41         int cert_id;
42 } pkgmgr_cert_x;
43
44 static int __cert_cb(void *data, int ncols, char **coltxt, char **colname)
45 {
46         pkgmgr_cert_x *info = (pkgmgr_cert_x *)data;
47         int i = 0;
48
49         for(i = 0; i < ncols; i++)
50         {
51                 if (strcmp(colname[i], "author_signer_cert") == 0) {
52                         if (coltxt[i])
53                                 info->cert_id = atoi(coltxt[i]);
54                         else
55                                 info->cert_id = 0;
56                 } else if (strcmp(colname[i], "package") == 0) {
57                         if (coltxt[i])
58                                 info->pkgid= strdup(coltxt[i]);
59                         else
60                                 info->pkgid = NULL;
61                 } else
62                         continue;
63         }
64         return 0;
65 }
66
67 static int __certinfo_cb(void *data, int ncols, char **coltxt, char **colname)
68 {
69         pkgmgr_certinfo_x *info = (pkgmgr_certinfo_x *)data;
70         int i = 0;
71         for(i = 0; i < ncols; i++)
72         {
73                 if (strcmp(colname[i], "package") == 0) {
74                         if (coltxt[i])
75                                 info->pkgid = strdup(coltxt[i]);
76                         else
77                                 info->pkgid = NULL;
78                 } else if (strcmp(colname[i], "author_signer_cert") == 0) {
79                         if (coltxt[i])
80                                 (info->cert_id)[PMINFO_AUTHOR_SIGNER_CERT] = atoi(coltxt[i]);
81                         else
82                                 (info->cert_id)[PMINFO_AUTHOR_SIGNER_CERT] = 0;
83                 } else if (strcmp(colname[i], "author_im_cert") == 0) {
84                         if (coltxt[i])
85                                 (info->cert_id)[PMINFO_AUTHOR_INTERMEDIATE_CERT] = atoi(coltxt[i]);
86                         else
87                                 (info->cert_id)[PMINFO_AUTHOR_INTERMEDIATE_CERT] = 0;
88                 } else if (strcmp(colname[i], "author_root_cert") == 0) {
89                         if (coltxt[i])
90                                 (info->cert_id)[PMINFO_AUTHOR_ROOT_CERT] = atoi(coltxt[i]);
91                         else
92                                 (info->cert_id)[PMINFO_AUTHOR_ROOT_CERT] = 0;
93                 } else if (strcmp(colname[i], "dist_signer_cert") == 0 ){
94                         if (coltxt[i])
95                                 (info->cert_id)[PMINFO_DISTRIBUTOR_SIGNER_CERT] = atoi(coltxt[i]);
96                         else
97                                 (info->cert_id)[PMINFO_DISTRIBUTOR_SIGNER_CERT] = 0;
98                 } else if (strcmp(colname[i], "dist_im_cert") == 0 ){
99                         if (coltxt[i])
100                                 (info->cert_id)[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT] = atoi(coltxt[i]);
101                         else
102                                 (info->cert_id)[PMINFO_DISTRIBUTOR_INTERMEDIATE_CERT] = 0;
103                 } else if (strcmp(colname[i], "dist_root_cert") == 0 ){
104                         if (coltxt[i])
105                                 (info->cert_id)[PMINFO_DISTRIBUTOR_ROOT_CERT] = atoi(coltxt[i]);
106                         else
107                                 (info->cert_id)[PMINFO_DISTRIBUTOR_ROOT_CERT] = 0;
108                 } else if (strcmp(colname[i], "dist2_signer_cert") == 0 ){
109                         if (coltxt[i])
110                                 (info->cert_id)[PMINFO_DISTRIBUTOR2_SIGNER_CERT] = atoi(coltxt[i]);
111                         else
112                                 (info->cert_id)[PMINFO_DISTRIBUTOR2_SIGNER_CERT] = 0;
113                 } else if (strcmp(colname[i], "dist2_im_cert") == 0 ){
114                         if (coltxt[i])
115                                 (info->cert_id)[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT] = atoi(coltxt[i]);
116                         else
117                                 (info->cert_id)[PMINFO_DISTRIBUTOR2_INTERMEDIATE_CERT] = 0;
118                 } else if (strcmp(colname[i], "dist2_root_cert") == 0 ){
119                         if (coltxt[i])
120                                 (info->cert_id)[PMINFO_DISTRIBUTOR2_ROOT_CERT] = atoi(coltxt[i]);
121                         else
122                                 (info->cert_id)[PMINFO_DISTRIBUTOR2_ROOT_CERT] = 0;
123                 } else if (strcmp(colname[i], "cert_info") == 0 ){
124                         if (coltxt[i])
125                                 info->cert_value = strdup(coltxt[i]);
126                         else
127                                 info->cert_value = NULL;
128                 } else if (strcmp(colname[i], "for_all_users") == 0 ){
129                         if (coltxt[i])
130                                 info->for_all_users = atoi(coltxt[i]);
131                         else
132                                 info->for_all_users = 0;
133                 } else
134                         continue;
135         }
136         return 0;
137 }
138
139 static int __exec_certinfo_query(char *query, void *data)
140 {
141         char *error_message = NULL;
142         if (SQLITE_OK !=
143             sqlite3_exec(GET_DB(cert_db), query, __certinfo_cb, data, &error_message)) {
144                 _LOGE("Don't execute query = %s error message = %s\n", query,
145                        error_message);
146                 sqlite3_free(error_message);
147                 return -1;
148         }
149         sqlite3_free(error_message);
150         return 0;
151 }
152
153 static int __certindexinfo_cb(void *data, int ncols, char **coltxt, char **colname)
154 {
155         pkgmgr_certindexinfo_x *info = (pkgmgr_certindexinfo_x *)data;
156         int i = 0;
157         for(i = 0; i < ncols; i++) {
158                 if (strcmp(colname[i], "cert_id") == 0) {
159                         if (coltxt[i])
160                                 info->cert_id = atoi(coltxt[i]);
161                         else
162                                 info->cert_id = 0;
163                 } else if (strcmp(colname[i], "cert_ref_count") == 0) {
164                         if (coltxt[i])
165                                 info->cert_ref_count = atoi(coltxt[i]);
166                         else
167                                 info->cert_ref_count = 0;
168                 } else
169                         continue;
170         }
171         return 0;
172 }
173
174 static int __exec_certindexinfo_query(char *query, void *data)
175 {
176         char *error_message = NULL;
177         if (SQLITE_OK !=
178             sqlite3_exec(GET_DB(cert_db), query, __certindexinfo_cb, data, &error_message)) {
179                 _LOGE("Don't execute query = %s error message = %s\n", query,
180                        error_message);
181                 sqlite3_free(error_message);
182                 return -1;
183         }
184         sqlite3_free(error_message);
185         return 0;
186 }
187
188 static int __delete_certinfo(const char *pkgid, uid_t uid)
189 {
190         int ret = -1;
191         int i = 0;
192         int j = 0;
193         int c = 0;
194         int unique_id[MAX_CERT_TYPE] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
195         char *error_message = NULL;
196         char query[MAX_QUERY_LEN] = {'\0'};
197         pkgmgr_certinfo_x *certinfo = NULL;
198         pkgmgr_certindexinfo_x *indexinfo = NULL;
199         certinfo = calloc(1, sizeof(pkgmgr_certinfo_x));
200         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
201         indexinfo = calloc(1, sizeof(pkgmgr_certindexinfo_x));
202         if (indexinfo == NULL) {
203                 _LOGE("Out of Memory!!!");
204                 ret = PMINFO_R_ERROR;
205                 goto err;
206         }
207
208         __open_cert_db(uid, false);
209         /*populate certinfo from DB*/
210         snprintf(query, MAX_QUERY_LEN, "select * from package_cert_info where package='%s' ", pkgid);
211         ret = __exec_certinfo_query(query, (void *)certinfo);
212         if (ret == -1) {
213                 _LOGE("Package Cert Info DB Information retrieval failed\n");
214                 ret = PMINFO_R_ERROR;
215                 goto err;
216         }
217         /*Update cert index table*/
218         for (i = 0; i < MAX_CERT_TYPE; i++) {
219                 if ((certinfo->cert_id)[i]) {
220                         for (j = 0; j < MAX_CERT_TYPE; j++) {
221                                 if ((certinfo->cert_id)[i] == unique_id[j]) {
222                                         /*Ref count has already been updated. Just continue*/
223                                         break;
224                                 }
225                         }
226                         if (j == MAX_CERT_TYPE)
227                                 unique_id[c++] = (certinfo->cert_id)[i];
228                         else
229                                 continue;
230                         memset(query, '\0', MAX_QUERY_LEN);
231                         snprintf(query, MAX_QUERY_LEN, "select * from package_cert_index_info where cert_id=%d ", (certinfo->cert_id)[i]);
232                         ret = __exec_certindexinfo_query(query, (void *)indexinfo);
233                         if (ret == -1) {
234                                 _LOGE("Cert Info DB Information retrieval failed\n");
235                                 ret = PMINFO_R_ERROR;
236                                 goto err;
237                         }
238                         memset(query, '\0', MAX_QUERY_LEN);
239                         if (indexinfo->cert_ref_count > 1) {
240                                 /*decrease ref count*/
241                                 snprintf(query, MAX_QUERY_LEN, "update package_cert_index_info set cert_ref_count=%d where cert_id=%d ",
242                                 indexinfo->cert_ref_count - 1, (certinfo->cert_id)[i]);
243                         } else {
244                                 /*delete this certificate as ref count is 1 and it will become 0*/
245                                 snprintf(query, MAX_QUERY_LEN, "delete from  package_cert_index_info where cert_id=%d ", (certinfo->cert_id)[i]);
246                         }
247                         if (SQLITE_OK !=
248                             sqlite3_exec(GET_DB(cert_db), query, NULL, NULL, &error_message)) {
249                                 _LOGE("Don't execute query = %s error message = %s\n", query,
250                                        error_message);
251                                 sqlite3_free(error_message);
252                                 ret = PMINFO_R_ERROR;
253                                 goto err;
254                         }
255                 }
256         }
257         /*Now delete the entry from db*/
258         snprintf(query, MAX_QUERY_LEN, "delete from package_cert_info where package='%s'", pkgid);
259         if (SQLITE_OK !=
260             sqlite3_exec(GET_DB(cert_db), query, NULL, NULL, &error_message)) {
261                 _LOGE("Don't execute query = %s error message = %s\n", query,
262                        error_message);
263                 sqlite3_free(error_message);
264                 ret = PMINFO_R_ERROR;
265                 goto err;
266         }
267         ret = PMINFO_R_OK;
268 err:
269         if (indexinfo) {
270                 free(indexinfo);
271                 indexinfo = NULL;
272         }
273         if (certinfo->pkgid) {
274                 free(certinfo->pkgid);
275                 certinfo->pkgid = NULL;
276         }
277         for (i = 0; i < MAX_CERT_TYPE; i++) {
278                 if ((certinfo->cert_info)[i]) {
279                         free((certinfo->cert_info)[i]);
280                         (certinfo->cert_info)[i] = NULL;
281                 }
282         }
283         __close_cert_db();
284         free(certinfo);
285         certinfo = NULL;
286         return ret;
287 }
288
289 static int __validate_cb(void *data, int ncols, char **coltxt, char **colname)
290 {
291         int *p = (int*)data;
292         *p = atoi(coltxt[0]);
293         return 0;
294 }
295
296 static int __maxid_cb(void *data, int ncols, char **coltxt, char **colname)
297 {
298         int *p = (int*)data;
299         if (coltxt[0])
300                 *p = atoi(coltxt[0]);
301         return 0;
302 }
303
304 API int pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(const char *lhs_package_id, const char *rhs_package_id, uid_t uid, pkgmgrinfo_cert_compare_result_type_e *compare_result)
305 {
306         int ret = PMINFO_R_OK;
307         char query[MAX_QUERY_LEN] = {'\0'};
308         char *error_message = NULL;
309         sqlite3_stmt *stmt = NULL;
310         char *lhs_certinfo = NULL;
311         char *rhs_certinfo = NULL;
312         int lcert;
313         int rcert;
314         int exist;
315         int i;
316         int is_global = 0;
317         *compare_result = PMINFO_CERT_COMPARE_ERROR;
318
319         retvm_if(lhs_package_id == NULL, PMINFO_R_EINVAL, "lhs package ID is NULL");
320         retvm_if(rhs_package_id == NULL, PMINFO_R_EINVAL, "rhs package ID is NULL");
321         retvm_if(compare_result == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
322
323         ret = __open_cert_db(uid, true);
324         if (ret != 0) {
325                 ret = PMINFO_R_ERROR;
326                 goto err;
327         }
328         _check_create_cert_db(GET_DB(cert_db));
329         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_cert_info where package='%s')", lhs_package_id);
330         if (SQLITE_OK !=
331             sqlite3_exec(GET_DB(cert_db), query, __validate_cb, (void *)&exist, &error_message)) {
332                 _LOGE("Don't execute query = %s error message = %s\n", query,
333                        error_message);
334                 ret = PMINFO_R_ERROR;
335                 goto err;
336         }
337         lcert = exist;
338
339         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_cert_info where package='%s')", rhs_package_id);
340         if (SQLITE_OK !=
341                 sqlite3_exec(GET_DB(cert_db), query, __validate_cb, (void *)&exist, &error_message)) {
342                 _LOGE("Don't execute query = %s error message = %s\n", query,
343                            error_message);
344                 ret = PMINFO_R_ERROR;
345                 goto err;
346         }
347         rcert = exist;
348
349         if (uid == GLOBAL_USER || uid == ROOT_UID) {
350                 snprintf(query, MAX_QUERY_LEN, "select cert_info from package_cert_index_info where cert_id=(select author_signer_cert from package_cert_info where package=?)");
351                 is_global = 1;
352         } else
353                 snprintf(query, MAX_QUERY_LEN, "select cert_info from package_cert_index_info where cert_id=(select author_signer_cert from package_cert_info where package=?) and for_all_users=(select for_all_users from package_cert_info where package=?)");
354         if (SQLITE_OK != sqlite3_prepare_v2(GET_DB(cert_db), query, strlen(query), &stmt, NULL)) {
355                 _LOGE("sqlite3_prepare_v2 error: %s", sqlite3_errmsg(GET_DB(cert_db)));
356                 ret = PMINFO_R_ERROR;
357                 goto err;
358         }
359
360         for (i = 1; i <= 2 - is_global; i++) {
361                 if (SQLITE_OK != sqlite3_bind_text(stmt, i, lhs_package_id, -1, SQLITE_STATIC)) {
362                         _LOGE("sqlite3_bind_text error: %s", sqlite3_errmsg(GET_DB(cert_db)));
363                         ret = PMINFO_R_ERROR;
364                         goto err;
365                 }
366         }
367         if (SQLITE_ROW != sqlite3_step(stmt) || sqlite3_column_text(stmt, 0) == NULL) {
368                 _LOGE("sqlite3_step error: %s", sqlite3_errmsg(GET_DB(cert_db)));
369                 ret = PMINFO_R_ERROR;
370                 goto err;
371         }
372
373         lhs_certinfo = strdup((const char *)sqlite3_column_text(stmt, 0));
374         sqlite3_reset(stmt);
375         sqlite3_clear_bindings(stmt);
376
377         for (i = 1; i <= 2 - is_global; i++) {
378                 if (SQLITE_OK != sqlite3_bind_text(stmt, i, rhs_package_id, -1, SQLITE_STATIC)) {
379                         _LOGE("sqlite3_bind_text error: %s", sqlite3_errmsg(GET_DB(cert_db)));
380                         ret = PMINFO_R_ERROR;
381                         goto err;
382                 }
383         }
384         if (SQLITE_ROW != sqlite3_step(stmt) || sqlite3_column_text(stmt, 0) == NULL) {
385                 _LOGE("sqlite3_step error: %s", sqlite3_errmsg(GET_DB(cert_db)));
386                 ret = PMINFO_R_ERROR;
387                 goto err;
388         }
389
390         rhs_certinfo = strdup((const char *)sqlite3_column_text(stmt, 0));
391
392         if ((lcert == 0) || (rcert == 0)) {
393                 if ((lcert == 0) && (rcert == 0))
394                         *compare_result = PMINFO_CERT_COMPARE_BOTH_NO_CERT;
395                 else if (lcert == 0)
396                         *compare_result = PMINFO_CERT_COMPARE_LHS_NO_CERT;
397                 else if (rcert == 0)
398                         *compare_result = PMINFO_CERT_COMPARE_RHS_NO_CERT;
399         } else {
400                 if (lhs_certinfo && rhs_certinfo && !strcmp(lhs_certinfo, rhs_certinfo))
401                         *compare_result = PMINFO_CERT_COMPARE_MATCH;
402                 else
403                         *compare_result = PMINFO_CERT_COMPARE_MISMATCH;
404         }
405
406 err:
407         if (stmt)
408                 sqlite3_finalize(stmt);
409         if (lhs_certinfo)
410                 free(lhs_certinfo);
411         if (rhs_certinfo)
412                 free(rhs_certinfo);
413         sqlite3_free(error_message);
414         __close_cert_db();
415
416         return ret;
417 }
418
419 API int pkgmgrinfo_pkginfo_compare_pkg_cert_info(const char *lhs_package_id, const char *rhs_package_id, pkgmgrinfo_cert_compare_result_type_e *compare_result)
420 {
421         return pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lhs_package_id, rhs_package_id, GLOBAL_USER, compare_result);
422 }
423
424 API int pkgmgrinfo_pkginfo_compare_app_cert_info(const char *lhs_app_id, const char *rhs_app_id, pkgmgrinfo_cert_compare_result_type_e *compare_result)
425 {
426         int ret = PMINFO_R_OK;
427         char query[MAX_QUERY_LEN] = {'\0'};
428         char *error_message = NULL;
429         pkgmgr_cert_x *info;
430         int exist;
431         char *lpkgid = NULL;
432         char *rpkgid = NULL;
433         const char* user_pkg_parser = getUserPkgParserDBPath();
434
435         retvm_if(lhs_app_id == NULL, PMINFO_R_EINVAL, "lhs app ID is NULL");
436         retvm_if(rhs_app_id == NULL, PMINFO_R_EINVAL, "rhs app ID is NULL");
437         retvm_if(compare_result == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
438
439         info = (pkgmgr_cert_x *)calloc(1, sizeof(pkgmgr_cert_x));
440         retvm_if(info == NULL, PMINFO_R_ERROR, "Out of Memory!!!");
441
442         ret = db_util_open_with_options(user_pkg_parser, &GET_DB(manifest_db),
443                                         SQLITE_OPEN_READONLY, NULL);
444         if (ret != SQLITE_OK) {
445                 _LOGE("connect db [%s] failed!\n", user_pkg_parser);
446                 ret = PMINFO_R_ERROR;
447                 goto err;
448         }
449
450         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", lhs_app_id);
451         if (SQLITE_OK !=
452             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
453                 _LOGE("Don't execute query = %s error message = %s\n", query,
454                        error_message);
455                 ret = PMINFO_R_ERROR;
456                 goto err;
457         }
458
459         if (exist == 0) {
460                 lpkgid = NULL;
461         } else {
462                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", lhs_app_id);
463                 if (SQLITE_OK !=
464                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
465                         _LOGE("Don't execute query = %s error message = %s\n", query,
466                                    error_message);
467                         ret = PMINFO_R_ERROR;
468                         goto err;
469                 }
470                 lpkgid = strdup(info->pkgid);
471                 if (lpkgid == NULL) {
472                         _LOGE("Out of Memory\n");
473                         ret = PMINFO_R_ERROR;
474                         goto err;
475                 }
476                 free(info->pkgid);
477                 info->pkgid = NULL;
478         }
479
480         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", rhs_app_id);
481         if (SQLITE_OK !=
482             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
483                 _LOGE("Don't execute query = %s error message = %s\n", query,
484                        error_message);
485                 ret = PMINFO_R_ERROR;
486                 goto err;
487         }
488
489         if (exist == 0) {
490                 rpkgid = NULL;
491         } else {
492                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", rhs_app_id);
493                 if (SQLITE_OK !=
494                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
495                         _LOGE("Don't execute query = %s error message = %s\n", query,
496                                    error_message);
497                         ret = PMINFO_R_ERROR;
498                         goto err;
499                 }
500                 rpkgid = strdup(info->pkgid);
501                 if (rpkgid == NULL) {
502                         _LOGE("Out of Memory\n");
503                         ret = PMINFO_R_ERROR;
504                         goto err;
505                 }
506                 free(info->pkgid);
507                 info->pkgid = NULL;
508         }
509         ret = pkgmgrinfo_pkginfo_compare_pkg_cert_info(lpkgid, rpkgid, compare_result);
510  err:
511         if (error_message)
512                 sqlite3_free(error_message);
513         __close_manifest_db();
514         if (info) {
515                 if (info->pkgid) {
516                         free(info->pkgid);
517                         info->pkgid = NULL;
518                 }
519                 free(info);
520                 info = NULL;
521         }
522         if (lpkgid) {
523                 free(lpkgid);
524                 lpkgid = NULL;
525         }
526         if (rpkgid) {
527                 free(rpkgid);
528                 rpkgid = NULL;
529         }
530         return ret;
531 }
532
533 API int pkgmgrinfo_pkginfo_compare_usr_app_cert_info(const char *lhs_app_id, const char *rhs_app_id, uid_t uid, pkgmgrinfo_cert_compare_result_type_e *compare_result)
534 {
535         int ret = PMINFO_R_OK;
536         char query[MAX_QUERY_LEN] = {'\0'};
537         char *error_message = NULL;
538         pkgmgr_cert_x *info;
539         int exist;
540         char *lpkgid = NULL;
541         char *rpkgid = NULL;
542
543         retvm_if(lhs_app_id == NULL, PMINFO_R_EINVAL, "lhs app ID is NULL");
544         retvm_if(rhs_app_id == NULL, PMINFO_R_EINVAL, "rhs app ID is NULL");
545         retvm_if(compare_result == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL");
546
547         info = (pkgmgr_cert_x *)calloc(1, sizeof(pkgmgr_cert_x));
548         retvm_if(info == NULL, PMINFO_R_ERROR, "Out of Memory!!!");
549
550         ret = __open_manifest_db(uid, true);
551         if (ret != SQLITE_OK) {
552                 _LOGE("connect db [%s] failed!\n", getUserPkgParserDBPathUID(uid));
553                 ret = PMINFO_R_ERROR;
554                 goto err;
555         }
556
557         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", lhs_app_id);
558         if (SQLITE_OK !=
559             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
560                 _LOGE("Don't execute query = %s error message = %s\n", query,
561                        error_message);
562                 ret = PMINFO_R_ERROR;
563                 goto err;
564         }
565
566         if (exist == 0) {
567                 lpkgid = NULL;
568         } else {
569                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", lhs_app_id);
570                 if (SQLITE_OK !=
571                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
572                         _LOGE("Don't execute query = %s error message = %s\n", query,
573                                    error_message);
574                         ret = PMINFO_R_ERROR;
575                         goto err;
576                 }
577                 lpkgid = strdup(info->pkgid);
578                 if (lpkgid == NULL) {
579                         _LOGE("Out of Memory\n");
580                         ret = PMINFO_R_ERROR;
581                         goto err;
582                 }
583                 free(info->pkgid);
584                 info->pkgid = NULL;
585         }
586
587         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_app_info where app_id='%s')", rhs_app_id);
588         if (SQLITE_OK !=
589             sqlite3_exec(GET_DB(manifest_db), query, __validate_cb, (void *)&exist, &error_message)) {
590                 _LOGE("Don't execute query = %s error message = %s\n", query,
591                        error_message);
592                 ret = PMINFO_R_ERROR;
593                 goto err;
594         }
595
596         if (exist == 0) {
597                 rpkgid = NULL;
598         } else {
599                 snprintf(query, MAX_QUERY_LEN, "select package from package_app_info where app_id='%s' ", rhs_app_id);
600                 if (SQLITE_OK !=
601                         sqlite3_exec(GET_DB(manifest_db), query, __cert_cb, (void *)info, &error_message)) {
602                         _LOGE("Don't execute query = %s error message = %s\n", query,
603                                    error_message);
604                         ret = PMINFO_R_ERROR;
605                         goto err;
606                 }
607                 rpkgid = strdup(info->pkgid);
608                 if (rpkgid == NULL) {
609                         _LOGE("Out of Memory\n");
610                         ret = PMINFO_R_ERROR;
611                         goto err;
612                 }
613                 free(info->pkgid);
614                 info->pkgid = NULL;
615         }
616         ret = pkgmgrinfo_pkginfo_compare_usr_pkg_cert_info(lpkgid, rpkgid, uid, compare_result);
617  err:
618         if (error_message)
619                 sqlite3_free(error_message);
620         __close_manifest_db();
621         if (info) {
622                 if (info->pkgid) {
623                         free(info->pkgid);
624                         info->pkgid = NULL;
625                 }
626                 free(info);
627                 info = NULL;
628         }
629         if (lpkgid) {
630                 free(lpkgid);
631                 lpkgid = NULL;
632         }
633         if (rpkgid) {
634                 free(rpkgid);
635                 rpkgid = NULL;
636         }
637         return ret;
638 }
639
640 API int pkgmgrinfo_pkginfo_create_certinfo(pkgmgrinfo_certinfo_h *handle)
641 {
642         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
643         pkgmgr_certinfo_x *certinfo = NULL;
644         certinfo = calloc(1, sizeof(pkgmgr_certinfo_x));
645         *handle = NULL;
646         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
647         *handle = (void *)certinfo;
648         return PMINFO_R_OK;
649 }
650
651 API int pkgmgrinfo_pkginfo_load_certinfo(const char *pkgid, pkgmgrinfo_certinfo_h handle, uid_t uid)
652 {
653         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "package ID is NULL\n");
654         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Certinfo handle is NULL\n");
655         pkgmgr_certinfo_x *certinfo = NULL;
656         char *error_message = NULL;
657         int ret = PMINFO_R_OK;
658         char query[MAX_QUERY_LEN] = {'\0'};
659         int exist = 0;
660         int i = 0;
661
662         /*Open db.*/
663         ret = __open_cert_db(uid, true);
664         if (ret != SQLITE_OK) {
665                 _LOGE("connect db [%s] failed!\n");
666                 ret = PMINFO_R_ERROR;
667                 goto err;
668         }
669         _check_create_cert_db(GET_DB(cert_db));
670         /*validate pkgid*/
671         snprintf(query, MAX_QUERY_LEN, "select exists(select * from package_cert_info where package='%s')", pkgid);
672         if (SQLITE_OK !=
673             sqlite3_exec(GET_DB(cert_db), query, __validate_cb, (void *)&exist, &error_message)) {
674                 _LOGE("Don't execute query = %s error message = %s\n", query,
675                        error_message);
676                 sqlite3_free(error_message);
677                 ret = PMINFO_R_ERROR;
678                 goto err;
679         }
680         if (exist == 0) {
681                 _LOGE("Package for user[%d] is not found in DB\n", uid);
682                 ret = PMINFO_R_ERROR;
683                 goto err;
684         }
685         certinfo = (pkgmgr_certinfo_x *)handle;
686         /*populate certinfo from DB*/
687         snprintf(query, MAX_QUERY_LEN, "select * from package_cert_info where package='%s' ", pkgid);
688         ret = __exec_certinfo_query(query, (void *)certinfo);
689         if (ret == -1) {
690                 _LOGE("Package Cert Info DB Information retrieval failed\n");
691                 ret = PMINFO_R_ERROR;
692                 goto err;
693         }
694         for (i = 0; i < MAX_CERT_TYPE; i++) {
695                 memset(query, '\0', MAX_QUERY_LEN);
696                 if (uid == GLOBAL_USER || uid == ROOT_UID)
697                         snprintf(query, MAX_QUERY_LEN, "select cert_info from package_cert_index_info where cert_id=%d", (certinfo->cert_id)[i]);
698                 else
699                         snprintf(query, MAX_QUERY_LEN, "select cert_info from package_cert_index_info where cert_id=%d and for_all_users=%d", (certinfo->cert_id)[i], certinfo->for_all_users);
700                 ret = __exec_certinfo_query(query, (void *)certinfo);
701                 if (ret == -1) {
702                         _LOGE("Cert Info DB Information retrieval failed\n");
703                         ret = PMINFO_R_ERROR;
704                         goto err;
705                 }
706                 if (certinfo->cert_value) {
707                         (certinfo->cert_info)[i] = strdup(certinfo->cert_value);
708                         free(certinfo->cert_value);
709                         certinfo->cert_value = NULL;
710                 }
711         }
712 err:
713         __close_cert_db();
714         return ret;
715 }
716
717 API int pkgmgrinfo_pkginfo_get_cert_value(pkgmgrinfo_certinfo_h handle, pkgmgrinfo_cert_type cert_type, const char **cert_value)
718 {
719         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
720         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
721         retvm_if(cert_type < PMINFO_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
722         retvm_if(cert_type > PMINFO_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
723         pkgmgr_certinfo_x *certinfo = NULL;
724         certinfo = (pkgmgr_certinfo_x *)handle;
725         if ((certinfo->cert_info)[cert_type])
726                 *cert_value = (certinfo->cert_info)[cert_type];
727         else
728                 *cert_value = NULL;
729         return PMINFO_R_OK;
730 }
731
732 API int pkgmgrinfo_pkginfo_destroy_certinfo(pkgmgrinfo_certinfo_h handle)
733 {
734         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
735         int i = 0;
736         pkgmgr_certinfo_x *certinfo = NULL;
737         certinfo = (pkgmgr_certinfo_x *)handle;
738         if (certinfo->pkgid) {
739                 free(certinfo->pkgid);
740                 certinfo->pkgid = NULL;
741         }
742         for (i = 0; i < MAX_CERT_TYPE; i++) {
743                 if ((certinfo->cert_info)[i]) {
744                         free((certinfo->cert_info)[i]);
745                         (certinfo->cert_info)[i] = NULL;
746                 }
747         }
748         free(certinfo);
749         certinfo = NULL;
750         return PMINFO_R_OK;
751 }
752
753 API int pkgmgrinfo_create_certinfo_set_handle(pkgmgrinfo_instcertinfo_h *handle)
754 {
755         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied to hold return value is NULL\n");
756         pkgmgr_instcertinfo_x *certinfo = NULL;
757         *handle = NULL;
758         certinfo = calloc(1, sizeof(pkgmgr_instcertinfo_x));
759         retvm_if(certinfo == NULL, PMINFO_R_ERROR, "Malloc Failed\n");
760         *handle = (void *)certinfo;
761         return PMINFO_R_OK;
762 }
763
764 API int pkgmgrinfo_set_cert_value(pkgmgrinfo_instcertinfo_h handle, pkgmgrinfo_instcert_type cert_type, char *cert_value)
765 {
766         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
767         retvm_if(cert_value == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
768         retvm_if(cert_type < PMINFO_SET_AUTHOR_ROOT_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
769         retvm_if(cert_type > PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT, PMINFO_R_EINVAL, "Invalid certificate type\n");
770         pkgmgr_instcertinfo_x *certinfo = NULL;
771         certinfo = (pkgmgr_instcertinfo_x *)handle;
772         (certinfo->cert_info)[cert_type] = strdup(cert_value);
773         return PMINFO_R_OK;
774 }
775
776 API int pkgmgrinfo_save_certinfo(const char *pkgid, pkgmgrinfo_instcertinfo_h handle, uid_t uid)
777 {
778         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "package ID is NULL\n");
779         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Certinfo handle is NULL\n");
780         char *error_message = NULL;
781         char query[MAX_QUERY_LEN] = {'\0'};
782         char vquery[MAX_QUERY_LEN] = {'\0'};
783         int i = 0;
784         int j = 0;
785         int c = 0;
786         int unique_id[MAX_CERT_TYPE] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
787         int newid = 0;
788         int is_new = 0;
789         int exist = -1;
790         int ret = -1;
791         int maxid = 0;
792         int flag = 0;
793         pkgmgr_instcertinfo_x *info = (pkgmgr_instcertinfo_x *)handle;
794         pkgmgr_certindexinfo_x *indexinfo = NULL;
795         indexinfo = calloc(1, sizeof(pkgmgr_certindexinfo_x));
796         if (indexinfo == NULL) {
797                 _LOGE("Out of Memory!!!");
798                 return PMINFO_R_ERROR;
799         }
800         info->pkgid = strdup(pkgid);
801
802         /*Open db.*/
803         ret =__open_cert_db(uid, false);
804         if (ret != 0) {
805                 ret = PMINFO_R_ERROR;
806                 _LOGE("Failed to open cert db \n");
807                 goto err;
808         }
809         _check_create_cert_db(GET_DB(cert_db));
810         /*Begin Transaction*/
811         ret = sqlite3_exec(GET_DB(cert_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
812         if (ret == -1) {
813                 _LOGE("Failed to begin transaction %s\n");
814                 ret = PMINFO_R_ERROR;
815                 goto err;
816         }
817
818         /*Check if request is to insert/update*/
819         snprintf(query, sizeof(query), "select exists(select * from package_cert_info where package='%s')", pkgid);
820         if (SQLITE_OK !=
821             sqlite3_exec(GET_DB(cert_db), query, __validate_cb, (void *)&exist, &error_message)) {
822                 _LOGE("Don't execute query = %s error message = %s\n", query,
823                        error_message);
824                 sqlite3_free(error_message);
825                 ret = PMINFO_R_ERROR;
826                 goto err;
827         }
828         if (exist) {
829                 /*Update request.
830                 We cant just issue update query directly. We need to manage index table also.
831                 Hence it is better to delete and insert again in case of update*/
832                 ret = __delete_certinfo(pkgid, uid);
833                 if (ret < 0)
834                         _LOGE("Certificate Deletion Failed\n");
835         }
836         for (i = 0; i < MAX_CERT_TYPE; i++) {
837                 if ((info->cert_info)[i]) {
838                         for (j = 0; j < i; j++) {
839                                 if ( (info->cert_info)[j]) {
840                                         if (strcmp((info->cert_info)[i], (info->cert_info)[j]) == 0) {
841                                                 (info->cert_id)[i] = (info->cert_id)[j];
842                                                 (info->is_new)[i] = 0;
843                                                 (info->ref_count)[i] = (info->ref_count)[j];
844                                                 break;
845                                         }
846                                 }
847                         }
848                         if (j < i)
849                                 continue;
850                         snprintf(query, sizeof(query), "select * from package_cert_index_info " \
851                                 "where cert_info='%s'",(info->cert_info)[i]);
852                         ret = __exec_certindexinfo_query(query, (void *)indexinfo);
853                         if (ret == -1) {
854                                 _LOGE("Cert Info DB Information retrieval failed\n");
855                                 ret = PMINFO_R_ERROR;
856                                 goto err;
857                         }
858                         if (indexinfo->cert_id == 0) {
859                                 /*New certificate. Get newid*/
860                                 snprintf(query, sizeof(query), "select MAX(cert_id) from package_cert_index_info ");
861                                 if (SQLITE_OK !=
862                                     sqlite3_exec(GET_DB(cert_db), query, __maxid_cb, (void *)&newid, &error_message)) {
863                                         _LOGE("Don't execute query = %s error message = %s\n", query,
864                                                error_message);
865                                         sqlite3_free(error_message);
866                                         ret = PMINFO_R_ERROR;
867                                         goto err;
868                                 }
869                                 newid = newid + 1;
870                                 if (flag == 0) {
871                                         maxid = newid;
872                                         flag = 1;
873                                 }
874                                 indexinfo->cert_id = maxid;
875                                 indexinfo->cert_ref_count = 1;
876                                 is_new = 1;
877                                 maxid = maxid + 1;
878                         }
879                         (info->cert_id)[i] = indexinfo->cert_id;
880                         (info->is_new)[i] = is_new;
881                         (info->ref_count)[i] = indexinfo->cert_ref_count;
882                         indexinfo->cert_id = 0;
883                         indexinfo->cert_ref_count = 0;
884                         is_new = 0;
885                 }
886         }
887         /*insert*/
888         snprintf(vquery, sizeof(vquery),
889                  "insert into package_cert_info(package, author_root_cert, author_im_cert, author_signer_cert, dist_root_cert, " \
890                 "dist_im_cert, dist_signer_cert, dist2_root_cert, dist2_im_cert, dist2_signer_cert) " \
891                 "values('%s', %d, %d, %d, %d, %d, %d, %d, %d, %d)",\
892                  info->pkgid,(info->cert_id)[PMINFO_SET_AUTHOR_ROOT_CERT],(info->cert_id)[PMINFO_SET_AUTHOR_INTERMEDIATE_CERT],
893                 (info->cert_id)[PMINFO_SET_AUTHOR_SIGNER_CERT], (info->cert_id)[PMINFO_SET_DISTRIBUTOR_ROOT_CERT],
894                 (info->cert_id)[PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT], (info->cert_id)[PMINFO_SET_DISTRIBUTOR_SIGNER_CERT],
895                 (info->cert_id)[PMINFO_SET_DISTRIBUTOR2_ROOT_CERT],(info->cert_id)[PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT],
896                 (info->cert_id)[PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT]);
897         if (SQLITE_OK !=
898             sqlite3_exec(GET_DB(cert_db), vquery, NULL, NULL, &error_message)) {
899                 _LOGE("Don't execute query = %s error message = %s\n", vquery,
900                        error_message);
901                 sqlite3_free(error_message);
902                 ret = PMINFO_R_ERROR;
903                 goto err;
904         }
905         /*Update index table info*/
906         /*If cert_id exists and is repeated for current package, ref count should only be increased once*/
907         for (i = 0; i < MAX_CERT_TYPE; i++) {
908                 if ((info->cert_info)[i]) {
909                         if ((info->is_new)[i]) {
910                                 snprintf(vquery, sizeof(vquery), "insert into package_cert_index_info(cert_info, cert_id, cert_ref_count) " \
911                                 "values('%s', '%d', '%d') ", (info->cert_info)[i], (info->cert_id)[i], 1);
912                                 unique_id[c++] = (info->cert_id)[i];
913                         } else {
914                                 /*Update*/
915                                 for (j = 0; j < MAX_CERT_TYPE; j++) {
916                                         if ((info->cert_id)[i] == unique_id[j]) {
917                                                 /*Ref count has already been increased. Just continue*/
918                                                 break;
919                                         }
920                                 }
921                                 if (j == MAX_CERT_TYPE)
922                                         unique_id[c++] = (info->cert_id)[i];
923                                 else
924                                         continue;
925                                 snprintf(vquery, sizeof(vquery), "update package_cert_index_info set cert_ref_count=%d " \
926                                 "where cert_id=%d",  (info->ref_count)[i] + 1, (info->cert_id)[i]);
927                         }
928                         if (SQLITE_OK !=
929                             sqlite3_exec(GET_DB(cert_db), vquery, NULL, NULL, &error_message)) {
930                                 _LOGE("Don't execute query = %s error message = %s\n", vquery,
931                                        error_message);
932                                 sqlite3_free(error_message);
933                                 ret = PMINFO_R_ERROR;
934                                 goto err;
935                         }
936                 }
937         }
938         /*Commit transaction*/
939         ret = sqlite3_exec(GET_DB(cert_db), "COMMIT", NULL, NULL, NULL);
940         if (ret != SQLITE_OK) {
941                 _LOGE("Failed to commit transaction, Rollback now\n");
942                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
943                 ret = PMINFO_R_ERROR;
944                 goto err;
945         }
946
947         ret =  PMINFO_R_OK;
948 err:
949         __close_cert_db();
950         if (indexinfo) {
951                 free(indexinfo);
952                 indexinfo = NULL;
953         }
954         return ret;
955 }
956
957 API int pkgmgrinfo_destroy_certinfo_set_handle(pkgmgrinfo_instcertinfo_h handle)
958 {
959         retvm_if(handle == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
960         int i = 0;
961         pkgmgr_instcertinfo_x *certinfo = NULL;
962         certinfo = (pkgmgr_instcertinfo_x *)handle;
963         if (certinfo->pkgid) {
964                 free(certinfo->pkgid);
965                 certinfo->pkgid = NULL;
966         }
967         for (i = 0; i < MAX_CERT_TYPE; i++) {
968                 if ((certinfo->cert_info)[i]) {
969                         free((certinfo->cert_info)[i]);
970                         (certinfo->cert_info)[i] = NULL;
971                 }
972         }
973         free(certinfo);
974         certinfo = NULL;
975         return PMINFO_R_OK;
976 }
977
978 API int pkgmgrinfo_delete_usr_certinfo(const char *pkgid, uid_t uid)
979 {
980         retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "Argument supplied is NULL\n");
981         int ret = -1;
982         /*Open db.*/
983         ret = __open_cert_db(uid, false);
984         if (ret != 0) {
985                 _LOGE("connect db [%s] failed!\n", getUserPkgCertDBPathUID(uid));
986                 ret = PMINFO_R_ERROR;
987                 goto err;
988         }
989         _check_create_cert_db(GET_DB(cert_db));
990         /*Begin Transaction*/
991         ret = sqlite3_exec(GET_DB(cert_db), "BEGIN EXCLUSIVE", NULL, NULL, NULL);
992         if (ret != SQLITE_OK) {
993                 _LOGE("Failed to begin transaction\n");
994                 ret = PMINFO_R_ERROR;
995                 goto err;
996         }
997         _LOGE("Transaction Begin\n");
998         ret = __delete_certinfo(pkgid, uid);
999         if (ret < 0) {
1000                 _LOGE("Certificate Deletion Failed\n");
1001         } else {
1002                 _LOGE("Certificate Deletion Success\n");
1003         }
1004         /*Commit transaction*/
1005         ret = sqlite3_exec(GET_DB(cert_db), "COMMIT", NULL, NULL, NULL);
1006         if (ret != SQLITE_OK) {
1007                 _LOGE("Failed to commit transaction, Rollback now\n");
1008                 sqlite3_exec(GET_DB(cert_db), "ROLLBACK", NULL, NULL, NULL);
1009                 ret = PMINFO_R_ERROR;
1010                 goto err;
1011         }
1012         _LOGE("Transaction Commit and End\n");
1013         ret = PMINFO_R_OK;
1014 err:
1015         __close_cert_db();
1016         return ret;
1017 }
1018
1019
1020 API int pkgmgrinfo_delete_certinfo(const char *pkgid)
1021 {
1022         return pkgmgrinfo_delete_usr_certinfo(pkgid, GLOBAL_USER);
1023 }
1024