* Re: Fwd: [Bug] `credential fill` prints incomplete bearer credential
2024-12-19 2:02 ` brian m. carlson
@ 2024-12-19 5:56 ` Junio C Hamano
2024-12-19 19:12 ` M Hickford
2024-12-19 19:15 ` M Hickford
2 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2024-12-19 5:56 UTC (permalink / raw)
To: brian m. carlson; +Cc: M Hickford, Git Mailing List
"brian m. carlson" <sandals@crustytoothpaste.net> writes:
> On 2024-12-18 at 20:42:31, M Hickford wrote:
>> Hi. Is this a bug in git version 2.47.1? Or am I using it incorrectly?
>>
>> # erase existing example.com credentials
>> printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
>> # store bearer token with expiry in far future in credential-cache
>> printf "host=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n"
>> | git credential-cache store
>> # try to retrieve credential
>> printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
>>
>> Expected output (complete credential):
>>
>> protocol=https
>> host=example.com
>> authtype=bearer
>> credential=letmein
>> password_expiry_utc=2147483640
>>
>> Actual output (incomplete credential, no prompt for username or password):
>>
>> protocol=https
>> host=example.com
>> password_expiry_utc=2147483640
>
> This is expected. Every request to a credential helper should include
> all of the capabilities that the caller supports on input, and the
> credential helper will always emit those on output. `git credential`,
> however, will only emit the capabilities that were actually supported,
> so that general callers (including Git LFS) can determine the actual
> set of supported capabilities.
> ...
The original report did
- run "git credential reject" to clear
- run "git credential-cache store"!!
- run "git credential fill" to check
which looked curious.
Am I correct to understand that if the second step is replaced with
"git credential approve" (which calls "credential-cache store"
internally), the right thing happens and necessary capabilities are
passed?
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Fwd: [Bug] `credential fill` prints incomplete bearer credential
2024-12-19 2:02 ` brian m. carlson
2024-12-19 5:56 ` Junio C Hamano
@ 2024-12-19 19:12 ` M Hickford
2024-12-19 19:15 ` M Hickford
2 siblings, 0 replies; 6+ messages in thread
From: M Hickford @ 2024-12-19 19:12 UTC (permalink / raw)
To: brian m. carlson, M Hickford, Git Mailing List
On Thu, 19 Dec 2024 at 02:02, brian m. carlson
<sandals@crustytoothpaste.net> wrote:
>
> On 2024-12-18 at 20:42:31, M Hickford wrote:
> > Hi. Is this a bug in git version 2.47.1? Or am I using it incorrectly?
> >
> > # erase existing example.com credentials
> > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
> > # store bearer token with expiry in far future in credential-cache
> > printf "host=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n"
> > | git credential-cache store
> > # try to retrieve credential
> > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
> >
> > Expected output (complete credential):
> >
> > protocol=https
> > host=example.com
> > authtype=bearer
> > credential=letmein
> > password_expiry_utc=2147483640
> >
> > Actual output (incomplete credential, no prompt for username or password):
> >
> > protocol=https
> > host=example.com
> > password_expiry_utc=2147483640
>
> This is expected. Every request to a credential helper should include
> all of the capabilities that the caller supports on input, and the
> credential helper will always emit those on output. `git credential`,
> however, will only emit the capabilities that were actually supported,
> so that general callers (including Git LFS) can determine the actual
> set of supported capabilities.
>
> In this case, you asked the cache helper for a credential, but didn't
> tell it that you supported `authtype` and `credential`. Therefore, the
> only safe thing it can assume is that you are incapable of parsing and
> understanding those fields, so it doesn't emit them. This is a benefit
> for security, because some tooling logs all fields but the `password`
> field, and we don't want to include new secret fields that the caller is
> going to shovel into a file or syslog.
Thank you Brian for the explanation. That fits my example.
Typically `credential fill` prompts the user if it can't complete a
credential. Surely it should prompt in this case too?
https://git-scm.com/docs/git-credential "git-credential will attempt
to add "username" and "password" attributes to the description by
reading config files, by contacting any configured credential helpers,
or by prompting the user"
>
> In addition, the helper could actually store two different sets of
> credentials, one which is a username and password, and one which is an
> authtype and credential. If you provided the capability, the latter
> would be omitted, but otherwise the former would. That can be helpful
> if you have a stronger credential type but might occasionally need to
> use older software (say, older versions of Git or Git LFS).
>
> However, if you provide the proper capability, this works as you expect:
>
> ----
> % printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
> % printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n" | git credential-cache store
> % printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
> capability[]=authtype
> authtype=bearer
> credential=letmein
> protocol=https
> host=example.com
> password_expiry_utc=2147483640
> ----
>
> Note that `capability[]` directives should always start the request to
> allow one-pass parsing.
>
> Hopefully this is helpful.
> --
> brian m. carlson (they/them or he/him)
> Toronto, Ontario, CA
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Fwd: [Bug] `credential fill` prints incomplete bearer credential
2024-12-19 2:02 ` brian m. carlson
2024-12-19 5:56 ` Junio C Hamano
2024-12-19 19:12 ` M Hickford
@ 2024-12-19 19:15 ` M Hickford
2024-12-21 8:08 ` M Hickford
2 siblings, 1 reply; 6+ messages in thread
From: M Hickford @ 2024-12-19 19:15 UTC (permalink / raw)
To: brian m. carlson, M Hickford, Git Mailing List
On Thu, 19 Dec 2024 at 02:02, brian m. carlson
<sandals@crustytoothpaste.net> wrote:
>
> On 2024-12-18 at 20:42:31, M Hickford wrote:
> > Hi. Is this a bug in git version 2.47.1? Or am I using it incorrectly?
> >
> > # erase existing example.com credentials
> > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
> > # store bearer token with expiry in far future in credential-cache
> > printf "host=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n"
> > | git credential-cache store
> > # try to retrieve credential
> > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
> >
> > Expected output (complete credential):
> >
> > protocol=https
> > host=example.com
> > authtype=bearer
> > credential=letmein
> > password_expiry_utc=2147483640
> >
> > Actual output (incomplete credential, no prompt for username or password):
> >
> > protocol=https
> > host=example.com
> > password_expiry_utc=2147483640
>
> This is expected. Every request to a credential helper should include
> all of the capabilities that the caller supports on input, and the
> credential helper will always emit those on output. `git credential`,
> however, will only emit the capabilities that were actually supported,
> so that general callers (including Git LFS) can determine the actual
> set of supported capabilities.
>
> In this case, you asked the cache helper for a credential, but didn't
> tell it that you supported `authtype` and `credential`. Therefore, the
> only safe thing it can assume is that you are incapable of parsing and
> understanding those fields, so it doesn't emit them. This is a benefit
> for security, because some tooling logs all fields but the `password`
> field, and we don't want to include new secret fields that the caller is
> going to shovel into a file or syslog.
>
> In addition, the helper could actually store two different sets of
> credentials, one which is a username and password, and one which is an
> authtype and credential. If you provided the capability, the latter
> would be omitted, but otherwise the former would. That can be helpful
> if you have a stronger credential type but might occasionally need to
> use older software (say, older versions of Git or Git LFS).
>
> However, if you provide the proper capability, this works as you expect:
>
> ----
> % printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
> % printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n" | git credential-cache store
> % printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
> capability[]=authtype
> authtype=bearer
> credential=letmein
> protocol=https
> host=example.com
> password_expiry_utc=2147483640
> ----
>
> Note that `capability[]` directives should always start the request to
> allow one-pass parsing.
I think a bug exists in credential-cache. Below it receives a query
*without* capability authtype, upgrades it *with* capability authtype
and prints a bearer credential.
git credential-cache exit
# store bearer credential
printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n"
| git credential-cache store
# query with capability authtype (prints bearer credential as expected)
printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" |
git credential-cache get
# query without capability authtype (expect nothing)
printf "host=example.com\nprotocol=https\n" | git credential-cache get
If you agree that this is a bug, we could add a test case to
helper_test_authtype.
Here's a second simpler example of credential-cache of upgrading a request:
git credential-cache exit
# store credential
printf "host=example.com\nprotocol=https\nusername=tim\npassword=hunter2\n"
| git credential-cache store
# get credential (response is upgraded with capability authtype)
printf "host=example.com\nprotocol=https" | git credential-cache get
>
> Hopefully this is helpful.
> --
> brian m. carlson (they/them or he/him)
> Toronto, Ontario, CA
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Fwd: [Bug] `credential fill` prints incomplete bearer credential
2024-12-19 19:15 ` M Hickford
@ 2024-12-21 8:08 ` M Hickford
0 siblings, 0 replies; 6+ messages in thread
From: M Hickford @ 2024-12-21 8:08 UTC (permalink / raw)
To: M Hickford; +Cc: brian m. carlson, Git Mailing List
On Thu, 19 Dec 2024 at 19:15, M Hickford <mirth.hickford@gmail.com> wrote:
>
> On Thu, 19 Dec 2024 at 02:02, brian m. carlson
> <sandals@crustytoothpaste.net> wrote:
> >
> > On 2024-12-18 at 20:42:31, M Hickford wrote:
> > > Hi. Is this a bug in git version 2.47.1? Or am I using it incorrectly?
> > >
> > > # erase existing example.com credentials
> > > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
> > > # store bearer token with expiry in far future in credential-cache
> > > printf "host=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n"
> > > | git credential-cache store
> > > # try to retrieve credential
> > > printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
> > >
> > > Expected output (complete credential):
> > >
> > > protocol=https
> > > host=example.com
> > > authtype=bearer
> > > credential=letmein
> > > password_expiry_utc=2147483640
> > >
> > > Actual output (incomplete credential, no prompt for username or password):
> > >
> > > protocol=https
> > > host=example.com
> > > password_expiry_utc=2147483640
> >
> > This is expected. Every request to a credential helper should include
> > all of the capabilities that the caller supports on input, and the
> > credential helper will always emit those on output. `git credential`,
> > however, will only emit the capabilities that were actually supported,
> > so that general callers (including Git LFS) can determine the actual
> > set of supported capabilities.
> >
> > In this case, you asked the cache helper for a credential, but didn't
> > tell it that you supported `authtype` and `credential`. Therefore, the
> > only safe thing it can assume is that you are incapable of parsing and
> > understanding those fields, so it doesn't emit them. This is a benefit
> > for security, because some tooling logs all fields but the `password`
> > field, and we don't want to include new secret fields that the caller is
> > going to shovel into a file or syslog.
> >
> > In addition, the helper could actually store two different sets of
> > credentials, one which is a username and password, and one which is an
> > authtype and credential. If you provided the capability, the latter
> > would be omitted, but otherwise the former would. That can be helpful
> > if you have a stronger credential type but might occasionally need to
> > use older software (say, older versions of Git or Git LFS).
> >
> > However, if you provide the proper capability, this works as you expect:
> >
> > ----
> > % printf "host=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential reject
> > % printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n" | git credential-cache store
> > % printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" | git -c credential.helper= -c credential.helper=cache credential fill
> > capability[]=authtype
> > authtype=bearer
> > credential=letmein
> > protocol=https
> > host=example.com
> > password_expiry_utc=2147483640
> > ----
> >
> > Note that `capability[]` directives should always start the request to
> > allow one-pass parsing.
>
> I think a bug exists in credential-cache. Below it receives a query
> *without* capability authtype, upgrades it *with* capability authtype
> and prints a bearer credential.
>
> git credential-cache exit
> # store bearer credential
> printf "capability[]=authtype\nhost=example.com\nprotocol=https\nauthtype=bearer\ncredential=letmein\npassword_expiry_utc=2147483640\n"
> | git credential-cache store
> # query with capability authtype (prints bearer credential as expected)
> printf "capability[]=authtype\nhost=example.com\nprotocol=https\n" |
> git credential-cache get
> # query without capability authtype (expect nothing)
> printf "host=example.com\nprotocol=https\n" | git credential-cache get
>
> If you agree that this is a bug, we could add a test case to
> helper_test_authtype.
Here's a small fix and test for credential-cache
https://lore.kernel.org/git/pull.1842.git.1734729534213.gitgitgadget@gmail.com/
>
> Here's a second simpler example of credential-cache of upgrading a request:
>
> git credential-cache exit
> # store credential
> printf "host=example.com\nprotocol=https\nusername=tim\npassword=hunter2\n"
> | git credential-cache store
> # get credential (response is upgraded with capability authtype)
> printf "host=example.com\nprotocol=https" | git credential-cache get
>
>
>
> >
> > Hopefully this is helpful.
> > --
> > brian m. carlson (they/them or he/him)
> > Toronto, Ontario, CA
^ permalink raw reply [flat|nested] 6+ messages in thread