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