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