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 sigtype;
00111 const char *rpm, *trpm;
00112 const char *sigtarget = NULL;
00113 char tmprpm[1024+1];
00114 Header sig = NULL;
00115 int res = EXIT_FAILURE;
00116 rpmRC rc;
00117
00118 tmprpm[0] = '\0';
00119 if (argv)
00120 while ((rpm = *argv++) != NULL) {
00121
00122 fprintf(stdout, "%s:\n", rpm);
00123
00124 if (manageFile(&fd, &rpm, O_RDONLY, 0))
00125 goto exit;
00126
00127 memset(l, 0, sizeof(*l));
00128 if (readLead(fd, l)) {
00129 rpmError(RPMERR_READLEAD, _("%s: readLead failed\n"), rpm);
00130 goto exit;
00131 }
00132 switch (l->major) {
00133 case 1:
00134 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't sign v1.0 RPM\n"), rpm);
00135 goto exit;
00136 break;
00137 case 2:
00138 rpmError(RPMERR_BADSIGTYPE, _("%s: Can't re-sign v2.0 RPM\n"), rpm);
00139 goto exit;
00140 break;
00141 default:
00142 break;
00143 }
00144
00145 rc = rpmReadSignature(fd, &sig, l->signature_type);
00146 if (!(rc == RPMRC_OK || rc == RPMRC_BADSIZE)) {
00147 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed\n"), rpm);
00148 goto exit;
00149 }
00150 if (sig == NULL) {
00151 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), rpm);
00152 goto exit;
00153 }
00154
00155
00156
00157 if (copyFile(&fd, &rpm, &ofd, &sigtarget))
00158 goto exit;
00159
00160
00161
00162
00163 if (flags != RESIGN_ADD_SIGNATURE) {
00164 void * uh = NULL;
00165 int_32 uht, uhc;
00166
00167
00168 if (headerGetEntry(sig, RPMTAG_HEADERSIGNATURES, &uht, &uh, &uhc)) {
00169 Header nh = headerCopyLoad(uh);
00170 sig = headerFree(sig);
00171
00172 sig = headerLink(nh);
00173
00174 nh = headerFree(nh);
00175 }
00176
00177 (void) headerRemoveEntry(sig, RPMSIGTAG_SIZE);
00178 (void) headerRemoveEntry(sig, RPMSIGTAG_MD5);
00179 (void) headerRemoveEntry(sig, RPMSIGTAG_LEMD5_1);
00180 (void) headerRemoveEntry(sig, RPMSIGTAG_LEMD5_2);
00181 (void) headerRemoveEntry(sig, RPMSIGTAG_PGP5);
00182 (void) headerRemoveEntry(sig, RPMSIGTAG_PGP);
00183 (void) headerRemoveEntry(sig, RPMSIGTAG_GPG);
00184 (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_SIZE, passPhrase);
00185 (void) rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
00186 }
00187
00188 if ((sigtype = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) > 0)
00189 (void) rpmAddSignature(sig, sigtarget, sigtype, passPhrase);
00190
00191
00192 strcpy(tmprpm, rpm);
00193 strcat(tmprpm, ".XXXXXX");
00194 (void) mktemp(tmprpm) ;
00195 trpm = tmprpm;
00196
00197 if (manageFile(&ofd, &trpm, O_WRONLY|O_CREAT|O_TRUNC, 0))
00198 goto exit;
00199
00200 l->signature_type = RPMSIGTYPE_HEADERSIG;
00201 if (writeLead(ofd, l)) {
00202 rpmError(RPMERR_WRITELEAD, _("%s: writeLead failed: %s\n"), trpm,
00203 Fstrerror(ofd));
00204 goto exit;
00205 }
00206
00207 if (rpmWriteSignature(ofd, sig)) {
00208 rpmError(RPMERR_SIGGEN, _("%s: rpmWriteSignature failed: %s\n"), trpm,
00209 Fstrerror(ofd));
00210 goto exit;
00211 }
00212
00213
00214
00215 if (copyFile(&fd, &sigtarget, &ofd, &trpm))
00216 goto exit;
00217
00218
00219
00220
00221 (void) unlink(sigtarget);
00222 sigtarget = _free(sigtarget);
00223
00224
00225 (void) unlink(rpm);
00226 (void) rename(trpm, rpm);
00227 tmprpm[0] = '\0';
00228 }
00229
00230 res = 0;
00231
00232 exit:
00233 if (fd) (void) manageFile(&fd, NULL, 0, res);
00234 if (ofd) (void) manageFile(&ofd, NULL, 0, res);
00235
00236 sig = rpmFreeSignature(sig);
00237
00238 if (sigtarget) {
00239 (void) unlink(sigtarget);
00240 sigtarget = _free(sigtarget);
00241 }
00242 if (tmprpm[0] != '\0') {
00243 (void) unlink(tmprpm);
00244 tmprpm[0] = '\0';
00245 }
00246
00247 return res;
00248 }
00249
00250 int rpmCheckSig(rpmCheckSigFlags flags, const char ** argv)
00251 {
00252 FD_t fd = NULL;
00253 FD_t ofd = NULL;
00254 int res2, res3;
00255 struct rpmlead lead, *l = &lead;
00256 const char *rpm = NULL;
00257 char result[1024];
00258 const char * sigtarget = NULL;
00259 unsigned char buffer[8192];
00260 unsigned char missingKeys[7164];
00261 unsigned char untrustedKeys[7164];
00262 Header sig;
00263 HeaderIterator hi;
00264 int_32 tag, type, count;
00265 const void * ptr;
00266 int res = 0;
00267 rpmRC rc;
00268
00269 if (argv)
00270 while ((rpm = *argv++) != NULL) {
00271
00272 if (manageFile(&fd, &rpm, O_RDONLY, 0)) {
00273 res++;
00274 goto bottom;
00275 }
00276
00277 memset(l, 0, sizeof(*l));
00278 if (readLead(fd, l)) {
00279 rpmError(RPMERR_READLEAD, _("%s: readLead failed\n"), rpm);
00280 res++;
00281 goto bottom;
00282 }
00283 switch (l->major) {
00284 case 1:
00285 rpmError(RPMERR_BADSIGTYPE, _("%s: No signature available (v1.0 RPM)\n"), rpm);
00286 res++;
00287 goto bottom;
00288 break;
00289 default:
00290 break;
00291 }
00292
00293 rc = rpmReadSignature(fd, &sig, l->signature_type);
00294 if (!(rc == RPMRC_OK || rc == RPMRC_BADSIZE)) {
00295 rpmError(RPMERR_SIGGEN, _("%s: rpmReadSignature failed\n"), rpm);
00296 res++;
00297 goto bottom;
00298 }
00299 if (sig == NULL) {
00300 rpmError(RPMERR_SIGGEN, _("%s: No signature available\n"), rpm);
00301 res++;
00302 goto bottom;
00303 }
00304
00305
00306 if (copyFile(&fd, &rpm, &ofd, &sigtarget)) {
00307 res++;
00308 goto bottom;
00309 }
00310
00311
00312
00313 res2 = 0;
00314 missingKeys[0] = '\0';
00315 untrustedKeys[0] = '\0';
00316 sprintf(buffer, "%s:%c", rpm, (rpmIsVerbose() ? '\n' : ' ') );
00317
00318 for (hi = headerInitIterator(sig);
00319 headerNextIterator(hi, &tag, &type, &ptr, &count);
00320 ptr = headerFreeData(ptr, type))
00321 {
00322 switch (tag) {
00323 case RPMSIGTAG_PGP5:
00324 case RPMSIGTAG_PGP:
00325 if (!(flags & CHECKSIG_PGP))
00326 continue;
00327 break;
00328 case RPMSIGTAG_GPG:
00329 if (!(flags & CHECKSIG_GPG))
00330 continue;
00331 break;
00332 case RPMSIGTAG_LEMD5_2:
00333 case RPMSIGTAG_LEMD5_1:
00334 case RPMSIGTAG_MD5:
00335 if (!(flags & CHECKSIG_MD5))
00336 continue;
00337 break;
00338 default:
00339 continue;
00340 break;
00341 }
00342 if (ptr == NULL) continue;
00343
00344 if ((res3 = rpmVerifySignature(sigtarget, tag, ptr, count,
00345 result))) {
00346 if (rpmIsVerbose()) {
00347 strcat(buffer, result);
00348 res2 = 1;
00349 } else {
00350 char *tempKey;
00351 switch (tag) {
00352 case RPMSIGTAG_SIZE:
00353 strcat(buffer, "SIZE ");
00354 res2 = 1;
00355 break;
00356 case RPMSIGTAG_LEMD5_2:
00357 case RPMSIGTAG_LEMD5_1:
00358 case RPMSIGTAG_MD5:
00359 strcat(buffer, "MD5 ");
00360 res2 = 1;
00361 break;
00362 case RPMSIGTAG_PGP5:
00363 case RPMSIGTAG_PGP:
00364 switch (res3) {
00365 case RPMSIG_NOKEY:
00366 res2 = 1;
00367
00368 case RPMSIG_NOTTRUSTED:
00369 { int offset = 7;
00370 strcat(buffer, "(PGP) ");
00371 tempKey = strstr(result, "Key ID");
00372 if (tempKey == NULL) {
00373 tempKey = strstr(result, "keyid:");
00374 offset = 9;
00375 }
00376 if (tempKey) {
00377 if (res3 == RPMSIG_NOKEY) {
00378 strcat(missingKeys, " PGP#");
00379
00380 strncat(missingKeys, tempKey + offset, 8);
00381
00382 } else {
00383 strcat(untrustedKeys, " PGP#");
00384
00385 strncat(untrustedKeys, tempKey + offset, 8);
00386
00387 }
00388 }
00389 } break;
00390 default:
00391 strcat(buffer, "PGP ");
00392 res2 = 1;
00393 break;
00394 }
00395 break;
00396 case RPMSIGTAG_GPG:
00397
00398 switch (res3) {
00399 case RPMSIG_NOKEY:
00400 strcat(buffer, "(GPG) ");
00401 strcat(missingKeys, " GPG#");
00402 tempKey = strstr(result, "key ID");
00403 if (tempKey)
00404
00405 strncat(missingKeys, tempKey+7, 8);
00406
00407 res2 = 1;
00408 break;
00409 default:
00410 strcat(buffer, "GPG ");
00411 res2 = 1;
00412 break;
00413 }
00414 break;
00415 default:
00416 strcat(buffer, "?UnknownSignatureType? ");
00417 res2 = 1;
00418 break;
00419 }
00420 }
00421 } else {
00422 if (rpmIsVerbose()) {
00423 strcat(buffer, result);
00424 } else {
00425 switch (tag) {
00426 case RPMSIGTAG_SIZE:
00427 strcat(buffer, "size ");
00428 break;
00429 case RPMSIGTAG_LEMD5_2:
00430 case RPMSIGTAG_LEMD5_1:
00431 case RPMSIGTAG_MD5:
00432 strcat(buffer, "md5 ");
00433 break;
00434 case RPMSIGTAG_PGP5:
00435 case RPMSIGTAG_PGP:
00436 strcat(buffer, "pgp ");
00437 break;
00438 case RPMSIGTAG_GPG:
00439 strcat(buffer, "gpg ");
00440 break;
00441 default:
00442 strcat(buffer, "??? ");
00443 break;
00444 }
00445 }
00446 }
00447 }
00448 hi = headerFreeIterator(hi);
00449 res += res2;
00450 (void) unlink(sigtarget);
00451 sigtarget = _free(sigtarget);
00452
00453 if (res2) {
00454 if (rpmIsVerbose()) {
00455 rpmError(RPMERR_SIGVFY, "%s", (char *)buffer);
00456 } else {
00457 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", (char *)buffer,
00458 _("NOT OK"),
00459 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
00460 (char *)missingKeys,
00461 (missingKeys[0] != '\0') ? _(") ") : "",
00462 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
00463 (char *)untrustedKeys,
00464 (untrustedKeys[0] != '\0') ? _(")") : "");
00465
00466 }
00467 } else {
00468 if (rpmIsVerbose()) {
00469 rpmError(RPMERR_SIGVFY, "%s", (char *)buffer);
00470 } else {
00471 rpmError(RPMERR_SIGVFY, "%s%s%s%s%s%s%s%s\n", (char *)buffer,
00472 _("OK"),
00473 (missingKeys[0] != '\0') ? _(" (MISSING KEYS:") : "",
00474 (char *)missingKeys,
00475 (missingKeys[0] != '\0') ? _(") ") : "",
00476 (untrustedKeys[0] != '\0') ? _(" (UNTRUSTED KEYS:") : "",
00477 (char *)untrustedKeys,
00478 (untrustedKeys[0] != '\0') ? _(")") : "");
00479 }
00480 }
00481
00482 bottom:
00483 if (fd) (void) manageFile(&fd, NULL, 0, 0);
00484 if (ofd) (void) manageFile(&ofd, NULL, 0, 0);
00485 if (sigtarget) {
00486 (void) unlink(sigtarget);
00487 sigtarget = _free(sigtarget);
00488 }
00489 }
00490
00491 return res;
00492 }