Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/pkg/pkg.c
Show All 27 Lines | |||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/sbuf.h> | |||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <archive.h> | #include <archive.h> | ||||
#include <archive_entry.h> | #include <archive_entry.h> | ||||
#include <dirent.h> | #include <dirent.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
▲ Show 20 Lines • Show All 545 Lines • ▼ Show 20 Lines | cleanup: | ||||
return (ret); | return (ret); | ||||
} | } | ||||
static struct pubkey * | static struct pubkey * | ||||
read_pubkey(int fd) | read_pubkey(int fd) | ||||
{ | { | ||||
struct pubkey *pk; | struct pubkey *pk; | ||||
struct sbuf *sig; | char *sigb; | ||||
size_t sigsz; | |||||
FILE *sig; | |||||
char buf[4096]; | char buf[4096]; | ||||
int r; | int r; | ||||
if (lseek(fd, 0, 0) == -1) { | if (lseek(fd, 0, 0) == -1) { | ||||
warn("lseek"); | warn("lseek"); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
sig = sbuf_new_auto(); | sigsz = 0; | ||||
sigb = NULL; | |||||
sig = open_memstream(&sigb, &sigsz); | |||||
if (sig == NULL) | |||||
err(EXIT_FAILURE, "open_memstream()"); | |||||
while ((r = read(fd, buf, sizeof(buf))) >0) { | while ((r = read(fd, buf, sizeof(buf))) >0) { | ||||
sbuf_bcat(sig, buf, r); | fwrite(buf, 1, r, sig); | ||||
} | } | ||||
sbuf_finish(sig); | fclose(sig); | ||||
pk = calloc(1, sizeof(struct pubkey)); | pk = calloc(1, sizeof(struct pubkey)); | ||||
pk->siglen = sbuf_len(sig); | pk->siglen = sigsz; | ||||
pk->sig = calloc(1, pk->siglen); | pk->sig = calloc(1, pk->siglen); | ||||
memcpy(pk->sig, sbuf_data(sig), pk->siglen); | memcpy(pk->sig, sigb, pk->siglen); | ||||
sbuf_delete(sig); | free(sigb); | ||||
return (pk); | return (pk); | ||||
} | } | ||||
static struct sig_cert * | static struct sig_cert * | ||||
parse_cert(int fd) { | parse_cert(int fd) { | ||||
int my_fd; | int my_fd; | ||||
struct sig_cert *sc; | struct sig_cert *sc; | ||||
FILE *fp; | FILE *fp, *sigfp, *certfp, *tmpfp; | ||||
struct sbuf *buf, *sig, *cert; | |||||
char *line; | char *line; | ||||
size_t linecap; | char *sig, *cert; | ||||
size_t linecap, sigsz, certsz; | |||||
ssize_t linelen; | ssize_t linelen; | ||||
buf = NULL; | |||||
sc = NULL; | sc = NULL; | ||||
line = NULL; | line = NULL; | ||||
linecap = 0; | linecap = 0; | ||||
sig = cert = NULL; | |||||
sigfp = certfp = tmpfp = NULL; | |||||
if (lseek(fd, 0, 0) == -1) { | if (lseek(fd, 0, 0) == -1) { | ||||
warn("lseek"); | warn("lseek"); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
/* Duplicate the fd so that fclose(3) does not close it. */ | /* Duplicate the fd so that fclose(3) does not close it. */ | ||||
if ((my_fd = dup(fd)) == -1) { | if ((my_fd = dup(fd)) == -1) { | ||||
warnx("dup"); | warnx("dup"); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
if ((fp = fdopen(my_fd, "rb")) == NULL) { | if ((fp = fdopen(my_fd, "rb")) == NULL) { | ||||
warn("fdopen"); | warn("fdopen"); | ||||
close(my_fd); | close(my_fd); | ||||
return (NULL); | return (NULL); | ||||
} | } | ||||
sig = sbuf_new_auto(); | sigsz = certsz = 0; | ||||
cert = sbuf_new_auto(); | sigfp = open_memstream(&sig, &sigsz); | ||||
if (sigfp == NULL) | |||||
err(EXIT_FAILURE, "open_memstream()"); | |||||
certfp = open_memstream(&cert, &certsz); | |||||
if (certfp == NULL) | |||||
err(EXIT_FAILURE, "open_memstream()"); | |||||
while ((linelen = getline(&line, &linecap, fp)) > 0) { | while ((linelen = getline(&line, &linecap, fp)) > 0) { | ||||
if (strcmp(line, "SIGNATURE\n") == 0) { | if (strcmp(line, "SIGNATURE\n") == 0) { | ||||
buf = sig; | tmpfp = sigfp; | ||||
continue; | continue; | ||||
} else if (strcmp(line, "CERT\n") == 0) { | } else if (strcmp(line, "CERT\n") == 0) { | ||||
buf = cert; | tmpfp = certfp; | ||||
continue; | continue; | ||||
} else if (strcmp(line, "END\n") == 0) { | } else if (strcmp(line, "END\n") == 0) { | ||||
break; | break; | ||||
} | } | ||||
if (buf != NULL) | if (tmpfp != NULL) | ||||
sbuf_bcat(buf, line, linelen); | fwrite(line, 1, linelen, tmpfp); | ||||
} | } | ||||
fclose(fp); | fclose(fp); | ||||
fclose(sigfp); | |||||
fclose(certfp); | |||||
/* Trim out unrelated trailing newline */ | |||||
sbuf_setpos(sig, sbuf_len(sig) - 1); | |||||
sbuf_finish(sig); | |||||
sbuf_finish(cert); | |||||
sc = calloc(1, sizeof(struct sig_cert)); | sc = calloc(1, sizeof(struct sig_cert)); | ||||
sc->siglen = sbuf_len(sig); | sc->siglen = sigsz -1; /* Trim out unrelated trailing newline */ | ||||
sc->sig = calloc(1, sc->siglen); | sc->sig = sig; | ||||
memcpy(sc->sig, sbuf_data(sig), sc->siglen); | |||||
sc->certlen = sbuf_len(cert); | sc->certlen = certsz; | ||||
sc->cert = strdup(sbuf_data(cert)); | sc->cert = cert; | ||||
sbuf_delete(sig); | |||||
sbuf_delete(cert); | |||||
return (sc); | return (sc); | ||||
} | } | ||||
static bool | static bool | ||||
verify_pubsignature(int fd_pkg, int fd_sig) | verify_pubsignature(int fd_pkg, int fd_sig) | ||||
{ | { | ||||
struct pubkey *pk; | struct pubkey *pk; | ||||
▲ Show 20 Lines • Show All 532 Lines • Show Last 20 Lines |