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

lib/repo: Search a list of paths in gpgkeypath for gpg keys #1773

Closed
wants to merge 20 commits into from

Conversation

rfairley
Copy link
Member

@rfairley rfairley commented Nov 6, 2018

This allows specifying gpgpath as a list of
paths that can point to a file or a directory. If a directory path
is given, paths to all regular files in the directory are added
to the remote as gpg ascii keys. If the path is not a directory,
the file is directly added (whether regular file, empty - errors
will be reported later when verifying gpg keys e.g. when pulling).

Adding the gpgkeypath property looks like:

ostree --repo=repo remote add --set=gpgpath="/path/key1.asc,/path/keys.d" R1 https://example.com/some/remote/ostree/repo

Closes #773

Still left to do

  • Update documentation of gpgkeypath

Other considerations

  • Checks before adding the keys in _ostree_gpg_verifier_add_key_ascii_file and if/how checks will be reported. Right now, entries in the list that are not directories are added automatically (whether regular, or don't exist, ...) (same as before). If the entry is a directory, all regular files in that directory are added, without traversing directories
  • Regexp matching of list entries

@rfairley rfairley changed the title [WIP] lib/repo: Search multiple filepaths in gpgkeypath for gpg keys [WIP] lib/repo: Search a list of paths in gpgkeypath for gpg keys Nov 6, 2018
@dustymabe
Copy link
Contributor

ostree --repo=repo remote add --set=gpgpath="/path/key1.asc;/path/keys.d" R1 https://example.com/some/remote/ostree/repo

is that a semi-colon ; above ? is there a reason to use a semi-colon over a comma?

@rfairley
Copy link
Member Author

rfairley commented Nov 7, 2018

@dustymabe Initially I was thinking the keyfile where gpgpath ends up would need semi-colons so that glibc could parse it (https://developer.gnome.org/glib/stable/glib-Key-value-file-parser.html#glib-Key-value-file-parser.description). But the separator for glibc to parse keys with multiple values can be changed to any character, so there is no real need to use semi-colons. Commas are also mentioned in that link. I'd be happy to go with commas, they do look nicer than semi-colons as well.

rfairley added 2 commits November 7, 2018 10:45
This allows specifying gpgpath as list of
paths that can point to a file or a directory. If a directory path
is given, paths to all regular files in the directory are added
to the remote as gpg ascii keys. If the path is not a directory,
the file is directly added (whether regular file, empty - errors
will be reported later when verifying gpg keys e.g. when pulling).

Adding the gpgkeypath property looks like:

ostree --repo=repo remote add --set=gpgpath="/path/key1.asc,/path/keys.d" R1 https://example.com/some/remote/ostree/repo

Closes ostreedev#773
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
src/libotutil/ot-keyfile-utils.c Outdated Show resolved Hide resolved
src/libotutil/ot-keyfile-utils.c Outdated Show resolved Hide resolved
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
@rfairley
Copy link
Member Author

Thanks @cgwalters for the review and helpful comments! I pushed a couple of fixup commits.

The first e75ac9d addresses the changes doing things the first way I had - not using the libglnx API.

The second, I used glnx_dirfd_iterator_init_at in ostree-gpg-verifier.c. With that came a bit of restructuring, but it seems to work well overall. One part where I found I still needed to use GKeyFile is 9c7ad70#diff-23d4c8887c7dda91613c9451bf3fe7c0R5112 to check if this is a directory. Am just having a look now into ot_dfd_iter_init_allow_noent() which you mentioned - sorry looked over this comment before. I think using this would avoid the need to use GKeyFile.

@rfairley
Copy link
Member Author

rfairley commented Nov 14, 2018

Pushed another fixup which cleans up the loop in ostree-repo.c from the previous commit and uses ot_dfd_iter_init_allow_noent().

This changes behaviour when coming across a path that does not exist. Previously, the path to a file that did not exist would give a message No file or directory. This is because the filepath was added to the verifier if it did not exist.

Now, if the path does not exist, the path does not get added to the verifier. No error message indicates this, so this is silent. A test showing this change in behaviour is this https://github.com/ostreedev/ostree/pull/1773/files#diff-9a33529a3274e91605ccacb39789b065R220.

A benefit of having NOENT be silent is that if multiple gpgkeypaths are specified, and at least one of them exists and contains a valid key, the pull operation will not fail due to one of the other paths not existing.

The downside is there is no specific error message given letting the user know a path was imported that doesn't exist.

Either having NOENT be silent or enforcing that all the paths exist can be done. Will think about this. Any ideas which way to go, or if there is another way to report NOENT would be appreciated!

@rfairley
Copy link
Member Author

^ Latest commits address the decl-and-inits, and I changed the nonexistent path handling to give No such file or directory if any of the paths given in the list don't exist. This behaviour is what _ostree_gpg_verifier_add_keyring_dir() follows, I think it makes sense to do the same for _ostree_gpg_verifier_add_keyfile_path().

Sorry for all the flip-flopping in the recent changes, will keep the changes settled now.

@rfairley
Copy link
Member Author

rfairley commented Nov 19, 2018

Updated the manpage.

There are 2 last questions I have:

  • I noticed the documentation in ostree.repo-config.xml mentions the config file follows the latest Freedesktop standards for Desktop Entry Files. While GNOME mentions commas being acceptable instead of semicolons to separate values, Freedesktop mentions only semicolons. Are we strictly following Freedesktop?
  • Currently any file in a given directory path is imported. Adding a pattern matcher so that only *.asc files are imported would be simple to add in, should this be done? I thought about pattern matching from the paths given in the gpgkeypath list, to enable globbing, but it does complicate the logic. Maybe add as an enhancement if requested.

@jlebon
Copy link
Member

jlebon commented Nov 20, 2018

I noticed the documentation in ostree.repo-config.xml mentions the config file follows the latest Freedesktop standards for Desktop Entry Files. While GNOME mentions commas being acceptable instead of semicolons to separate values, Freedesktop mentions only semicolons. Are we strictly following Freedesktop?

Hmm, it would be nice to support both I think, since traditionally keyfiles use semicolons for lists. So that's an easy gotcha to fall into. What do you think of something like:

  • parse as a string first, if there are neither commas or semicolons, just return that
  • otherwise, use g_key_file_set_list_separator depending on above and parse as a list

?

Currently any file in a given directory path is imported. Adding a pattern matcher so that only *.asc files are imported would be simple to add in, should this be done?

I think the original reason for this ask was to support just passing /etc/pki/rpm-gpg, which only holds keys. So I think doing this later when a use case shows up would be fine.

src/libostree/ostree-repo.c Outdated Show resolved Hide resolved
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
@rfairley
Copy link
Member Author

Thanks @jlebon !

What do you think of something like:

parse as a string first, if there are neither commas or semicolons, just return that
otherwise, use g_key_file_set_list_separator depending on above and parse as a list

I like that idea, so g_key_file_set_list_separator can set the separator to , or ; depending on which one is present in the key being read (gpgkeypath here, but this logic can apply to other keys). If both ; and , are present in a string parsed for a single key, then we throw an error? Or perhaps default to separating by the ; in that case, but error might be more informative.

I think doing this later when a use case shows up would be fine.

+1

@jlebon
Copy link
Member

jlebon commented Nov 20, 2018

If both ; and , are present in a string parsed for a single key, then we throw an error? Or perhaps default to separating by the ; in that case, but error might be more informative.

Sure, making it an error SGTM!

@rfairley
Copy link
Member Author

⬆️ fixup to add the check for both ; and ,, returning an error if both are present.

The function ot_keyfile_get_string_as_list deals with this check, and returns a null-terminated array of strings (whether the single-string or list-of-strings case).

src/libostree/ostree-repo.c Show resolved Hide resolved
src/libostree/ostree-gpg-verifier.c Outdated Show resolved Hide resolved
if (dent->d_type != DT_REG)
continue;

g_autofree char *iter_path = g_strjoin (sep, path, dent->d_name, NULL);
Copy link
Member

Choose a reason for hiding this comment

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

You can use g_build_filename for this and drop the need for sep.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, though strictly speaking...since we're doing fd-relative here, a cleaner approach would be to open the file here, stashing it an another array, and then later using gpgme_data_new_from_fd() just like we do for paths.

Or even more strongly, open every file here and then change the verifier to just iterate over the fds.

(This is an optional followup)

Copy link
Member Author

@rfairley rfairley Nov 21, 2018

Choose a reason for hiding this comment

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

Ahh, the utility functions are handy. Added this in.

Storing the fds while reading the paths and later iterating over those once added to the verifier sounds clean, saves doing the intermediate work of storing the path. I added a TODO for this.

@jlebon
Copy link
Member

jlebon commented Nov 21, 2018

This looks good to me. Nice work! 👍
Will let @cgwalters have a final lookover.

@cgwalters
Copy link
Member

Very nice, thanks!

@rh-atomic-bot r+ a802199

@rh-atomic-bot
Copy link

📋 Looks like this PR is still in progress, ignoring approval

@cgwalters cgwalters changed the title [WIP] lib/repo: Search a list of paths in gpgkeypath for gpg keys lib/repo: Search a list of paths in gpgkeypath for gpg keys Nov 21, 2018
@cgwalters
Copy link
Member

@rh-atomic-bot r+ a802199

@rh-atomic-bot
Copy link

⚡ Test exempted: merge already tested.

@rfairley
Copy link
Member Author

Thanks for the review @cgwalters and @jlebon !

@dustymabe
Copy link
Contributor

woot! Nice work @rfairley

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants