ff60c66ccd0931b980e7d7cb4f32634267a20b89
[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   rmdir(gpgdir);
31 }
32
33 int
34 checksig(Pool *sigpool, FILE *fp, FILE *sigfp)
35 {
36   char *gpgdir;
37   char *keysfile;
38   const char *pubkey;
39   char cmd[256];
40   FILE *kfp;
41   Solvable *s;
42   Id p;
43   off_t posfp, possigfp;
44   int r, nkeys;
45
46   gpgdir = mkdtemp(pool_tmpjoin(sigpool, "/var/tmp/solvgpg.XXXXXX", 0, 0));
47   if (!gpgdir)
48     return 0;
49   keysfile = pool_tmpjoin(sigpool, gpgdir, "/keys", 0);
50   if (!(kfp = fopen(keysfile, "w")) )
51     {
52       cleanupgpg(gpgdir);
53       return 0;
54     }
55   nkeys = 0;
56   for (p = 1, s = sigpool->solvables + p; p < sigpool->nsolvables; p++, s++)
57     {
58       if (!s->repo)
59         continue;
60       pubkey = solvable_lookup_str(s, SOLVABLE_DESCRIPTION);
61       if (!pubkey || !*pubkey)
62         continue;
63       if (fwrite(pubkey, strlen(pubkey), 1, kfp) != 1)
64         break;
65       if (fputc('\n', kfp) == EOF)      /* Just in case... */
66         break;
67       nkeys++;
68     }
69   if (fclose(kfp) || !nkeys || p < sigpool->nsolvables)
70     {
71       cleanupgpg(gpgdir);
72       return 0;
73     }
74   snprintf(cmd, sizeof(cmd), "gpg2 -q --homedir %s --import %s", gpgdir, keysfile);
75   if (system(cmd))
76     {
77       fprintf(stderr, "key import error\n");
78       cleanupgpg(gpgdir);
79       return 0;
80     }
81   unlink(keysfile);
82   posfp = lseek(fileno(fp), 0, SEEK_CUR);
83   lseek(fileno(fp), 0, SEEK_SET);
84   possigfp = lseek(fileno(sigfp), 0, SEEK_CUR);
85   lseek(fileno(sigfp), 0, SEEK_SET);
86   snprintf(cmd, sizeof(cmd), "gpgv -q --homedir %s --keyring %s/pubring.gpg /dev/fd/%d /dev/fd/%d >/dev/null 2>&1", gpgdir, gpgdir, fileno(sigfp), fileno(fp));
87   fcntl(fileno(fp), F_SETFD, 0);        /* clear CLOEXEC */
88   fcntl(fileno(sigfp), F_SETFD, 0);     /* clear CLOEXEC */
89   r = system(cmd);
90   lseek(fileno(sigfp), possigfp, SEEK_SET);
91   lseek(fileno(fp), posfp, SEEK_SET);
92   fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
93   fcntl(fileno(sigfp), F_SETFD, FD_CLOEXEC);
94   cleanupgpg(gpgdir);
95   return r == 0 ? 1 : 0;
96 }
97
98 #else
99
100 int
101 checksig(Pool *sigpool, FILE *fp, FILE *sigfp)
102 {
103   char cmd[256];
104   int r;
105
106   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));
107   fcntl(fileno(fp), F_SETFD, 0);        /* clear CLOEXEC */
108   fcntl(fileno(sigfp), F_SETFD, 0);     /* clear CLOEXEC */
109   r = system(cmd);
110   fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
111   fcntl(fileno(sigfp), F_SETFD, FD_CLOEXEC);
112   return r == 0 ? 1 : 0;
113 }
114
115 #endif
116
117 Pool *
118 read_sigs()
119 {
120   Pool *sigpool = pool_create();
121 #if defined(ENABLE_PUBKEY) && defined(ENABLE_RPMDB)
122   Repo *repo = repo_create(sigpool, "pubkeys");
123   repo_add_rpmdb_pubkeys(repo, 0);
124 #endif
125   return sigpool;
126 }