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
cleanupgpg(char * gpgdir)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
checksig(Pool * sigpool,FILE * fp,FILE * sigfp)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
checksig(Pool * sigpool,FILE * fp,FILE * sigfp)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 *
read_sigs()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 }
135