Make rpmlead opaque, add methods to deal with it
- rename methods to rpmLead*() for easy grepping - populate lead from header where necessary - add rpmLeadCheck() method for minimal compatibility checking to get rid of duplicate code in several places - conditionalize lead version on dirtokens
This commit is contained in:
parent
89ecfb96d0
commit
92698df723
65
build/pack.c
65
build/pack.c
|
@ -283,7 +283,7 @@ int readRPM(const char *fileName, rpmSpec *specp, struct rpmlead *lead,
|
|||
}
|
||||
|
||||
/* Get copy of lead */
|
||||
if ((rc = Fread(lead, sizeof(char), sizeof(*lead), fdi)) != sizeof(*lead)) {
|
||||
if ((rc = Fread(lead, sizeof(char), RPMLEAD_SIZE, fdi)) != RPMLEAD_SIZE) {
|
||||
rpmlog(RPMLOG_ERR, _("readRPM: read %s: %s\n"),
|
||||
(fileName ? fileName : "<stdin>"),
|
||||
Fstrerror(fdi));
|
||||
|
@ -347,35 +347,6 @@ int readRPM(const char *fileName, rpmSpec *specp, struct rpmlead *lead,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DYING
|
||||
static unsigned char header_magic[8] = {
|
||||
0x8e, 0xad, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
#define RPMPKGVERSION_MIN 30004
|
||||
#define RPMPKGVERSION_MAX 40003
|
||||
static int rpmpkg_version = -1;
|
||||
|
||||
static int rpmLeadVersion(void)
|
||||
{
|
||||
int rpmlead_version;
|
||||
|
||||
/* Intitialize packaging version from macro configuration. */
|
||||
if (rpmpkg_version < 0) {
|
||||
rpmpkg_version = rpmExpandNumeric("%{_package_version}");
|
||||
if (rpmpkg_version < RPMPKGVERSION_MIN)
|
||||
rpmpkg_version = RPMPKGVERSION_MIN;
|
||||
if (rpmpkg_version > RPMPKGVERSION_MAX)
|
||||
rpmpkg_version = RPMPKGVERSION_MAX;
|
||||
}
|
||||
|
||||
rpmlead_version = rpmpkg_version / 10000;
|
||||
if (_noDirTokens || (rpmlead_version < 3 || rpmlead_version > 4))
|
||||
rpmlead_version = 3;
|
||||
return rpmlead_version;
|
||||
}
|
||||
|
||||
int writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
|
||||
int type, CSA_t csa, char *passPhrase, const char **cookie)
|
||||
{
|
||||
|
@ -526,35 +497,11 @@ int writeRPM(Header *hdrp, unsigned char ** pkgidp, const char *fileName,
|
|||
}
|
||||
|
||||
/* Write the lead section into the package. */
|
||||
{ int archnum = -1;
|
||||
int osnum = -1;
|
||||
struct rpmlead lead;
|
||||
|
||||
if (Fileno(csa->cpioFdIn) < 0) {
|
||||
#ifndef DYING
|
||||
rpmGetArchInfo(NULL, &archnum);
|
||||
rpmGetOsInfo(NULL, &osnum);
|
||||
#endif
|
||||
} else if (csa->lead != NULL) {
|
||||
archnum = csa->lead->archnum;
|
||||
osnum = csa->lead->osnum;
|
||||
}
|
||||
|
||||
memset(&lead, 0, sizeof(lead));
|
||||
lead.major = rpmLeadVersion();
|
||||
lead.minor = 0;
|
||||
lead.type = type;
|
||||
lead.archnum = archnum;
|
||||
lead.osnum = osnum;
|
||||
lead.signature_type = RPMSIGTYPE_HEADERSIG;
|
||||
|
||||
{ const char *name, *version, *release;
|
||||
(void) headerNVR(h, &name, &version, &release);
|
||||
sprintf(buf, "%s-%s-%s", name, version, release);
|
||||
strncpy(lead.name, buf, sizeof(lead.name));
|
||||
}
|
||||
|
||||
if (writeLead(fd, &lead) != RPMRC_OK) {
|
||||
{
|
||||
rpmlead lead = rpmLeadFromHeader(h);
|
||||
int rc = rpmLeadWrite(fd, lead);
|
||||
lead = rpmLeadFree(lead);
|
||||
if (rc != RPMRC_OK) {
|
||||
rc = RPMLOG_ERR;
|
||||
rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
|
||||
Fstrerror(fd));
|
||||
|
|
|
@ -677,7 +677,7 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
|
|||
pgpDig dig;
|
||||
char buf[8*BUFSIZ];
|
||||
ssize_t count;
|
||||
struct rpmlead * l = alloca(sizeof(*l));
|
||||
rpmlead l = NULL;
|
||||
Header sigh = NULL;
|
||||
int32_t sigtag;
|
||||
int32_t sigtype;
|
||||
|
@ -693,33 +693,19 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t fd, const char * fn, Header * hdrp)
|
|||
|
||||
if (hdrp) *hdrp = NULL;
|
||||
|
||||
memset(l, 0, sizeof(*l));
|
||||
rc = readLead(fd, l);
|
||||
l = rpmLeadNew();
|
||||
|
||||
if ((rc = rpmLeadRead(fd, l)) == RPMRC_OK) {
|
||||
rc = rpmLeadCheck(l, fn);
|
||||
}
|
||||
l = rpmLeadFree(l);
|
||||
|
||||
if (rc != RPMRC_OK)
|
||||
goto exit;
|
||||
|
||||
switch (l->major) {
|
||||
case 1:
|
||||
rpmlog(RPMLOG_ERR,
|
||||
_("packaging version 1 is not supported by this version of RPM\n"));
|
||||
rc = RPMRC_NOTFOUND;
|
||||
goto exit;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
break;
|
||||
default:
|
||||
rpmlog(RPMLOG_ERR, _("only packaging with major numbers <= 4 "
|
||||
"is supported by this version of RPM\n"));
|
||||
rc = RPMRC_NOTFOUND;
|
||||
goto exit;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read the signature header. */
|
||||
msg = NULL;
|
||||
rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
|
||||
rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
|
||||
switch (rc) {
|
||||
default:
|
||||
rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), fn,
|
||||
|
|
27
lib/psm.c
27
lib/psm.c
|
@ -1487,34 +1487,17 @@ assert(psm->mi == NULL);
|
|||
rc = rpmpsmNext(psm, PSM_RPMIO_FLAGS);
|
||||
|
||||
/* Write the lead section into the package. */
|
||||
{ int archnum = -1;
|
||||
int osnum = -1;
|
||||
struct rpmlead lead;
|
||||
|
||||
#ifndef DYING
|
||||
rpmGetArchInfo(NULL, &archnum);
|
||||
rpmGetOsInfo(NULL, &osnum);
|
||||
#endif
|
||||
|
||||
memset(&lead, 0, sizeof(lead));
|
||||
/* XXX Set package version conditioned on noDirTokens. */
|
||||
lead.major = 3;
|
||||
lead.minor = 0;
|
||||
lead.type = RPMLEAD_BINARY;
|
||||
lead.archnum = archnum;
|
||||
lead.osnum = osnum;
|
||||
lead.signature_type = RPMSIGTYPE_HEADERSIG;
|
||||
|
||||
strncpy(lead.name, rpmteNEVR(psm->te), sizeof(lead.name));
|
||||
|
||||
rc = writeLead(psm->fd, &lead);
|
||||
{
|
||||
rpmlead lead = rpmLeadFromHeader(psm->oh);
|
||||
rc = rpmLeadWrite(psm->fd, lead);
|
||||
lead = rpmLeadFree(lead);
|
||||
if (rc != RPMRC_OK) {
|
||||
rpmlog(RPMLOG_ERR, _("Unable to write package: %s\n"),
|
||||
Fstrerror(psm->fd));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write the signature section into the package. */
|
||||
/* XXX rpm-4.1 and later has archive size in signature header. */
|
||||
{ Header sigh = headerRegenSigHeader(fi->h, noArchiveSize);
|
||||
|
|
|
@ -154,7 +154,7 @@ static int rpmReSign(rpmts ts,
|
|||
{
|
||||
FD_t fd = NULL;
|
||||
FD_t ofd = NULL;
|
||||
struct rpmlead lead, *l = &lead;
|
||||
rpmlead lead;
|
||||
int32_t sigtag;
|
||||
const char *rpm, *trpm;
|
||||
const char *sigtarget = NULL;
|
||||
|
@ -178,27 +178,19 @@ static int rpmReSign(rpmts ts,
|
|||
if (manageFile(&fd, &rpm, O_RDONLY, 0))
|
||||
goto exit;
|
||||
|
||||
memset(l, 0, sizeof(*l));
|
||||
rc = readLead(fd, l);
|
||||
if (rc != RPMRC_OK) {
|
||||
rpmlog(RPMLOG_ERR, _("%s: not an rpm package\n"), rpm);
|
||||
goto exit;
|
||||
lead = rpmLeadNew();
|
||||
|
||||
if ((rc = rpmLeadRead(fd, lead)) == RPMRC_OK) {
|
||||
rc = rpmLeadCheck(lead, rpm);
|
||||
}
|
||||
switch (l->major) {
|
||||
case 1:
|
||||
rpmlog(RPMLOG_ERR, _("%s: Can't sign v1 packaging\n"), rpm);
|
||||
|
||||
if (rc != RPMRC_OK) {
|
||||
lead = rpmLeadFree(lead);
|
||||
goto exit;
|
||||
break;
|
||||
case 2:
|
||||
rpmlog(RPMLOG_ERR, _("%s: Can't re-sign v2 packaging\n"), rpm);
|
||||
goto exit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
msg = NULL;
|
||||
rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
|
||||
rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
|
||||
switch (rc) {
|
||||
default:
|
||||
rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), rpm,
|
||||
|
@ -338,8 +330,8 @@ static int rpmReSign(rpmts ts,
|
|||
if (manageFile(&ofd, &trpm, O_WRONLY|O_CREAT|O_TRUNC, 0))
|
||||
goto exit;
|
||||
|
||||
l->signature_type = RPMSIGTYPE_HEADERSIG;
|
||||
rc = writeLead(ofd, l);
|
||||
rc = rpmLeadWrite(ofd, lead);
|
||||
lead = rpmLeadFree(lead);
|
||||
if (rc != RPMRC_OK) {
|
||||
rpmlog(RPMLOG_ERR, _("%s: writeLead failed: %s\n"), trpm,
|
||||
Fstrerror(ofd));
|
||||
|
@ -522,7 +514,6 @@ int rpmVerifySignatures(QVA_t qva, rpmts ts, FD_t fd,
|
|||
const char * fn)
|
||||
{
|
||||
int res2, res3;
|
||||
struct rpmlead lead, *l = &lead;
|
||||
char result[1024];
|
||||
char buf[8192], * b;
|
||||
char missingKeys[7164], * m;
|
||||
|
@ -543,25 +534,20 @@ int rpmVerifySignatures(QVA_t qva, rpmts ts, FD_t fd,
|
|||
int nosignatures = !(qva->qva_flags & VERIFY_SIGNATURE);
|
||||
|
||||
{
|
||||
memset(l, 0, sizeof(*l));
|
||||
rc = readLead(fd, l);
|
||||
if (rc != RPMRC_OK) {
|
||||
rpmlog(RPMLOG_ERR, _("%s: not an rpm package\n"), fn);
|
||||
rpmlead lead = rpmLeadNew();
|
||||
if ((rc = rpmLeadRead(fd, lead)) == RPMRC_OK) {
|
||||
rc = rpmLeadCheck(lead, fn);
|
||||
}
|
||||
lead = rpmLeadFree(lead);
|
||||
|
||||
if (rc != RPMRC_OK) {
|
||||
res++;
|
||||
goto exit;
|
||||
}
|
||||
switch (l->major) {
|
||||
case 1:
|
||||
rpmlog(RPMLOG_ERR, _("%s: No signature available (v1.0 RPM)\n"), fn);
|
||||
res++;
|
||||
goto exit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
msg = NULL;
|
||||
rc = rpmReadSignature(fd, &sigh, l->signature_type, &msg);
|
||||
rc = rpmReadSignature(fd, &sigh, RPMSIGTYPE_HEADERSIG, &msg);
|
||||
switch (rc) {
|
||||
default:
|
||||
rpmlog(RPMLOG_ERR, _("%s: rpmReadSignature failed: %s"), fn,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "lib/signature.h"
|
||||
#include "lib/rpmlead.h"
|
||||
#include "lib/legacy.h"
|
||||
#include <rpmlog.h>
|
||||
#include "debug.h"
|
||||
|
||||
|
@ -17,19 +18,74 @@ static unsigned char lead_magic[] = {
|
|||
RPMLEAD_MAGIC0, RPMLEAD_MAGIC1, RPMLEAD_MAGIC2, RPMLEAD_MAGIC3
|
||||
};
|
||||
|
||||
/* The lead needs to be 8 byte aligned */
|
||||
/** \ingroup lead
|
||||
* The lead data structure.
|
||||
* The lead needs to be 8 byte aligned.
|
||||
* @deprecated The lead (except for signature_type) is legacy.
|
||||
* @todo Don't use any information from lead.
|
||||
*/
|
||||
struct rpmlead_s {
|
||||
unsigned char magic[4];
|
||||
unsigned char major;
|
||||
unsigned char minor;
|
||||
short type;
|
||||
short archnum;
|
||||
char name[66];
|
||||
short osnum;
|
||||
short signature_type; /*!< Signature header type (RPMSIG_HEADERSIG) */
|
||||
char reserved[16]; /*!< Pad to 96 bytes -- 8 byte aligned! */
|
||||
};
|
||||
|
||||
rpmRC writeLead(FD_t fd, const struct rpmlead *lead)
|
||||
rpmlead rpmLeadNew(void)
|
||||
{
|
||||
struct rpmlead l;
|
||||
int archnum, osnum;
|
||||
rpmlead l = calloc(1, sizeof(*l));
|
||||
|
||||
rpmGetArchInfo(NULL, &archnum);
|
||||
rpmGetOsInfo(NULL, &osnum);
|
||||
|
||||
l->major = (_noDirTokens ? 4: 3);
|
||||
l->minor = 0;
|
||||
l->archnum = archnum;
|
||||
l->osnum = osnum;
|
||||
l->signature_type = RPMSIGTYPE_HEADERSIG;
|
||||
return l;
|
||||
}
|
||||
|
||||
rpmlead rpmLeadFromHeader(Header h)
|
||||
{
|
||||
char * nevr;
|
||||
assert(h != NULL);
|
||||
rpmlead l = rpmLeadNew();
|
||||
|
||||
l->type = !(headerIsEntry(h, RPMTAG_SOURCERPM));
|
||||
nevr = headerGetNEVR(h, NULL);
|
||||
strncpy(l->name, nevr, sizeof(l->name));
|
||||
free(nevr);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
rpmlead rpmLeadFree(rpmlead lead)
|
||||
{
|
||||
assert(lead != NULL);
|
||||
free(lead);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The lead needs to be 8 byte aligned */
|
||||
rpmRC rpmLeadWrite(FD_t fd, rpmlead lead)
|
||||
{
|
||||
struct rpmlead_s l;
|
||||
assert(lead != NULL);
|
||||
|
||||
memcpy(&l, lead, sizeof(l));
|
||||
|
||||
memcpy(&l.magic, lead_magic, sizeof(l.magic));
|
||||
l.type = htons(l.type);
|
||||
l.archnum = htons(l.archnum);
|
||||
l.osnum = htons(l.osnum);
|
||||
l.signature_type = htons(l.signature_type);
|
||||
l.type = htons(lead->type);
|
||||
l.archnum = htons(lead->archnum);
|
||||
l.osnum = htons(lead->osnum);
|
||||
l.signature_type = htons(lead->signature_type);
|
||||
|
||||
if (Fwrite(&l, 1, sizeof(l), fd) != sizeof(l))
|
||||
return RPMRC_FAIL;
|
||||
|
@ -37,8 +93,26 @@ rpmRC writeLead(FD_t fd, const struct rpmlead *lead)
|
|||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
rpmRC readLead(FD_t fd, struct rpmlead *lead)
|
||||
rpmRC rpmLeadCheck(rpmlead lead, const char* fn)
|
||||
{
|
||||
if (memcmp(lead->magic, lead_magic, sizeof(lead_magic))) {
|
||||
rpmlog(RPMLOG_ERR, _("%s: not an rpm package\n"), fn);
|
||||
return RPMRC_NOTFOUND;
|
||||
}
|
||||
if (lead->signature_type != RPMSIGTYPE_HEADERSIG) {
|
||||
rpmlog(RPMLOG_ERR, _("%s: illegal signature type\n"), fn);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
if (lead->major < 3 || lead->major > 4) {
|
||||
rpmlog(RPMLOG_ERR, _("%s: unsupported RPM package (version %d)\n"), fn, lead->major);
|
||||
return RPMRC_FAIL;
|
||||
}
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
||||
rpmRC rpmLeadRead(FD_t fd, rpmlead lead)
|
||||
{
|
||||
assert(lead != NULL);
|
||||
memset(lead, 0, sizeof(*lead));
|
||||
/* FIX: remove timed read */
|
||||
if (timedRead(fd, (char *)lead, sizeof(*lead)) != sizeof(*lead)) {
|
||||
|
@ -49,15 +123,10 @@ rpmRC readLead(FD_t fd, struct rpmlead *lead)
|
|||
}
|
||||
return RPMRC_NOTFOUND;
|
||||
}
|
||||
|
||||
if (memcmp(lead->magic, lead_magic, sizeof(lead_magic)))
|
||||
return RPMRC_NOTFOUND;
|
||||
lead->type = ntohs(lead->type);
|
||||
lead->archnum = ntohs(lead->archnum);
|
||||
lead->osnum = ntohs(lead->osnum);
|
||||
lead->signature_type = ntohs(lead->signature_type);
|
||||
if (lead->signature_type != RPMSIGTYPE_HEADERSIG)
|
||||
return RPMRC_NOTFOUND;
|
||||
|
||||
return RPMRC_OK;
|
||||
}
|
||||
|
|
|
@ -19,33 +19,37 @@ extern "C" {
|
|||
|
||||
#define RPMLEAD_SIZE 96 /*!< Don't rely on sizeof(struct) */
|
||||
|
||||
/** \ingroup lead
|
||||
* The lead data structure.
|
||||
* The lead needs to be 8 byte aligned.
|
||||
* @deprecated The lead (except for signature_type) is legacy.
|
||||
* @todo Don't use any information from lead.
|
||||
*/
|
||||
struct rpmlead {
|
||||
unsigned char magic[4];
|
||||
unsigned char major;
|
||||
unsigned char minor;
|
||||
short type;
|
||||
short archnum;
|
||||
char name[66];
|
||||
short osnum;
|
||||
short signature_type; /*!< Signature header type (RPMSIG_HEADERSIG) */
|
||||
char reserved[16]; /*!< Pad to 96 bytes -- 8 byte aligned! */
|
||||
} ;
|
||||
typedef struct rpmlead_s * rpmlead;
|
||||
|
||||
#include <rpmlib.h>
|
||||
|
||||
/** \ingroup lead
|
||||
* Initialize a lead structure
|
||||
* @return Pointer to empty lead structure
|
||||
*/
|
||||
rpmlead rpmLeadNew(void);
|
||||
|
||||
/** \ingroup lead
|
||||
* Initialize a lead structure from header
|
||||
* param h Header
|
||||
* @return Pointer to populated lead structure (malloced)
|
||||
*/
|
||||
rpmlead rpmLeadFromHeader(Header h);
|
||||
|
||||
/** \ingroup lead
|
||||
* Free a lead structure
|
||||
* @param lead Pointer to lead structure
|
||||
* @return NULL always
|
||||
*/
|
||||
rpmlead rpmLeadFree(rpmlead lead);
|
||||
|
||||
/** \ingroup lead
|
||||
* Write lead to file handle.
|
||||
* @param fd file handle
|
||||
* @param lead package lead
|
||||
* @return RPMRC_OK on success, RPMRC_FAIL on error
|
||||
*/
|
||||
rpmRC writeLead(FD_t fd, const struct rpmlead *lead);
|
||||
rpmRC rpmLeadWrite(FD_t fd, rpmlead lead);
|
||||
|
||||
/** \ingroup lead
|
||||
* Read lead from file handle.
|
||||
|
@ -53,7 +57,15 @@ rpmRC writeLead(FD_t fd, const struct rpmlead *lead);
|
|||
* @retval lead package lead
|
||||
* @return RPMRC_OK on success, RPMRC_FAIL/RPMRC_NOTFOUND on error
|
||||
*/
|
||||
rpmRC readLead(FD_t fd, struct rpmlead *lead);
|
||||
rpmRC rpmLeadRead(FD_t fd, rpmlead lead);
|
||||
|
||||
/** \ingroup lead
|
||||
* Check lead for compatibility.
|
||||
* @param lead Pointer to lead handle
|
||||
* @param fn File name
|
||||
* @return RPMRC_OK on success, RPMRC_FAIL/RPMRC_NOTFOUND on error
|
||||
*/
|
||||
rpmRC rpmLeadCheck(rpmlead lead, const char* fn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -111,14 +111,14 @@ static inline rpmRC printSize(FD_t fd, int siglen, int pad, int datalen)
|
|||
/* HACK: workaround for davRead wiring. */
|
||||
if (fdno == 123456789) {
|
||||
st.st_size = 0;
|
||||
st.st_size -= sizeof(struct rpmlead)+siglen+pad+datalen;
|
||||
st.st_size -= RPMLEAD_SIZE+siglen+pad+datalen;
|
||||
} else if (fstat(fdno, &st) < 0)
|
||||
return RPMRC_FAIL;
|
||||
|
||||
rpmlog(RPMLOG_DEBUG,
|
||||
_("Expected size: %12d = lead(%d)+sigs(%d)+pad(%d)+data(%d)\n"),
|
||||
(int)sizeof(struct rpmlead)+siglen+pad+datalen,
|
||||
(int)sizeof(struct rpmlead), siglen, pad, datalen);
|
||||
RPMLEAD_SIZE+siglen+pad+datalen,
|
||||
RPMLEAD_SIZE, siglen, pad, datalen);
|
||||
rpmlog(RPMLOG_DEBUG,
|
||||
_(" Actual size: %12d\n"), (int)st.st_size);
|
||||
|
||||
|
|
Loading…
Reference in New Issue