Correct credential helper discrepancies handling input
cover Correct credential helper discrepancies handling input
Whilst working in the credential helper and auth space I happened to notice that the behaviour of some of the credential helpers in contrib/credential/ is not consistent.
Specifically both the git-credential-wincred and git-credential-netrc helpers die when they receive unknown credential property keys, which is contrary to the behaviour of all the other in-tree helpers including:
git-credential-cache, -store, -libsecret, -gnome-keyring, -osxkeychain.
Also update the git-credential-osxkeychain helper to include a comment making it's behaviour explicit in ignoring unknown keys, as per other helpers.
Matthew John Cheetham (3):
wincred: ignore unknown lines (do not die)
netrc: ignore unknown lines (do not die)
osxkeychain: clarify that we ignore unknown lines
contrib/credential/netrc/git-credential-netrc.perl | 5 ++++- .../credential/osxkeychain/git-credential-osxkeychain.c | 5 +++++ contrib/credential/wincred/git-credential-wincred.c | 7 +++++-- 3 files changed, 14 insertions(+), 3 deletions(-)
base-commit: dd3f6c4cae7e3b15ce984dce8593ff7569650e24
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1363%2Fmjcheetham%2Fcredhelper-fixes-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1363/mjcheetham/credhelper-fixes-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1363
Signature · 1 line
gitgitgadget
PATCH 1/3 wincred: ignore unknown lines (do not die)
From: Matthew John Cheetham <[email protected]>
It is the expectation that credential helpers be liberal in what they accept and conservative in what they return, to allow for future growth and evolution of the protocol/interaction.
All of the other helpers (store, cache, osxkeychain, libsecret, gnome-keyring) except netrc currently ignore any credential lines that are not recognised, whereas the Windows helper (wincred) instead dies.
Fix the discrepancy and ignore unknown lines in the wincred helper.
--- contrib/credential/wincred/git-credential-wincred.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
contrib/credential/wincred/git-credential-wincred.c +5 -2
@@ -278,8 +278,11 @@ static void read_credential(void) wusername =utf8_to_utf16_dup (v); }else if (!strcmp (buf,"password" )) password =utf8_to_utf16_dup (v); -else -die ("unrecognized input" ); +/* +* Ignore other lines; we don't know what they mean, but +* this future-proofs us when later versions of git do +* learn new lines, and the helpers are updated to match. +*/ } }
Signature · 1 line
gitgitgadget
PATCH 2/3 netrc: ignore unknown lines (do not die)
In reply to Matthew John Cheetham via GitGitGadgetFrom: Matthew John Cheetham <[email protected]>
Contrary to the documentation on credential helpers, as well as the help text for git-credential-netrc itself, this helper will die when presented with an unknown property/attribute/token.
Correct the behaviour here by skipping and ignoring any tokens that are unknown. This means all helpers in the tree are consistent and ignore any unknown credential properties/attributes.
--- contrib/credential/netrc/git-credential-netrc.perl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
contrib/credential/netrc/git-credential-netrc.perl +4 -1
@@ -356,7 +356,10 @@ sub read_credential_data_from_stdin { next unless m/^([^=]+)=(.+)/; my ($token, $value) = ($1, $2); - die "Unknown search token $token" unless exists $q{$token}; + + # skip any unknown tokens + next unless exists $q{$token}; + $q{$token} = $value; log_debug("We were given search token $token and value $value"); }
Signature · 1 line
gitgitgadget
PATCH 3/3 osxkeychain: clarify that we ignore unknown lines
In reply to Matthew John Cheetham via GitGitGadgetFrom: Matthew John Cheetham <[email protected]>
Like in all the other credential helpers, the osxkeychain helper ignores unknown credential lines.
Add a comment (a la the other helpers) to make it clear and explicit that this is the desired behaviour.
--- contrib/credential/osxkeychain/git-credential-osxkeychain.c | 5 +++++ 1 file changed, 5 insertions(+)
contrib/credential/osxkeychain/git-credential-osxkeychain.c +5 -0
@@ -159,6 +159,11 @@ static void read_credential(void) username =xstrdup (v); else if (!strcmp(buf, "password")) password =xstrdup (v); +/* +* Ignore other lines; we don't know what they mean, but +* this future-proofs us when later versions of git do +* learn new lines, and the helpers are updated to match. +*/ } }
Signature · 1 line
gitgitgadget
Quoted 4 lines · Matthew John Cheetham via GitGitGadget
Whilst working in the credential helper and auth space I happened to notice that the behaviour of some of the credential helpers in contrib/credential/ is not consistent.
Quoted 8 lines
Specifically both the git-credential-wincred and git-credential-netrc helpers die when they receive unknown credential property keys, which is contrary to the behaviour of all the other in-tree helpers including:
git-credential-cache, -store, -libsecret, -gnome-keyring, -osxkeychain.Also update the git-credential-osxkeychain helper to include a comment making it's behaviour explicit in ignoring unknown keys, as per other helpers.
Thanks for sending this patches separate from your earlier RFC. I think these patches speak for themselves and are good to go.
Thanks,
-Stolee
Re: [PATCH 1/3] wincred: ignore unknown lines (do not die)
In reply to Matthew John Cheetham via GitGitGadget"Matthew John Cheetham via GitGitGadget" <[email protected]>
Quoted 5 lines · writes:
From: Matthew John Cheetham <[email protected]>
It is the expectation that credential helpers be liberal in what they accept and conservative in what they return, to allow for future growth and evolution of the protocol/interaction.
That is nice in principle, and the updated code below may work well with existing "other side of the connection" (codepaths in "git" that asks credential API to talk to the helpers), but I am not sure if this is always a safe thing to do.
When we gain a new "command" in the protocol, if we just read it without understanding it, would we open ourselves to a risk of breaking the protocol communication, worst of which may be to deadlock? A new command, when received by a more recent helper that understands how to react to it, may _require_ it to write more than "username" and "password" back to "git" from get_credential(), for example, but the helper with this patch alone, while not complaining about seeing such a new and unknown command, would not know how to compute and write that third thing other than "username" and "password"---would the other side who issued that new command get stuck waiting for us to return the third thing? Worse yet, the new command may expect us to read further in get_credential() (e.g. maybe they will give us a challenge, which may need to be used when yielding the "username" and "password" things), but because we do not even know we need to read, their attempt to write to us may get them stuck, and that is when we are expecting to write to them, easily leading to a deadlock, no?
Quoted 4 lines
All of the other helpers (store, cache, osxkeychain, libsecret, gnome-keyring) except
netrccurrently ignore any credential lines that are not recognised, whereas the Windows helper (wincred) instead dies.
Is that different from saying "everybody other than netrc and win ignore unknown"?
Quoted 1 line
Fix the discrepancy and ignore unknown lines in the wincred helper.
OK. As long as everybody consistently ignores, and possibly opens themselves up consistently to a protocol mismatch issue, it is OK. We will know if that can be a real problem or does not happen in practice.
Quoted 22 lines
Signed-off-by Matthew John Cheetham <[email protected]>--- contrib/credential/wincred/git-credential-wincred.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)contrib/credential/wincred/git-credential-wincred.c +5
-2@@ -278,8 +278,11 @@ static void read_credential(void) wusername =utf8_to_utf16_dup (v); }else if (!strcmp (buf,"password" )) password =utf8_to_utf16_dup (v); -else -die ("unrecognized input" ); +/* +* Ignore other lines; we don't know what they mean, but +* this future-proofs us when later versions of git do +* learn new lines, and the helpers are updated to match. +*/ } }
Re: [PATCH 1/3] wincred: ignore unknown lines (do not die)
Quoted 18 lines · Junio C Hamano
Quoted 3 lines
It is the expectation that credential helpers be liberal in what they accept and conservative in what they return, to allow for future growth and evolution of the protocol/interaction.
That is nice in principle, and the updated code below may work well with existing "other side of the connection" (codepaths in "git" that asks credential API to talk to the helpers), but I am not sure if this is always a safe thing to do.
When we gain a new "command" in the protocol, if we just read it without understanding it, would we open ourselves to a risk of breaking the protocol communication, worst of which may be to deadlock? A new command, when received by a more recent helper that understands how to react to it, may _require_ it to write more than "username" and "password" back to "git" from
get_credential(), for example, but the helper with this patch alone, while not complaining about seeing such a new and unknown command, would not know how to compute and write that third thing other than "username" and
Quoted 8 lines
"password"---would the other side who issued that new command get stuck waiting for us to return the third thing? Worse yet, the new command may expect us to read further in
get_credential()(e.g. maybe they will give us a challenge, which may need to be used when yielding the "username" and "password" things), but because we do not even know we need to read, their attempt to write to us may get them stuck, and that is when we are expecting to write to them, easily leading to a deadlock, no?
This open-endedness was an intentional part of the original credential-helper design. Helpers are always "best effort", and it is OK if they ignore a request, or return a partial result. If the sending side really wants to extend the protocol in a way that the other side doesn't act at all (say, they "username" to be used _only_ if the helper also understands a new "foobar" key), then they should be adding the new fields as an atomic unit. I.e., "foobar", "foobar-userame", and so on. And then existing helpers which don't understand the new feature will just ignore it totally.
In practice, I think it's not that big a deal either way, because the setup of these helpers is under the control of the user. So if you really want to use "foobar" but a helper doesn't support it, then you'd just remove that helper from your config.
-Peff
Quoted 4 lines · Matthew John Cheetham via GitGitGadget
Whilst working in the credential helper and auth space I happened to notice that the behaviour of some of the credential helpers in contrib/credential/ is not consistent.
Quoted 8 lines
Specifically both the git-credential-wincred and git-credential-netrc helpers die when they receive unknown credential property keys, which is contrary to the behaviour of all the other in-tree helpers including:
git-credential-cache, -store, -libsecret, -gnome-keyring, -osxkeychain.Also update the git-credential-osxkeychain helper to include a comment making it's behaviour explicit in ignoring unknown keys, as per other helpers.
Thanks, I think these are all sensible changes. The new behavior matches the original vision of the helper protocol. But more importantly, it brings them in line with all of the _other_ existing helpers. Which is no coincidence, since the designer of the protocol wrote most of them. ;)
I haven't had a chance to look carefully at the rest of your larger series yet, but I think these are a nice standalone improvement regardless of what happens there.
-Peff