rpm-software-management / rpm

The RPM package manager
http://rpm.org
Other
508 stars 367 forks source link

RFE: read sources checksums from the SPEC file and verify them #463

Open gsauthof opened 6 years ago

gsauthof commented 6 years ago

In SPEC files there is the Source0/SourceX directive to specify the sources. Example:

Source0: http://releases.nixos.org/patchelf/patchelf-%{version}//%{name}-%{version}.tar.bz2

cf. https://github.com/gsauthof/copr-epel/blob/master/patchelf/patchelf.spec#L9

Other software then uses those keys to download the referenced files. For example, one can tell rpmbuild to auto-download all sources, Copr auto-downloads the sources (by default) or the user evaluates the SPEC file with rpmspec -P and copy'n'pastes into a curl/wget command line.

Either way, as-is, there is no way to specify cryptographic checksum inside the SPEC file for the sources specified there. For example like this:

Source0-sha256: a0f65c1ba148890e9f2f7823f4bedf7ecad5417772f64f994004f59a39014f83

With such syntax available it would be great if rpm would verify each source against the specified checksum and fail if there is a mismatch.

cf. https://bugzilla.redhat.com/show_bug.cgi?id=1536846#c7 for an example where this came up

As-is, it seems, one has to maintain checksums outside the .spec file, be cautious to manually check checksums or just ignore the problem - which is all tedious and error-prone or dangerous.

For example, because of this I had to roll my own verification logic for my Copr packages (as described in https://bugzilla.redhat.com/show_bug.cgi?id=1536846#c7).

Thus, adding this capability directly to rpm would reliably protect against man-in-the-middle (MITM) attacks.

Note that restricting auto-downloads to secure protocols like https isn't a substitute for this feature as a) not all sources are available via https and b) the infrastructure behind the https endpoint can have security issues (e.g. a temporary intrusion where files are getting replaced).

See also the discussion around https://pagure.io/copr/copr/pull-request/211#comment-43965 how Copr disabled insecure protocols for auto-downloads.

Other package formats support specifying checksums for the referenced source files (e.g. Arch/Gentoo/Homebrew source packages).

dirkmueller commented 1 year ago

I would like to see something more like pk11 format

SourceCSum: sha256://<checksum>

I think that makes it really tricky with ordering (is it applying to the next source or the previous one? and what if there are conditionals around source lines?). imho really not very intuitive as it is very context dependent.

Which would allow use different checksums algorithms. Or as second argument of the Source:

Source: <url/><filename> sha256://<checksum>

This is also breaking with older rpm releases. that's why I suggested the alternative `#' fragment url above, which would be compatible.

kloczek commented 1 year ago

I think that makes it really tricky with ordering (is it applying to the next source or the previous one? and what if there are conditionals around source lines?). imho really not very intuitive as it is very context dependent.

Currentpy you can use:

Source: file1
Source: file2
.
.

and rpm automatically numbers those Source internally. So in above scenario ..

Source: file1
Source: file2
SourceCSum: sha256://<checksum1>
SourceCSum: sha256://<checksum2>

Would be instantly equivalent of:

Source0: file1
Source1: file2
SourceCSum0: sha256://<checksum1>
SourceCSum1: sha256://<checksum2>

Using <csum_algh>://<checksum> could allow as well use for example something like github://verified which could retrieve verified sign out of released/tagged Source: (and Patch:) archives (patches generated out of commits) as well. https://docs.github.com/en/authentication/troubleshooting-commit-signature-verification/checking-your-commit-and-tag-signature-verification-status

dirkmueller commented 1 year ago

@kloczek I am fully aware of the autonumbering functionality for sources/patches, but SourceCSum is not backward compatible with older rpm versions, so you would have to do something like


%if %{with somecondition}
Source: file1
%if 0%{?rpm_is_new_enough}
SourceCSum: sha256(checksum)
%endif
%else
%if 0%{?rpm_is_new_enough}
SourceCSum: sha256(checksum)
%endif
Source: file1
%endif

now the ordering between source and Sourcecsum is different in both branches of the build conditional. I think for an average human being this can be very confusing.

I feel like this looks super ugly. in suse spec files all conditionalized statements are ordered near the end, so there could be dozens to hundreds of lines between the first block and the second block. it is very confusing. having it in one line avoids all of that.

Regarding the <csum_alg> and also using something like github:/ you can totally do both in both my suggestions as well, so it would look like

Source sha256(<themagicchecksum>)github(signinkeyweexpect): http://someurl

This is an orthogonal discussion. you can have multiple variants in both suggestions of mine (also in the fragmet suffix)

kloczek commented 1 year ago

This is an orthogonal discussion. you can have multiple variants in both suggestions of mine (also in the fragmet suffix)

Maybe you din't notice but I've proposed not one but two variants. Main point which I've added is to use pk11 like csum format. From that point of view everything from my point of view is secondary.

voxik commented 1 year ago

What about having macros such as:

Source: %checksum(ULR, sha256, <hash>)
dirkmueller commented 1 year ago

This is an orthogonal discussion. you can have multiple variants in both suggestions of mine (also in the fragmet suffix)

Maybe you din't notice but I've proposed not one but two variants. Main point which I've added is to use pk11 like csum format. From that point of view everything from my point of view is secondary.

I did notice, but I mapped that to PKCS#11 uris which are of the form pkcs11:key=value so I wasn't able to get the point. we can have such format if it doesn't include '/', that would be then:

Source: https://url#pkcs11:sha256=<checksum>/filename.tar.gz

we could also do

Source: https://url#pkcs11://sha256=<checksum>/filename.tar.gz
mlschroe commented 8 months ago

Note that we need to come up with something that works both for Source: and %sourcelist