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