Repository navigation
Update Manager uses the wrong destination for keyrings #1036
Description
Activity
Hi, I spent some time trying to understand this issue, as I too was a bit confused by exactly the scenario reported in this issue and some other issues related to the new
.sources(Deb822) source file format. I think I have a theory for what's happening in the scenario described in this particular issue, with a fix. Just wanted to share my findings here first before proposing the fix.Background
Although this issue is reported in mintupdate (Update Manager) repository, the Software Sources program is in https://github.com/linuxmint/mintsources . The Update Manager has a menu option Edit > Software Sources, which opens the Software Sources (mintsources) application.
Before spending so much time with mintsources and reading the source code, it wasn't obvious to me what theMaintenance > Add missing keysoption was for. I believe it is meant for the scenarios where a new source repository is added (either in/etc/apt/sources.list.d/or through the mintsourcesAdditional Repositories > Add) and the corresponding signature verification keys are required to be able to use the repository. Usually, the third party repository docs describe the procedures for adding both the source list and the key. But theMaintenance > Add missing keysoptions just makes it easier. But there are some caveats when doing so which mintsources handles to some extent, and misses by no fault of it's own, but mostly because of the new Deb822 format, details below.Before describing my theory, I'd like to share my findings about the various relevant directories, as knowing them helps understand the observations:
/etc/apt/trusted.gpg.d/- The keys placed in this directory are automatically trusted by apt. If a source file doesn't specify the path to the key (e.g.:signed-by=/usr/share/keyrings/steam.gpgis not defined), the keys intrusted.gpg.d/directory will be used by apt to verify the source. This happens when the source is added from the mintsources GUIAdditional Repositories > Add, if only the address of the repository, along with suite and components are provided (e.g.:deb https://repo.steampowered.com/steam/ stable steam). Because is it automatically trusted, it is discouraged to add third party repository verification keys in this. mintsources puts the key here when the source doesn't specify the path to the key./usr/share/keyrings/- The keys placed in this directory are not automatically trusted by apt. This directory is recommended to be used by the package managers to install the keys and update them from time to time. Manual edits to the files in this directory can get overwritten by the package manager or OS updates. Most of the third party repositories document their keys to be added here. Their source also refer to signed-by file in this directory. Since this directory is not automatically trusted, only if the sources refer to the key file in this directory, they are used for verification. For example, in case of steam,deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steamforces apt to only attempt verification using the file/usr/share/keyrings/steam.gpg. If the file is missing, the verification would fail. But if the file is missing, mintsources'Maintenance > Add missing keyswill download and put the file in/usr/share/keyrings/steam.gpg, as it is specified in the source file. Only when it's not specified, mintsources puts it in/etc/apt/trusted.gpg.d/directory./etc/apt/keyrings/- The keys placed in this directory are also not automatically trusted by apt. This directory is recommended to be used for any user managed keys that are expected to persist and not get overwritten by any updates. Similar to/usr/share/keyrings/, any source can refer to key files in this directory for verification. But unlike/usr/share/keyrings/keys, the keys are not expected to be managed by the package manager or automatically updated. The system user/admin usually is responsible for updating the key. mintsources uses this directory temporarily when downloading the keys and later move them to the key path, if specified in the source, or under/etc/apt/trusted.gpg.d/.
/usr/share/keyrings/and/etc/apt/keyrings/are generally recommended for adding keys. Usually, it's/usr/share/keyrings/as the keys are managed by the package managers with the packages from the added repository.Observed bug
Taking the example of steam, if https://repo.steampowered.com/steam/ is followed perfectly, the key is expected to exist in
/usr/share/keyrings/steam.gpg, the source file refers to this file and verification should succeed. But if the source file doesn't containsigned-by=/usr/share/keyrings/steam.gpg, even if the key exists in/usr/share/keyrings/steam.gpg, it can't be use it to verify because/usr/share/keyrings/directory is meant for explicit reference verification.
On the other hand, if no key was created by the user and only the source was created but with a reference to the key under/usr/share/keyrings/, ideally, mintsources would place the downloaded key under/usr/share/keyrings/and verification would succeed. But due to a bug, mintsources fails to find where it should put the key file, even when it is specified in the source file, and it defaults to adding the key in/etc/apt/trusted.gpg.d/. But since the source already has a reference to a key, it will not be verified with thetrusted.gpg.d/directory key.To be clear, mintsources adding the key in
/etc/apt/trusted.gpg.d/isn't wrong, but in the specific scenario where the source has asigned-byfield referring to/usr/share/keyrings, key in/etc/apt/trusted.gpg.d/won't be used.Debugging
Reading the code and running the mintsources program, I wasn't able to reproduce this bug initially. I cloned the repository and ran the python script as root. Comparing the latest code in the git repository and Linux Mint 22.3, the
mintSources.pycontent is exactly the same. But when I run the same program from the GUI, not in terminal with python, I was able to reproduce the bug. mintsources is installed as a symlink/usr/bin/mintsources -> software-sources, where the main program,mintSources.pyis run in a subprocess.
Adding some debug statements, and trying various things to understand why the downloaded key was being written to trusted directory instead of the one specified insigned-bydirectory, I noticed that mintsources usesinxi -rfor listing the sources and extracts the key file path from there. The commandinxi -r | grep {uri}(refer https://github.com/linuxmint/mintsources/blob/f57af383dc51682833a1774d7a75813f192a7fe1/usr/lib/linuxmint/mintSources/mintSources.py#L1217) seemed to be resulting in an empty result. Which leads to mintsource not knowing where to put the key and it defaults to writing it in the trusted directory.
When the program is run in a terminal, I can see that the result of inxi-grep appears to be as expected and the key is written to/usr/share/keyring/or the specified key path. After trying a few more things, I noticed a difference in inxi output when run in terminal and as a subprocess not from the terminal.When mintsources is run from GUI,
inxi -rresults in:Repos: 12No active apt repos in /etc/apt/sources.list 12Active apt repos in /etc/apt/sources.list.d/official-package-repositories.list 121 deb https: //packages.linuxmint.com zena main upstream import backport 122 deb https: //archive.ubuntu.com/ubuntu noble main restricted universe multiverse 123 deb https: //archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse 124 deb https: //archive.ubuntu.com/ubuntu noble-backports main restricted universe multiverse 125 deb http: //security.ubuntu.com/ubuntu/ noble-security main restricted universe multiverse 12Active apt repos in /etc/apt/sources.list.d/steam-stable.list 121 deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https: //repo.steampowered.com/steam/ stable steam
12in each of the lines above is a color code, which can be ignored.
When the same is run in a terminal, it results in:Repos: No active apt repos in: /etc/apt/sources.list Active apt repos in: /etc/apt/sources.list.d/official-package-repositories.list 1: deb https://packages.linuxmint.com zena main upstream import backport 2: deb https://archive.ubuntu.com/ubuntu noble main restricted universe multiverse 3: deb https://archive.ubuntu.com/ubuntu noble-updates main restricted universe multiverse 4: deb https://archive.ubuntu.com/ubuntu noble-backports main restricted universe multiverse 5: deb http://security.ubuntu.com/ubuntu/ noble-security main restricted universe multiverse Active apt repos in: /etc/apt/sources.list.d/steam-stable.list 1: deb [arch=amd64,i386 signed-by=/usr/share/keyrings/steam.gpg] https://repo.steampowered.com/steam/ stable steam
with proper color in the terminal.
The colors weren't the core issue. I tried adding-c 0to inxi but the problem persisted. The problem was the repository address. For some reason, inxi would insert a space afterhttp:. I suspect that maybe it interprets it as a key-value pair and tries to prettify the result, but not always. After going through the inxi man page, I tried the--ttyoption, https://man.archlinux.org/man/inxi.1#tty. It seems inxi does things differently by default, expecting that it's running in an IRC client.inxi --tty -rfixes the problem, grep successfully matches with the repository URL. mintsources writes the key in the path specified bysigned-byin the source file.Here's a diff of the change:
diff --git a/usr/lib/linuxmint/mintSources/mintSources.py b/usr/lib/linuxmint/mintSources/mintSources.py index ff9060f..da23b55 100755 --- a/usr/lib/linuxmint/mintSources/mintSources.py +++ b/usr/lib/linuxmint/mintSources/mintSources.py @@ -1214,7 +1214,7 @@ class Application(object): uri = repository.uri if uri.endswith("/"): uri = uri[:-1] - output = subprocess.getoutput(f"inxi -r | grep {uri}") + output = subprocess.getoutput(f"inxi --tty -r | grep {uri}") key_path = None if "signed-by" in output: key_path = output.split("signed-by=")[1].split("]")[0]
You can make a copy of the original file and add this little change to try it yourself. Even if there's an existing key in
/etc/apt/trusted.gpg.d/, another key will be added in/usr/share/keyringsas per the source list'ssigned-byvalue.The Authentication Keys tab in mintsources depends on
apt-key listfor listing the keys, which seems to only list the keys under trusted.gpg and trusted.gpg.d/. Maybe this could be an improvement to add other existing keys.Another problem I noticed is that all the above applies to the old
.listssources files. The new.sources(Deb822 format) files are not supported for extracting the signed-by value becauseinxidoesn't seem to list that value ininxi -routput. Repositories like the Microsoft VSCode, Brave Browser, etc use the Deb822 format. I have no perl experience to look much into inxi's code, I tried a little. But maybe we can do all that in python itself usingrepolibwhich is already used for reading the sources.Should be fixed by linuxmint/mintsources@e772ba3
Describe the bug
The "Add missing keys" button adds keys to
/etc/apt/trusted.gpg.d/. This is wrong, because the keyrings have been moved to/usr/share/keyrings. Theaptcommand does not look in/etc/apt/trusted.gpg.d/, so this button doesn't do anything useful.Furthermore, this may impact other tools within Update Manager that interact with keyrings.
Screenshots
To Reproduce
ls -l /etc/apt/trusted.gpg.d/Expected behavior
Keys in
/usr/share/keyringsDistribution:
Linux Mint
Software version:
7.1.4
Logs:
Nothing relevant.