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