00001
00006 #include "system.h"
00007
00008 #include <rpmlib.h>
00009
00010 #include "rpmlead.h"
00011 #include "signature.h"
00012 #include "misc.h"
00013 #include "debug.h"
00014
00015
00016
00017
00018 static int manageFile(FD_t *fdp, const char **fnp, int flags, int rc)
00019 {
00020 const char *fn;
00021 FD_t fd;
00022
00023 if (fdp == NULL) {
00024 return 1;
00025 }
00026
00027
00028 if (*fdp && (fnp == NULL || *fnp == NULL)) {
00029 Fclose(*fdp);
00030 *fdp = NULL;
00031 return 0;
00032 }
00033
00034
00035 if (*fdp == NULL && fnp && *fnp) {
00036 fd = Fopen(*fnp, ((flags & O_WRONLY) ? "w.ufdio" : "r.ufdio"));
00037 if (fd == NULL || Ferror(fd)) {
00038 rpmError(RPMERR_OPEN, _("%s: open failed: %s\n"), *fnp,
00039 Fstrerror(fd));
00040 return 1;
00041 }
00042 *fdp = fd;
00043 return 0;
00044 }
00045
00046
00047 if (*fdp == NULL && (fnp == NULL || *fnp == NULL)) {
00048 if (makeTempFile(NULL, (fnp ? &fn : NULL), &fd)) {
00049 rpmError(RPMERR_MAKETEMP, _("makeTempFile failed\n"));
00050 return 1;
00051 }
00052 if (fnp)
00053 *fnp = fn;
00054 *fdp = fd;
00055 return 0;
00056 }
00057
00058
00059 if (*fdp && fnp && *fnp) {
00060 return 0;
00061 }
00062
00063
00064 return 1;
00065 }
00066
00067 static int copyFile(FD_t *sfdp, const char **sfnp,
00068 FD_t *tfdp, const char **tfnp)
00069 {
00070 unsigned char buffer[BUFSIZ];
00071 ssize_t count;
00072 int rc = 1;
00073
00074 if (manageFile(sfdp, sfnp, O_RDONLY, 0))
00075 goto exit;
00076 if (manageFile(tfdp, tfnp, O_WRONLY|O_CREAT|O_TRUNC, 0))
00077 goto exit;
00078
00079 while ((count = Fread(buffer, sizeof(buffer[0]), sizeof(buffer), *sfdp)) > 0) {
00080 if (Fwrite(buffer, sizeof(buffer[0]), count, *tfdp) < 0) {
00081 rpmError(RPMERR_FWRITE, _("%s: Fwrite failed: %s\n"), *tfnp,
00082 Fstrerror(*tfdp));
00083 goto exit;
00084 }
00085 }
00086 if (count < 0) {
00087 rpmError(RPMERR_FREAD, _("%s: Fread failed: %s\n"), *sfnp, Fstrerror(*sfdp));
00088 goto exit;
00089 }
00090
00091 rc = 0;
00092
00093 exit:
00094 if (*sfdp) manageFile(sfdp, NULL, 0, rc);
00095 if (*tfdp) manageFile(tfdp, NULL, 0, rc);
00096 return rc;
00097 }
00098
00099 int rpmReSign(rpmResignFlags add, char *passPhrase, const char **argv)
00100 {
00101 FD_t fd = NULL;
00102 FD_t ofd = NULL;
00103 struct rpmlead lead, *l = &lead;
00104 int sigtype;
00105 const char *rpm, *trpm;
00106 const char *sigtarget = NULL;
00107 char tmprpm[1024+1];
00108 Header sig = NULL;
00109 int rc = EXIT_FAILURE;
00110
00111 tmprpm[0] = '\0';
00112 while ((rpm = *argv++) != NULL) {
00113
00114 fprintf(stdout, "%s:\n", rpm);
00115
00116 if (manageFile(&fd, &rpm, O_RDONLY, 0))
00117 goto exit;
00118
00119 if (readLead(fd, l)) {
00120 rpmError(RPMERR_READLEAD, _("%s: readLead failed\n"), rpm);
00121 goto exit;
00122 }
00123 switch (l->major) {
00124 case 1:
00125 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't sign v1.0 RPM\n"), rpm);
00126 goto exit;
00127 break;
00128 case 2:
00129 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't re-sign v2.0 RPM\n"), rpm);
00130 goto exit;
00131 break;
00132 default:
00133 break;
00134 }
00135
00136 if (rpmReadSignature(fd, &sig, l->signature_type)) {
00137 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed\n"), rpm);
00138 goto exit;
00139 }
00140 if (sig == NULL) {
00141 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), rpm);
00142 goto exit;
00143 }
00144
00145
00146
00147 if (copyFile(&fd, &rpm, &ofd, &sigtarget))
00148 goto exit;
00149
00150
00151
00152
00153 if (add != RESIGN_ADD_SIGNATURE) {
00154 rpmFreeSignature(sig);
00155 sig = rpmNewSignature();
00156 rpmAddSignature(sig, sigtarget, RPMSIGTAG_SIZE, passPhrase);
00157 rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
00158 }
00159
00160 if ((sigtype = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0)
00161 rpmAddSignature(sig, sigtarget, sigtype, passPhrase);
00162
00163
00164 strcpy(tmprpm, rpm);
00165 strcat(tmprpm, ".XXXXXX");
00166 mktemp(tmprpm) ;
00167 trpm = tmprpm;
00168
00169 if (manageFile(&ofd, &trpm, O_WRONLY|O_CREAT|O_TRUNC, 0))
00170 goto exit;
00171
00172 l->signature_type = RPMSIG_HEADERSIG;
00173 if (writeLead(ofd, l)) {
00174 rpmError(RPMERR_WRITELEAD, _("%s: writeLead failed: %s\n"), trpm,
00175 Fstrerror(ofd));
00176 goto exit;
00177 }
00178
00179 if (rpmWriteSignature(ofd, sig)) {
00180 rpmError(RPMERR_SIGGEN, _("%s: rpmWriteSignature failed: %s\n"), trpm,
00181 Fstrerror(ofd));
00182 goto exit;
00183 }
00184
00185
00186
00187 if (copyFile(&fd, &sigtarget, &ofd, &trpm))
00188 goto exit;
00189
00190
00191
00192
00193 unlink(sigtarget);
00194 free((void *)sigtarget); sigtarget = NULL;
00195
00196
00197 unlink(rpm);
00198 rename(trpm, rpm); tmprpm[0] = '\0';
00199 }
00200
00201 rc = 0;
00202
00203 exit:
00204 if (fd) manageFile(&fd, NULL, 0, rc);
00205 if (ofd) manageFile(&ofd, NULL, 0, rc);
00206
00207 if (sig) {
00208 rpmFreeSignature(sig);
00209 sig = NULL;
00210 }
00211 if (sigtarget) {
00212 unlink(sigtarget);
00213 free((void *)sigtarget);
00214 sigtarget = NULL;
00215 }
00216 if (tmprpm[0] != '\0') {
00217 unlink(tmprpm);
00218 tmprpm[0] = '\0';
00219 }
00220
00221 return rc;
00222 }
00223
00224 int rpmCheckSig(rpmCheckSigFlags flags, const char **argv)
00225 {
00226 FD_t fd = NULL;
00227 FD_t ofd = NULL;
00228 int res2, res3;
00229 struct rpmlead lead, *l = &lead;
00230 const char *rpm = NULL;
00231 char result[1024];
00232 const char * sigtarget = NULL;
00233 unsigned char buffer[8192];
00234 unsigned char missingKeys[7164];
00235 unsigned char untrustedKeys[7164];
00236 Header sig;
00237 HeaderIterator hi;
00238 int_32 tag, type, count;
00239 const void * ptr;
00240 int res = 0;
00241
00242 while ((rpm = *argv++) != NULL) {
00243
00244 if (manageFile(&fd, &rpm, O_RDONLY, 0)) {
00245 res++;
00246 goto bottom;
00247 }
00248
00249 if (readLead(fd, &lead)) {
00250 rpmError(RPMERR_READLEAD, _("%s: readLead failed\n"), rpm);
00251 res++;
00252 goto bottom;
00253 }
00254 switch (l->major) {
00255 case 1:
00256 rpmError(RPMERR_BADSIGTYPE, _("%s: No signature available (v1.0 RPM)\n"), rpm);
00257 res++;
00258 goto bottom;
00259 break;
00260 default:
00261 break;
00262 }
00263 if (rpmReadSignature(fd, &sig, l->signature_type)) {
00264 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed\n"), rpm);
00265 res++;
00266 goto bottom;
00267 }
00268 if (sig == NULL) {
00269 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), rpm);
00270 res++;
00271 goto bottom;
00272 }
00273
00274
00275 if (copyFile(&fd, &rpm, &ofd, &sigtarget)) {
00276 res++;
00277 goto bottom;
00278 }
00279
00280
00281
00282 res2 = 0;
00283 missingKeys[0] = '\0';
00284 untrustedKeys[0] = '\0';
00285 sprintf(buffer, "%s:%c", rpm, (rpmIsVerbose() ? '\n' : ' ') );
00286
00287 for (hi = headerInitIterator(sig);
00288 headerNextIterator(hi, &tag, &type, &ptr, &count);
00289 ptr = headerFreeData(ptr, type))
00290 {
00291 switch (tag) {
00292 case RPMSIGTAG_PGP5:
00293 case RPMSIGTAG_PGP:
00294 if (!(flags & CHECKSIG_PGP))
00295 continue;
00296 break;
00297 case RPMSIGTAG_GPG:
00298 if (!(flags & CHECKSIG_GPG))
00299 continue;
00300 break;
00301 case RPMSIGTAG_LEMD5_2:
00302 case RPMSIGTAG_LEMD5_1:
00303 case RPMSIGTAG_MD5:
00304 if (!(flags & CHECKSIG_MD5))
00305 continue;
00306 break;
00307 default:
00308 continue;
00309 break;
00310 }
00311
00312 if ((res3 = rpmVerifySignature(sigtarget, tag, ptr, count,
00313 result))) {
00314 if (rpmIsVerbose()) {
00315 strcat(buffer, result);
00316 res2 = 1;
00317 } else {
00318 char *tempKey;
00319 switch (tag) {
00320 case RPMSIGTAG_SIZE:
00321 strcat(buffer, "SIZE ");
00322 res2 = 1;
00323 break;
00324 case RPMSIGTAG_LEMD5_2:
00325 case RPMSIGTAG_LEMD5_1:
00326 case RPMSIGTAG_MD5:
00327 strcat(buffer, "MD5 ");
00328 res2 = 1;
00329 break;
00330 case RPMSIGTAG_PGP5:
00331 case RPMSIGTAG_PGP:
00332 switch (res3) {
00333
00334 case RPMSIG_NOKEY:
00335 case RPMSIG_NOTTRUSTED:
00336 { int offset = 7;
00337 strcat(buffer, "(PGP) ");
00338 tempKey = strstr(result, "Key ID");
00339 if (tempKey == NULL) {
00340 tempKey = strstr(result, "keyid:");
00341 offset = 9;
00342 }
00343 if (tempKey) {
00344 if (res3 == RPMSIG_NOKEY) {
00345 strcat(missingKeys, " PGP#");
00346 strncat(missingKeys, tempKey + offset, 8);
00347 } else {
00348 strcat(untrustedKeys, " PGP#");
00349 strncat(untrustedKeys, tempKey + offset, 8);
00350 }
00351 }
00352 } break;
00353 default:
00354 strcat(buffer, "PGP ");
00355 res2 = 1;
00356 break;
00357 }
00358 break;
00359 case RPMSIGTAG_GPG:
00360
00361 switch (res3) {
00362 case RPMSIG_NOKEY:
00363 strcat(buffer, "(GPG) ");
00364 strcat(missingKeys, " GPG#");
00365 tempKey = strstr(result, "key ID");
00366 if (tempKey)
00367 strncat(missingKeys, tempKey+7, 8);
00368 break;
00369 default:
00370 strcat(buffer, "GPG ");
00371 res2 = 1;
00372 break;
00373 }
00374 break;
00375 default:
00376 strcat(buffer, "?UnknownSignatureType? ");
00377 res2 = 1;
00378 break;
00379 }
00380 }
00381 } else {
00382 if (rpmIsVerbose()) {
00383 strcat(buffer, result);
00384 } else {
00385 switch (tag) {
00386 case RPMSIGTAG_SIZE:
00387 strcat(buffer, "size ");
00388 break;
00389 case RPMSIGTAG_LEMD5_2:
00390 case RPMSIGTAG_LEMD5_1:
00391 case RPMSIGTAG_MD5:
00392 strcat(buffer, "md5 ");
00393 break;
00394 case RPMSIGTAG_PGP5:
00395 case RPMSIGTAG_PGP:
00396 strcat(buffer, "pgp ");
00397 break;
00398 case RPMSIGTAG_GPG:
00399 strcat(buffer, "gpg ");
00400 break;
00401 default:
00402 strcat(buffer, "??? ");
00403 break;
00404 }
00405 }
00406 }
00407 }
00408 headerFreeIterator(hi);
00409 res += res2;
00410 unlink(sigtarget);
00411 free((void *)sigtarget); sigtarget = NULL;
00412
00413 if (res2) {
00414 if (rpmIsVerbose()) {
00415 rpmError(RPMERR_SIGVFY, "%s", (char *)buffer);
00416 } else {
00417 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", (char *)buffer,
00418 _("NOT OK"),
00419 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
00420 (char *)missingKeys,
00421 (missingKeys[0] != '\0') ? _(") ") : "",
00422 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
00423 (char *)untrustedKeys,
00424 (untrustedKeys[0] != '\0') ? _(")") : "");
00425
00426 }
00427 } else {
00428 if (rpmIsVerbose()) {
00429 rpmError(RPMERR_SIGVFY, "%s", (char *)buffer);
00430 } else {
00431 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", (char *)buffer,
00432 _("OK"),
00433 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
00434 (char *)missingKeys,
00435 (missingKeys[0] != '\0') ? _(") ") : "",
00436 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
00437 (char *)untrustedKeys,
00438 (untrustedKeys[0] != '\0') ? _(")") : "");
00439 }
00440 }
00441
00442 bottom:
00443 if (fd) manageFile(&fd, NULL, 0, 0);
00444 if (ofd) manageFile(&ofd, NULL, 0, 0);
00445 if (sigtarget) {
00446 unlink(sigtarget);
00447 free((void *)sigtarget); sigtarget = NULL;
00448 }
00449 }
00450
00451 return res;
00452 }