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