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