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