Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expired-pgp-keys: New plugin for detecting expired PGP keys #1592

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

jan-kolarik
Copy link
Member

Based on the implementation from rpm-software-management/dnf-plugins-core#533.

Workaround for: #1192.

@jrohel
Copy link
Contributor

jrohel commented Jul 25, 2024

I looked into the source code. It's a rewrite of the new "expired-gpg-keys" plugin from DNF4 to libdnf5.

And here's the problem. The original plugin is in Python. It is not part of the libdnf library -> this makes it ignored by users using libdnf directly - microdnf, PackageKit, ... And it behaves more like an application plugin - it interacts with the user via the console.

This PR implements the libdnf5 plugin. So it is a library plugin. The advantage is that it will be active for all users of the libdnf5 library (dnf5 application, dnf5daemon-server, ...). However, the library must not interfere with the console. For example, dnf5daemon-server does not have a console to communicate with the user - it is a background daemon.

The dnf5 application only supports "command" plugins. And generally making this plugin as an application plugin is not a good way to go. The same problem would occur as with DNF4. It would not work for other applications (users of the libdnf5 library).

How to get out of this?
We need an interface defined in the libdnf5 library for this case.
Queries whether to do key import are done via callbacks. Similarly, queries to remove them (with possible information why) should be handled via callbacks.

@jan-kolarik
Copy link
Member Author

I looked into the source code. It's a rewrite of the new "expired-gpg-keys" plugin from DNF4 to libdnf5.

And here's the problem. The original plugin is in Python. It is not part of the libdnf library -> this makes it ignored by users using libdnf directly - microdnf, PackageKit, ... And it behaves more like an application plugin - it interacts with the user via the console.

This PR implements the libdnf5 plugin. So it is a library plugin. The advantage is that it will be active for all users of the libdnf5 library (dnf5 application, dnf5daemon-server, ...). However, the library must not interfere with the console. For example, dnf5daemon-server does not have a console to communicate with the user - it is a background daemon.

The dnf5 application only supports "command" plugins. And generally making this plugin as an application plugin is not a good way to go. The same problem would occur as with DNF4. It would not work for other applications (users of the libdnf5 library).

How to get out of this? We need an interface defined in the libdnf5 library for this case. Queries whether to do key import are done via callbacks. Similarly, queries to remove them (with possible information why) should be handled via callbacks.

That's a good point Jarek, I wasn't thinking about non-CLI users here. I will rework the plugin as you've suggested, thanks for that!

@jan-kolarik jan-kolarik added the blocked Further work on issue or PR is blocked by something else label Jul 25, 2024
@jan-kolarik jan-kolarik force-pushed the jkolarik/pgp-expired-keys branch 2 times, most recently from daa8582 to e88960d Compare July 25, 2024 11:34
@pmatilai
Copy link
Member

Looking at the expiriation date will miss what I think is the more common issue just now: all the obsolete SHA1 based signatures that will fail in various other ways. Sequoia generally defers this checking to verify rather than import time, but you might want to additionally call pgpPubKeyLint() on the key material to catch at least some of those issues too.

@jan-kolarik jan-kolarik force-pushed the jkolarik/pgp-expired-keys branch from e88960d to 770c1b2 Compare January 28, 2025 09:04
@jan-kolarik jan-kolarik removed the blocked Further work on issue or PR is blocked by something else label Jan 28, 2025
@jan-kolarik jan-kolarik force-pushed the jkolarik/pgp-expired-keys branch 2 times, most recently from a4a55fd to 76a04e7 Compare January 28, 2025 09:14
@jan-kolarik
Copy link
Member Author

I performed some manual testing, and everything appears to be working as expected. One potential minor issue is that when GPG keys are available remotely (e.g., Copr keys), users always see output about downloading the keys, like this:

[kolage@ecstatic_dewdney dnf5]# dnf upgrade libdnf
Updating and loading repositories:
Repositories loaded.
 https://download.copr.fedorainfracloud. 100% |  13.9 KiB/s |   1.0 KiB |  00m00s
 https://download.copr.fedorainfracloud. 100% |  12.2 KiB/s |   1.0 KiB |  00m00s
...

This happens because the FileDownloader in the RpmSignature class uses the standard download callbacks from the Base class, and there’s currently no proper way to customize these callbacks for one-time use.

@jan-kolarik
Copy link
Member Author

jan-kolarik commented Jan 28, 2025

This PR also adds a new libdnf5 workflow hook at the Resolved stage, enabling custom logic to be added immediately after the goal is resolved. Related updates were also made to the Actions plugin to support this new behavior.

@jan-kolarik
Copy link
Member Author

How to test:

If the plugin is enabled and any COPR repository is enabled on your system, you can test it by faketiming the system date and disabling sslverify, then running a transaction. This should trigger a prompt to remove the PGP key:

faketime '+5years' dnf5 install nudoku --setopt=sslverify=False

CI tests will be delivered in a follow-up PR.

@jrohel jrohel self-assigned this Jan 29, 2025
@jrohel
Copy link
Contributor

jrohel commented Jan 29, 2025

PR adds new virtual methods to the public class API. This breaks the ABI. Yes, I know, we need to add some new hooks for plugins from time to time. It wasn't clear in the beginning where all the hooks should be placed.

At least we should increase the PLUGIN_API_VERSION in "include/libdnf5/version.hpp". It might solve the problems with the SWIG interface. For example, Python plugins can query PLUGIN_API_VERSION to know which methods are available.

But the ABI for C++ plugins will remain broken. So I'm thinking about methods to solve this problem. And right now I got one idea. How about instead of adding a new virtual method to the base class, create a new class that inherits from the base class and add the virtual method to the new class.
Example:
Instead of adding the resolved method to IPlugin, we create a new class IPlugin3 (current PLUGIN_API_VERSION is "2.0", we will probably increase it to "3.0"). It will inherit from IPlugin. New plugins can use IPlugin3 with the new methods, and the original IPlugin will still be usable with the old API/ABI.
But this is just an idea for which I can try to create a prototype to see how it will work.

@jan-kolarik jan-kolarik force-pushed the jkolarik/pgp-expired-keys branch from 76a04e7 to fc0b546 Compare January 29, 2025 13:37
@jan-kolarik
Copy link
Member Author

jan-kolarik commented Jan 29, 2025

The only failing CI test seems to be about updating the Actions plugin CI test text expectation.

Copy link
Contributor

@jrohel jrohel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Nice work. I wrote comments what still needs to be resolved.

include/libdnf5/version.hpp Outdated Show resolved Hide resolved
dnf5/context.cpp Outdated Show resolved Hide resolved
New hook to be called right after resolving the goal.
As we've agreed on introducing breaking changes only with major versions of API, dropping the minor version difference check.
Instead of always hardcoding the latest API version in the plugin, we should define the minimum API version the plugin is compatible with.
@jan-kolarik jan-kolarik force-pushed the jkolarik/pgp-expired-keys branch from fc0b546 to ca74f15 Compare January 31, 2025 13:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Review
Development

Successfully merging this pull request may close these issues.

3 participants