home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / misc / src / rpm / checksig.c < prev    next >
C/C++ Source or Header  |  1997-09-17  |  7KB  |  304 lines

  1. /* checksig.c: verify the signature of an RPM */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <string.h>
  8.  
  9. #include "checksig.h"
  10. #include "intl.h"
  11. #include "rpmlib.h"
  12. #include "rpmlead.h"
  13. #include "signature.h"
  14. #include "messages.h"
  15. #include "lib/misc.h"
  16.  
  17. int doReSign(int add, char *passPhrase, char **argv)
  18. {
  19.     int fd, ofd, count;
  20.     struct rpmlead lead;
  21.     unsigned short sigtype;
  22.     char *rpm, *sigtarget;
  23.     char tmprpm[1024];
  24.     unsigned char buffer[8192];
  25.     Header sig;
  26.     
  27.     while (*argv) {
  28.     rpm = *argv++;
  29.     printf("%s:\n", rpm);
  30.     if ((fd = open(rpm, O_RDONLY, 0644)) < 0) {
  31.         fprintf(stderr, _("%s: Open failed\n"), rpm);
  32.         exit(1);
  33.     }
  34.     if (readLead(fd, &lead)) {
  35.         fprintf(stderr, _("%s: readLead failed\n"), rpm);
  36.         exit(1);
  37.     }
  38.     if (lead.major == 1) {
  39.         fprintf(stderr, _("%s: Can't sign v1.0 RPM\n"), rpm);
  40.         exit(1);
  41.     }
  42.     if (lead.major == 2) {
  43.         fprintf(stderr, _("%s: Can't re-sign v2.0 RPM\n"), rpm);
  44.         exit(1);
  45.     }
  46.     if (rpmReadSignature(fd, &sig, lead.signature_type)) {
  47.         fprintf(stderr, _("%s: rpmReadSignature failed\n"), rpm);
  48.         exit(1);
  49.     }
  50.     if (add != ADD_SIGNATURE) {
  51.         rpmFreeSignature(sig);
  52.     }
  53.  
  54.     /* Write the rest to a temp file */
  55.     if (makeTempFile(NULL, &sigtarget, &ofd))
  56.         exit(1);
  57.  
  58.     while ((count = read(fd, buffer, sizeof(buffer))) > 0) {
  59.         if (count == -1) {
  60.         perror(_("Couldn't read the header/archive"));
  61.         close(ofd);
  62.         unlink(sigtarget);
  63.         free(sigtarget);
  64.         exit(1);
  65.         }
  66.         if (write(ofd, buffer, count) < 0) {
  67.         perror(_("Couldn't write header/archive to temp file"));
  68.         close(ofd);
  69.         unlink(sigtarget);
  70.         free(sigtarget);
  71.         exit(1);
  72.         }
  73.     }
  74.     close(fd);
  75.     close(ofd);
  76.  
  77.     /* Start writing the new RPM */
  78.     sprintf(tmprpm, "%s.tmp", rpm);
  79.     ofd = open(tmprpm, O_WRONLY|O_CREAT|O_TRUNC, 0644);
  80.     lead.signature_type = RPMSIG_HEADERSIG;
  81.     if (writeLead(ofd, &lead)) {
  82.         perror("writeLead()");
  83.         close(ofd);
  84.         unlink(sigtarget);
  85.         unlink(tmprpm);
  86.         free(sigtarget);
  87.         exit(1);
  88.     }
  89.  
  90.     /* Generate the signature */
  91.     sigtype = rpmLookupSignatureType();
  92.     rpmMessage(RPMMESS_VERBOSE, "Generating signature: %d\n", sigtype);
  93.     if (add != ADD_SIGNATURE) {
  94.         sig = rpmNewSignature();
  95.         rpmAddSignature(sig, sigtarget, RPMSIGTAG_SIZE, passPhrase);
  96.         rpmAddSignature(sig, sigtarget, RPMSIGTAG_MD5, passPhrase);
  97.     }
  98.     if (sigtype>0) {
  99.         rpmAddSignature(sig, sigtarget, sigtype, passPhrase);
  100.     }
  101.     if (rpmWriteSignature(ofd, sig)) {
  102.         close(ofd);
  103.         unlink(sigtarget);
  104.         unlink(tmprpm);
  105.         free(sigtarget);
  106.         rpmFreeSignature(sig);
  107.         exit(1);
  108.     }
  109.     rpmFreeSignature(sig);
  110.  
  111.     /* Append the header and archive */
  112.     fd = open(sigtarget, O_RDONLY);
  113.     while ((count = read(fd, buffer, sizeof(buffer))) > 0) {
  114.         if (count == -1) {
  115.         perror(_("Couldn't read sigtarget"));
  116.         close(ofd);
  117.         close(fd);
  118.         unlink(sigtarget);
  119.         unlink(tmprpm);
  120.         free(sigtarget);
  121.         exit(1);
  122.         }
  123.         if (write(ofd, buffer, count) < 0) {
  124.         perror(_("Couldn't write package"));
  125.         close(ofd);
  126.         close(fd);
  127.         unlink(sigtarget);
  128.         unlink(tmprpm);
  129.         free(sigtarget);
  130.         exit(1);
  131.         }
  132.     }
  133.     close(fd);
  134.     close(ofd);
  135.     unlink(sigtarget);
  136.     free(sigtarget);
  137.  
  138.     /* Move it in to place */
  139.     unlink(rpm);
  140.     rename(tmprpm, rpm);
  141.     }
  142.  
  143.     return 0;
  144. }
  145.  
  146. int doCheckSig(int flags, char **argv)
  147. {
  148.     int fd, ofd, res, res2, res3, missingKeys;
  149.     struct rpmlead lead;
  150.     char *rpm;
  151.     char result[1024], * sigtarget;
  152.     unsigned char buffer[8192];
  153.     Header sig;
  154.     HeaderIterator sigIter;
  155.     int_32 tag, type, count;
  156.     void *ptr;
  157.  
  158.     res = 0;
  159.     while (*argv) {
  160.     rpm = *argv++;
  161.     if ((fd = open(rpm, O_RDONLY, 0644)) < 0) {
  162.         fprintf(stderr, _("%s: Open failed\n"), rpm);
  163.         res++;
  164.         continue;
  165.     }
  166.     if (readLead(fd, &lead)) {
  167.         fprintf(stderr, _("%s: readLead failed\n"), rpm);
  168.         res++;
  169.         continue;
  170.     }
  171.     if (lead.major == 1) {
  172.         fprintf(stderr, _("%s: No signature available (v1.0 RPM)\n"), rpm);
  173.         res++;
  174.         continue;
  175.     }
  176.     if (rpmReadSignature(fd, &sig, lead.signature_type)) {
  177.         fprintf(stderr, _("%s: rpmReadSignature failed\n"), rpm);
  178.         res++;
  179.         continue;
  180.     }
  181.     if (! sig) {
  182.         fprintf(stderr, _("%s: No signature available\n"), rpm);
  183.         res++;
  184.         continue;
  185.     }
  186.     /* Write the rest to a temp file */
  187.     if (makeTempFile(NULL, &sigtarget, &ofd))
  188.         exit(1);
  189.     while ((count = read(fd, buffer, sizeof(buffer))) > 0) {
  190.         if (count == -1) {
  191.         perror(_("Couldn't read the header/archive"));
  192.         close(ofd);
  193.         unlink(sigtarget);
  194.         free(sigtarget);
  195.         exit(1);
  196.         }
  197.         if (write(ofd, buffer, count) < 0) {
  198.         fprintf(stderr, _("Unable to write %s"), sigtarget);
  199.         perror("");
  200.         close(ofd);
  201.         unlink(sigtarget);
  202.         free(sigtarget);
  203.         exit(1);
  204.         }
  205.     }
  206.     close(fd);
  207.     close(ofd);
  208.  
  209.     sigIter = headerInitIterator(sig);
  210.     res2 = 0;
  211.     missingKeys = 0;
  212.     if (rpmIsVerbose()) {
  213.         sprintf(buffer, "%s:\n", rpm);
  214.     } else {
  215.         sprintf(buffer, "%s: ", rpm);
  216.     }
  217.     while (headerNextIterator(sigIter, &tag, &type, &ptr, &count)) {
  218.         if ((tag == RPMSIGTAG_PGP) && !(flags & CHECKSIG_PGP)) 
  219.         continue;
  220.         else if ((tag == RPMSIGTAG_MD5 || 
  221.               tag == RPMSIGTAG_LEMD5_2 ||
  222.               tag == RPMSIGTAG_LEMD5_1) 
  223.               && !(flags & CHECKSIG_MD5)) 
  224.         continue;
  225.  
  226.         if ((res3 = rpmVerifySignature(sigtarget, tag, ptr, count, 
  227.                        result))) {
  228.         if (rpmIsVerbose()) {
  229.             strcat(buffer, result);
  230.             res2 = 1;
  231.         } else {
  232.             switch (tag) {
  233.               case RPMSIGTAG_SIZE:
  234.             strcat(buffer, "SIZE ");
  235.             res2 = 1;
  236.             break;
  237.               case RPMSIGTAG_MD5:
  238.               case RPMSIGTAG_LEMD5_1:
  239.               case RPMSIGTAG_LEMD5_2:
  240.             strcat(buffer, "MD5 ");
  241.             res2 = 1;
  242.             break;
  243.               case RPMSIGTAG_PGP:
  244.             if (res3 == RPMSIG_NOKEY) {
  245.                 /* Do not consedier this a failure */
  246.                 strcat(buffer, "(PGP) ");
  247.                 missingKeys = 1;
  248.             } else {
  249.                 strcat(buffer, "PGP ");
  250.                 res2 = 1;
  251.             }
  252.             break;
  253.               default:
  254.             strcat(buffer, "?UnknownSignatureType? ");
  255.             res2 = 1;
  256.             }
  257.         }
  258.         } else {
  259.         if (rpmIsVerbose()) {
  260.             strcat(buffer, result);
  261.         } else {
  262.             switch (tag) {
  263.               case RPMSIGTAG_SIZE:
  264.             strcat(buffer, "size ");
  265.             break;
  266.               case RPMSIGTAG_MD5:
  267.               case RPMSIGTAG_LEMD5_1:
  268.               case RPMSIGTAG_LEMD5_2:
  269.             strcat(buffer, "md5 ");
  270.             break;
  271.               case RPMSIGTAG_PGP:
  272.             strcat(buffer, "pgp ");
  273.             break;
  274.               default:
  275.             strcat(buffer, "??? ");
  276.             }
  277.         }
  278.         }
  279.     }
  280.     headerFreeIterator(sigIter);
  281.     res += res2;
  282.     unlink(sigtarget);
  283.     free(sigtarget);
  284.  
  285.     if (res2) {
  286.         if (rpmIsVerbose()) {
  287.         fprintf(stderr, "%s", buffer);
  288.         } else {
  289.         fprintf(stderr, "%sNOT OK%s\n", buffer,
  290.             missingKeys ? _(" (MISSING KEYS)") : "");
  291.         }
  292.     } else {
  293.         if (rpmIsVerbose()) {
  294.         printf("%s", buffer);
  295.         } else {
  296.         printf("%sOK%s\n", buffer,
  297.                missingKeys ? _(" (MISSING KEYS)") : "");
  298.         }
  299.     }
  300.     }
  301.  
  302.     return res;
  303. }
  304.