Imported Upstream version 0.6.35
[platform/upstream/libsolv.git] / examples / solv / checksig.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5
6 #include "pool.h"
7 #include "repo.h"
8 #ifdef ENABLE_PUBKEY
9 #include "repo_pubkey.h"
10 #endif
11
12 #include "checksig.h"
13
14 #ifndef DEBIAN
15
16 static void
17 cleanupgpg(char *gpgdir)
18 {
19   char cmd[256];
20   snprintf(cmd, sizeof(cmd), "%s/pubring.gpg", gpgdir);
21   unlink(cmd);
22   snprintf(cmd, sizeof(cmd), "%s/pubring.gpg~", gpgdir);
23   unlink(cmd);
24   snprintf(cmd, sizeof(cmd), "%s/secring.gpg", gpgdir);
25   unlink(cmd);
26   snprintf(cmd, sizeof(cmd), "%s/trustdb.gpg", gpgdir);
27   unlink(cmd);
28   snprintf(cmd, sizeof(cmd), "%s/keys", gpgdir);
29   unlink(cmd);
30   snprintf(cmd, sizeof(cmd), "%s/pubring.kbx", gpgdir);
31   unlink(cmd);
32   snprintf(cmd, sizeof(cmd), "%s/pubring.kbx~", gpgdir);
33   unlink(cmd);
34   snprintf(cmd, sizeof(cmd), "%s/private-keys-v1.d", gpgdir);
35   rmdir(cmd);
36   rmdir(gpgdir);
37 }
38
39 int
40 checksig(Pool *sigpool, FILE *fp, FILE *sigfp)
41 {
42   char *gpgdir;
43   char *keysfile;
44   const char *pubkey, *pubring;
45   char cmd[256];
46   FILE *kfp;
47   Solvable *s;
48   Id p;
49   off_t posfp, possigfp;
50   int r, nkeys;
51
52   gpgdir = mkdtemp(pool_tmpjoin(sigpool, "/var/tmp/solvgpg.XXXXXX", 0, 0));
53   if (!gpgdir)
54     return 0;
55   keysfile = pool_tmpjoin(sigpool, gpgdir, "/keys", 0);
56   if (!(kfp = fopen(keysfile, "w")) )
57     {
58       cleanupgpg(gpgdir);
59       return 0;
60     }
61   nkeys = 0;
62   for (p = 1, s = sigpool->solvables + p; p < sigpool->nsolvables; p++, s++)
63     {
64       if (!s->repo)
65         continue;
66       pubkey = solvable_lookup_str(s, SOLVABLE_DESCRIPTION);
67       if (!pubkey || !*pubkey)
68         continue;
69       if (fwrite(pubkey, strlen(pubkey), 1, kfp) != 1)
70         break;
71       if (fputc('\n', kfp) == EOF)      /* Just in case... */
72         break;
73       nkeys++;
74     }
75   if (fclose(kfp) || !nkeys || p < sigpool->nsolvables)
76     {
77       cleanupgpg(gpgdir);
78       return 0;
79     }
80   snprintf(cmd, sizeof(cmd), "gpg2 -q --homedir %s --import %s", gpgdir, keysfile);
81   if (system(cmd))
82     {
83       fprintf(stderr, "key import error\n");
84       cleanupgpg(gpgdir);
85       return 0;
86     }
87   unlink(keysfile);
88   posfp = lseek(fileno(fp), 0, SEEK_CUR);
89   lseek(fileno(fp), 0, SEEK_SET);
90   possigfp = lseek(fileno(sigfp), 0, SEEK_CUR);
91   lseek(fileno(sigfp), 0, SEEK_SET);
92   snprintf(cmd, sizeof(cmd), "%s/pubring.kbx", gpgdir);
93   pubring = access(cmd, R_OK) == 0 ? "pubring.kbx" : "pubring.gpg";
94   snprintf(cmd, sizeof(cmd), "gpgv -q --homedir %s --keyring %s/%s /dev/fd/%d /dev/fd/%d >/dev/null 2>&1", gpgdir, gpgdir, pubring, fileno(sigfp), fileno(fp));
95   fcntl(fileno(fp), F_SETFD, 0);        /* clear CLOEXEC */
96   fcntl(fileno(sigfp), F_SETFD, 0);     /* clear CLOEXEC */
97   r = system(cmd);
98   lseek(fileno(sigfp), possigfp, SEEK_SET);
99   lseek(fileno(fp), posfp, SEEK_SET);
100   fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
101   fcntl(fileno(sigfp), F_SETFD, FD_CLOEXEC);
102   cleanupgpg(gpgdir);
103   return r == 0 ? 1 : 0;
104 }
105
106 #else
107
108 int
109 checksig(Pool *sigpool, FILE *fp, FILE *sigfp)
110 {
111   char cmd[256];
112   int r;
113
114   snprintf(cmd, sizeof(cmd), "gpgv -q --keyring /etc/apt/trusted.gpg /dev/fd/%d /dev/fd/%d >/dev/null 2>&1", fileno(sigfp), fileno(fp));
115   fcntl(fileno(fp), F_SETFD, 0);        /* clear CLOEXEC */
116   fcntl(fileno(sigfp), F_SETFD, 0);     /* clear CLOEXEC */
117   r = system(cmd);
118   fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
119   fcntl(fileno(sigfp), F_SETFD, FD_CLOEXEC);
120   return r == 0 ? 1 : 0;
121 }
122
123 #endif
124
125 Pool *
126 read_sigs()
127 {
128   Pool *sigpool = pool_create();
129 #if defined(ENABLE_PUBKEY) && defined(ENABLE_RPMDB)
130   Repo *repo = repo_create(sigpool, "pubkeys");
131   repo_add_rpmdb_pubkeys(repo, 0);
132 #endif
133   return sigpool;
134 }