179 lines
3.9 KiB
C
179 lines
3.9 KiB
C
/* checksig.c: verify the signature of an RPM */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
#include "checksig.h"
|
|
#include "rpmlib.h"
|
|
#include "rpmlead.h"
|
|
#include "signature.h"
|
|
|
|
int doReSign(char *passPhrase, char **argv)
|
|
{
|
|
int fd, ofd, count;
|
|
struct rpmlead lead;
|
|
unsigned short sigtype;
|
|
char *sig, *rpm, *sigtarget;
|
|
char tmprpm[1024];
|
|
unsigned char buffer[8192];
|
|
|
|
/* Figure out the signature type */
|
|
if ((sigtype = sigLookupType()) == RPMSIG_BAD) {
|
|
fprintf(stderr, "Bad signature type in rpmrc\n");
|
|
exit(1);
|
|
}
|
|
|
|
while (*argv) {
|
|
rpm = *argv++;
|
|
if ((fd = open(rpm, O_RDONLY, 0644)) < 0) {
|
|
fprintf(stderr, "%s: Open failed\n", rpm);
|
|
exit(1);
|
|
}
|
|
if (readLead(fd, &lead)) {
|
|
fprintf(stderr, "%s: readLead failed\n", rpm);
|
|
exit(1);
|
|
}
|
|
if (lead.major == 1) {
|
|
fprintf(stderr, "%s: Can't sign v1.0 RPM\n", rpm);
|
|
exit(1);
|
|
}
|
|
if (!readSignature(fd, lead.signature_type, (void **) &sig)) {
|
|
fprintf(stderr, "%s: readSignature failed\n", rpm);
|
|
exit(1);
|
|
}
|
|
if (sig) {
|
|
free(sig);
|
|
}
|
|
|
|
/* Write the rest to a temp file */
|
|
sigtarget = tempnam("/var/tmp", "rpmbuild");
|
|
ofd = open(sigtarget, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
|
while ((count = read(fd, buffer, sizeof(buffer))) > 0) {
|
|
if (count == -1) {
|
|
perror("Couldn't read the header/archvie");
|
|
close(ofd);
|
|
unlink(sigtarget);
|
|
exit(1);
|
|
}
|
|
if (write(ofd, buffer, count) < 0) {
|
|
perror("Couldn't write header/archive to temp file");
|
|
close(ofd);
|
|
unlink(sigtarget);
|
|
exit(1);
|
|
}
|
|
}
|
|
close(fd);
|
|
close(ofd);
|
|
|
|
/* Start writing the new RPM */
|
|
sprintf(tmprpm, "%s.tmp", rpm);
|
|
ofd = open(tmprpm, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
|
lead.signature_type = sigtype;
|
|
if (writeLead(ofd, &lead)) {
|
|
perror("writeLead()");
|
|
close(ofd);
|
|
unlink(sigtarget);
|
|
unlink(tmprpm);
|
|
exit(1);
|
|
}
|
|
|
|
/* Generate the signature */
|
|
if (makeSignature(sigtarget, sigtype, ofd, passPhrase)) {
|
|
fprintf(stderr, "makeSignature() failed\n");
|
|
close(ofd);
|
|
unlink(sigtarget);
|
|
unlink(tmprpm);
|
|
exit(1);
|
|
}
|
|
|
|
/* Append the header and archive */
|
|
fd = open(sigtarget, O_RDONLY);
|
|
while ((count = read(fd, buffer, sizeof(buffer))) > 0) {
|
|
if (count == -1) {
|
|
perror("Couldn't read sigtarget");
|
|
close(ofd);
|
|
close(fd);
|
|
unlink(sigtarget);
|
|
unlink(tmprpm);
|
|
exit(1);
|
|
}
|
|
if (write(ofd, buffer, count) < 0) {
|
|
perror("Couldn't write package");
|
|
close(ofd);
|
|
close(fd);
|
|
unlink(sigtarget);
|
|
unlink(tmprpm);
|
|
exit(1);
|
|
}
|
|
}
|
|
close(fd);
|
|
close(ofd);
|
|
unlink(sigtarget);
|
|
|
|
/* Move it in to place */
|
|
unlink(rpm);
|
|
rename(tmprpm, rpm);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int doCheckSig(char **argv)
|
|
{
|
|
int fd;
|
|
struct rpmlead lead;
|
|
char *sig, *rpm;
|
|
char result[1024];
|
|
int res = 0;
|
|
int xres;
|
|
|
|
while (*argv) {
|
|
rpm = *argv++;
|
|
if ((fd = open(rpm, O_RDONLY, 0644)) < 0) {
|
|
fprintf(stderr, "%s: Open failed\n", rpm);
|
|
res = -1;
|
|
continue;
|
|
}
|
|
if (readLead(fd, &lead)) {
|
|
fprintf(stderr, "%s: readLead failed\n", rpm);
|
|
res = -1;
|
|
continue;
|
|
}
|
|
if (lead.major == 1) {
|
|
fprintf(stderr, "%s: No signature available (v1.0 RPM)\n", rpm);
|
|
res = -1;
|
|
continue;
|
|
}
|
|
if (!readSignature(fd, lead.signature_type, (void **) &sig)) {
|
|
fprintf(stderr, "%s: readSignature failed\n", rpm);
|
|
res = -1;
|
|
continue;
|
|
}
|
|
|
|
xres = verifySignature(fd, lead.signature_type, sig, result);
|
|
if (!xres) {
|
|
if (isVerbose()) {
|
|
printf("%s: %s", rpm, result);
|
|
}
|
|
printf("%s: Signature OK.\n", rpm);
|
|
} else {
|
|
if (isVerbose()) {
|
|
fprintf(stderr, "%s: %s", rpm, result);
|
|
}
|
|
if (xres == RPMSIG_NOSIG) {
|
|
fprintf(stderr, "%s: No signature available.\n", rpm);
|
|
} else if (xres == RPMSIG_UNKNOWNSIG) {
|
|
fprintf(stderr, "%s: Unknown signature type.\n", rpm);
|
|
} else {
|
|
fprintf(stderr, "%s: Signature NOT OK!\n", rpm);
|
|
}
|
|
res = -1;
|
|
}
|
|
close(fd);
|
|
}
|
|
|
|
return res;
|
|
}
|