Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@andy-bower
Copy link
Contributor

@andy-bower andy-bower commented Oct 21, 2024

This attempt to close #20 was surprisingly straightforward. Some caveats come to mind:

  1. I am new to autoconf so the configure.ac changes are a bit cargo-culty - may need some attention!
  2. The ordering for trying credentials needs review: store -> gpg -> netrc -> prompt.
  3. Do you want the password prompt at all when the store is not available?
  4. Should it be possible to disable the store at runtime?
  5. The options.pwprompt setting gets overwritten with whether the prompt was actually used so that main knows whether to request the password be saved upon a successful query (we don't save the decrypted or netrc passsword!). That's a change of semantics versus the other 'options'.

This is what the store looks like:

$ lssecret
Item:	Mutt CardDAV Search user credentials
Key:	url
Value:	https://my.cloud.server/remote.php/dav/addressbooks/users/fred/contacts
Key:	user
Value:	fred
Key:	xdg:schema
Value:	com.github.t-brown.mcds.password

How to make a first query

$ src/mcds -u http://foobar/ bloggs
mcds: password for fred at http://foobar/:

The password then gets stored if successful and the prompt not presented again unless run with -p.

Tested with libsecret-1-dev not present and with ./configure --disable-libsecret.

$ src/mcds -V
mcds (GNU mcds) 1.7
Copyright (C) 2019 Timothy Brown.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Compiled on Oct 21 2024 at 22:17:16:
  with GPGME support and
  with libsecret support.

@andy-bower andy-bower marked this pull request as draft October 21, 2024 23:35
@andy-bower
Copy link
Contributor Author

I've rebased, squashed and force-pushed this change and will switch from draft for proper review.

@andy-bower andy-bower marked this pull request as ready for review October 23, 2024 15:51
Copy link
Owner

@t-brown t-brown left a comment

Choose a reason for hiding this comment

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

Thanks for the contribution!

#if HAVE_LIBSECRET
#include <libsecret/secret.h>

#define MCDS_NAMESPACE "com.github.t-brown.mcds"
Copy link
Owner

Choose a reason for hiding this comment

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

I'm not crash hot on #defines and prefer static const char. However, this does mean you can concat them easily.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough! I don't think there's a particular need not just to put the full identifier in one string constant - do you want to do that change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, you may have a better schema id in mind - I just constructed one from this repo by default!

Copy link
Contributor Author

@andy-bower andy-bower left a comment

Choose a reason for hiding this comment

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

Thanks for enhancing my PR @t-brown! I think it was a good idea to split out the password prompting and libsecret integration.

I have some questions about the decision tree for using the various methods.

Admittedly these were open questions when I raised the PR but I just want to check this is how you'd like it!

In particular perhaps we could think of the first time user who potentially could run without a config file if they put the URL on the command line and their user ID matched the system one?

Anyway, I think the choices you've come up with are the conservative ones which would avoid surprising behaviour for existing users and there'd be scope to change.

fprintf(stderr, " SSL Verify : %d\n", options.verify);
fprintf(stderr, " Use .netrc : %d\n", options.netrc);
fprintf(stderr, " Use libsecret : %d\n", options.libsecret);
fprintf(stderr, " Password prompted : %d\n", options.pwprompt);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason I had "prompted" before was that I was modifying the options value with the result of whether it was actually prompted, for the purpose of saving it. If that is no longer the case you could reword it to make more sense as a config key, e.g. just "prompt".

Comment on lines +200 to +202
if (lookup_password() == 1) {
return(EXIT_FAILURE);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This means we can't fall back to prompt, .netrc or gpg if the password hasn't been cached?

Copy link
Owner

Choose a reason for hiding this comment

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

Yeah, I'm thinking these are not fall backs, rather "or"s. In my head the workflow would be to run -p the first time and then libsecret afterwards. Or you just use .netrc or gpg. But not to prompt the user, since that is an CLI option.

Copy link
Contributor Author

@andy-bower andy-bower Oct 27, 2024

Choose a reason for hiding this comment

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

Re this and last comment - I think you're unambiguously right about prompt vs .netrc/gpg but I'm not so sure when it comes to prompt vs. libsecret as I think those two modes would typically go hand-in-hand with other applications.

But I think I get more or less what I want if libsecret = yes is specified in the config as then you can simply add -p if you need to specify what that password is.

What about a command line option (e.g. -k- see below!) as a compromise to enable this config to make it easier for a first-time user to play?

} else {
options.netrc = 0;
}
} else if (strncmp("libsecret", vals[0], 9) == 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A thought: how about "keyring" or similar as the user-facing name for this config option as libsecret is more of an implementation detail and the user is more likely to be used to prompts from the likes of 'gnome-keyring' or 'kwallet' that actually implement the storage?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(we'd better add to the man page too @t-brown!)

Copy link
Owner

Choose a reason for hiding this comment

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

I do like the word keyring better, however I am torn as we are using libsecret. Does kwallet use libsecret? As it's GNOME vs KDE?

In hind sight, I should have done something like the following in the rc file:

pass = netrc | gpg | keyring 

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be honest, I'm not sure how the potential backends are organised and could have been wrong to mention kwallet - I think the actual API name might be "Secrets Service". One could also perhaps generically call it a credentials cache.

Only adding libsecet ability to save the password.
@t-brown t-brown merged commit a8a8010 into t-brown:master Nov 4, 2024
1 check passed
@andy-bower andy-bower deleted the secret branch November 9, 2024 22:46
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.

Add gnome-keyring integration

2 participants