glibc 2.2 (or thereabouts) changed glob() and fnmatch() to not return
dangling symlinks as matches, which gravely affects rpmbuild in particular.
Because of this, rpm has carried a bundled copies of glibc 2.1 functions
for close to 22 years now (commit bed2a465fe).
glibc 2.27 in 2018 thankfully finally reverted that particular braindamage,
I think we've carried the compatibility babbage long enough to excuse
ourselves with a little shorter grace period in this case.
Nukes away, add a blurb about the version requirement on glibc
based systems.
This still leaves our internal glob_pattern_p() intact as unlike glob()
itself, that's not portable.
No functional changes as such.
This change adds support for using Sequoia as an alternative to the
internal OpenPGP backend. To use this backend, it is necessary to
have the rpm-sequoia library installed.
https://gitlab.com/sequoia-pgp/rpm-sequoiaFixes#1978.
While we're purging obsolete APIs:
I fail to see how any of these would ever be of any relevance within
rpm. RPMLOG_UUCP? Nope. RPMLOG_NEWS? RPMLOG_KERN? Nope...
Unsurprisingly none of this stuff has ever been used.
This frees up the top 28 bits of the log code for things that we may
actually want to use.
This fixes a regression in 598a771d8b,
which caused RPM to parse key flags from a hashed key ID subpacket. As
a result, RPM would wrongly reject a signature that had both key ID and
key usage flags subpackets in the hashed section.
rpmio/digest.h contains definitions that are only used by the interal
OpenPGP parser, and are not required by the future Sequoia backend.
Move those definitions into rpmio/rpmpgp_internal.h.
Fixes#2006.
Commit d8bb57eeab reintroduced
rpmio/rpmpgp.h which is quite confusing when we have a public header by
the same name elsewhere, and doubly more confusing to those of use who
are used to having the public header by the same name in this very
location prior to commit 650ba79f22.
No functional changes.
Split the internal OpenPGP implementation into the bits that are
needed by a new OpenPGP backend like Sequoia, and the bits that are
not needed by another OpenPGP backend.
Move most of the functionality in rpmio/rpmpgp.c into
rpmio/rpmpgp_internal.c.
Leave pgpValStr, and pgpIdentItem, which are used for printing and
needn't be reimplemented by other backends, and pgpReadPkts, which is
just a thin wrapper around pgpParsePkts, and which uses an internal
rpm function that a new backend shouldn't have to worry about
emulating or even calling.
Move the symbol tables, which are used by pgpValStr, pgpIdentItem, and
the internal OpenPGP implementation to rpmio/rpmpgp.h. These are
common to all implementations.
Fixes#2000.
Once upon a time there may have been a point to having the extension in a
separate convenience library, but nowdays with Lua being mandatory there's
not a whole lot of point in complicating the build with all this fubar.
As a nice little bonus, we can now hide luaopen_posix() symbol.
The stats aren't particularly interesting except for development
and debugging purposes. Rather than change all the debug fprintf()'s
in rpmio to rpmlog(), just change the stats to only get printed
when --rpmiodebug is active like the rest of the io debug code.
Fixes: #1987
This means that finally there's just one place that when adding support
for new compress formats, there's in theory there's just one place to
update. Reality is a little more complicated, but hey...
Adjust tests a bit, and rather test functionality than command output
because those reflect command paths which we can't easily adjust now.
- Add accessor functions pgpDigParamsSignID, pgpDigParamsUserID,
pgpDigParamsVersion, and pgpDigParamsTime.
- Move the definition of `pgpDigParams_s` from `rpmio/digest.h` to
`rpmio/rpmpgp.c`.
- Change code to use the accessor functions.
- Fixes#1979.
Modify pgpPrtSig() to ignore the MPIs of a signature if its `tag`
parameter is 0. The only caller that sets `tag` to 0 is
pgpPrtParamSubkeys() (via parseSubkeySig()), which does not actually
check any cryptographic signatures. The subkey binding signature has
been checked earlier in pgpPrtParams().
This ensures that a signature is only accepted if the subkey that made
it is actually allowed to sign. Test 265 verifies that RPM ignores
subkeys that cannot sign.
A subkey is considered to be capable of signing if, and only if, its
subkey binding signature has a hashed key flags subpacket that contains
the flag 0x02. RFC4880 requires that the subkey binding signature be
v4, which this requirement enforces implicitly. RFC4880 also requires
that primary key binding signatures be present and checked. This is not
yet implemented, but may be implemented later.
Fixes#1911.
RPM needs to know if a subkey can be used for signing. Signatures made
by a subkey that cannot be used for signing are invalid. Add a
key_flags member to pgpDigParams_s to store this information, and a
PGPDIG_SIG_HAS_KEY_FLAGS flag to indicate that it is valid. The key
usage flags are reset for every signature. Key usage flags in the
unhashed section are ignored. If there is more than one key usage flags
subpacket in the hashed section, the signature is rejected.
This is needed for key usage flags parsing, as key usage flags outside
of the hashed region must be ignored. For now, just use it to
unconditionally ignore unhashed creation time subpackets.
According to `man 3ssl` the only successful return value for
EVP_PKEY_verify_init() is 1, and EVP_PKEY_CTX_set_rsa_padding() and
EVP_PKEY_CTX_set_signature_md() can both return 0 or a negative number
on failure or any positive number on success. BN_bn2binpad() returns -1
on error, but 0 (an empty key or signature) is also not valid.
Therefore use != 1 to check the return value of EVP_PKEY_verify_init(),
<= 0 to check the return values of the other three functions mentioned
above. Also delete a bunch of cruft.
Such data is probably an attempt to exploit RPM, not do anything useful.
This avoids a whole class of silly integer overflow problems.
Signatures in packages are already limited to less than 64MiB by the
maximum size of the signature header, and this is already a sufficient
limitation.
According to RFC 4880 §5.2.3.4 the signature creation time MUST be a
hashed subpacket. Enforce this requirement in RPM. Also set the saved
flags to PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID |
PGPDIG_SAVED_CREATION_TIME for v3 signatures, and do not overwrite an
already saved key ID with one taken from a v3 signature.
The crypto backend used during importing has little relevance to
anything, plus we discarded the NSS backend two years ago so it doesn't
have an even theoretical chance of being right...
Introduced back in 2007 in 5831404601 the
point was to fake up a sane public header structure with minimal
internal disruption, TEMPORARILY. I think 15 years is temporary enough.
The machinery has worked rather well for what it is, but having the
headers appear in multiple locations is weird and confusing to people,
plus this "physical" separation makes it far more clearer what is
a public header and what isn't.
The rpm signal queue (rpmsq) was necessary to support clean shutdown
of Berkeley Database on signals, but our current backends do not
need such handholding. A library silently hogging your signals on
function call is antisocial behavior, stop doing that since we no
longer have to.
Since the rpmsq is no longer active in transactions, use sigaction()
instead of rpmsqSetAction() to manipulate SIGPIPE. While at it,
eliminate the use of deprecated signal() which in particular should
not be mixed with sigaction() use.
This is quite a dramatic behavior change to a long-standing behavior
so while everybody hated the signal hogging, this may still cause some
fallout in strange places.
This also makes a whole lot of rpmsq code redundant and unused, leaving
it in place for the time being as a backup if we need to revert
short term, to be flushed in the next soname bump.
At this point this is quite literally merely a symbolic change,
as values from PGP hash algo are assumed equal to RPM hash algos,
but it's a necessary first step to supporting hashes not included
in RFC-4880.
Fixes: #1899
These APIs never belonged to rpmpgp.h anyway, it was only used for
being the least-worst fit within rpm. As if it was so hard to just
add a new header...
rreallocn() is like realloc() but with multiplication protection.
Inspired by glibc's reallocarray() but I dislike that name.
While at it, add xmallocn() as a shortcut to rreallocn(NULL, ...) case.
Based on initial patch by Demi Marie Obenour.
If a public key was too short for the curve ID, the code would
previously perform out-of-bounds pointer arithmetic, which is undefined
behavior in C. Check that the packet is long enough to contain the
curve ID before bumping `se` past the curve ID.
Furthermore, if a public key is too short to even contain the fixed-size
header, an out-of-bounds pointer would be created, which is also
undefined behavior. Fix this by returning early if the buffer is too
short.
Finally, return early if the public key algorithm or curve ID is
invalid, rather than relying in processMpis() to fail. While
processMpis() will error out, bailing out explicitly is much clearer.
Make sure selfsig is freed in case we break out of the loop in this
block.
Note that the tests added with the binding validation commit bd36c5d do
not cover this code path so valgrind won't show this.
We don't want readline dependency in librpmio so need to do this the
hard way: add an optional callback through which rpmlua can supply
it's own readline-aware callback function.
This screams for a closure, use one. This is not supposed to change
any functionality except, except only make the rpm.next_file() function
available in the context of scriptlets which is the only context it is
meaningful.
Confusingly, the "RPM build errors" section also includes messages
logged as warnings. That gives the false impression that they somehow
contributed to the actual build failure and therefore were turned into
errors.
This appears to be a historical artifact; when a message passes through
the logging system and is of the priority RPMLOG_WARNING or higher, we
save it in a global buffer (ctx->recs), which is then simply dumped with
rpmlogPrint() in the error summary. This was probably good enough when
the summary was introduced (commit f2efc72, year 2000), as there were
almost no warnings generated by RPM at that time, however as they became
more abundant, the summary code was never revisited.
There are 3 ways to fix this discrepancy:
1) Change the summary's title to "RPM build problems"
2) Remove the summary altogether
3) Don't show warnings in it
Options #1 and #2 would be too disruptive. The error summary needs to
stay as is, for the following reasons:
- While it usually just repeats the last error, not all errors
terminate a build right away, so those can get drown in the output
that follows after. Examples: "File not found" in rpmInstall(), or
macro expansion errors (note: we may have these terminate a build in
the future).
- It makes it immediately obvious that something went wrong when
examining build logs, and the title "RPM build errors" undoubtedly
has become the de-facto text string to search for.
That leaves us with option #3. To further lessen the disruption, do
keep a summary of warnings, but put them under their own heading, and
only show it on build failures. That way, we restrict all the extra
verbosity to error time (as it is now) and don't pollute the output of
otherwise good builds. There may be packages with long-standing
warnings that are not feasible to fix for any reason, and having an
indented block of text resembling "RPM build errors" at the end of every
build would do no good.
Effectively, this commit is just cosmetic - it splits the error summary
into two, without any functional or API changes (apart from two function
additions).
Fixes: #793
Avoids having to manually "print()" everything, at the cost of requiring
a "return" which is not really less to type but more natural for
programming, and other benefits likely to follow.
Guess this is rebase considered harmful: this should've been in
commit de9cc32b98 but in that fork,
rpmluaCallStringFunction() didn't yet exist so it couldn't be
adjusted there, but merging the PR broke the build.
We pop it to print its contents, but we forgot to push an empty
print buffer afterwards. This makes a difference as a newline
is not automatically added in print statements if a buffer is used.