* Git credential-cache manager is not treating `path=` correctly
@ 2023-08-23 16:23 Gabriel Nützi
2023-08-23 19:22 ` Jeff King
0 siblings, 1 reply; 4+ messages in thread
From: Gabriel Nützi @ 2023-08-23 16:23 UTC (permalink / raw)
To: git@vger.kernel.org
I report this potential bug:
https://stackoverflow.com/questions/76963207/git-credential-cache-does-not-matchpath-correctly
I really dont get Git `2.41.0` and its crude `git credential-cache` manager:
When I test `git credential-cache` with the below script (`setsid test.sh`).
if it can report 3 different passwords it will fail with
```
fatal: could not read Username for
'https://www.server.com/repos/1.git': No such device or address
```
on the first run,
and when the script runs **a second time** it will pass happily.
The `git credential-store` on the other hand does not work at all and
on the first `git credential fill` prompt the user.
**Question: What is going on here. This makes no sense and results in
peculiar fails on CI**
*Note: setsid is to detach from the controlling terminal that git does
not prompt or something.*
*Note: We need `useHttpPath=true` to tell Git to use the `path` in
credential `fill` statements (AFAIK).
```shell
#!/bin/bash
set -e
# set -x
# IMPORTANT: =======================================
# Execute this script inside a container
# and check if it reports all password correctly
#
# ==================================================
# git credential-cache exit || true
git config --global --unset-all credential.helper || true
git config --global --add credential.helper ""
# git config --global --add credential.helper "store" # Does not work at all.
git config --global --add credential.helper "cache --timeout=7200"
git config --global
"credential.https://www.server.com/repos/1.git.useHttpPath" true
git config --global
"credential.https://www.server.com/repos/2.git.useHttpPath" true
export GIT_TRACE=1
# Add 3 credentials, 2 specifics with `path=`
# 1 with general host.
{
echo "protocol=https"
echo "host=www.server.com"
echo "path=repos/1.git"
echo "username=banana"
echo "password=banana1"
} | git credential approve
{
echo "protocol=https"
echo "host=www.server.com"
echo "path=repos/2.git"
echo "username=banana"
echo "password=banana2"
} | git credential approve
{
echo "protocol=https"
echo "host=www.server.com"
echo "username=banana"
echo "password=general"
} | git credential approve
echo "Check the credentials"
# Check it
{
echo "protocol=https"
echo "host=www.server.com"
echo "path=repos/1.git"
} | git credential fill | grep -q "password=banana1" || {
echo "wrong pass banana1"
exit 1
}
{
echo "protocol=https"
echo "host=www.server.com"
echo "path=repos/2.git"
} | git credential fill | grep -q "password=banana2" || {
echo "wrong pass banana2"
exit 1
}
{
echo "protocol=https"
echo "host=www.server.com"
} | git credential fill | grep -q "password=general" || {
echo "wrong pass general"
exit 1
}
echo "all passwords correctly reported"
```
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: Git credential-cache manager is not treating `path=` correctly 2023-08-23 16:23 Git credential-cache manager is not treating `path=` correctly Gabriel Nützi @ 2023-08-23 19:22 ` Jeff King 2023-08-23 21:02 ` Ganriel Nützi 0 siblings, 1 reply; 4+ messages in thread From: Jeff King @ 2023-08-23 19:22 UTC (permalink / raw) To: Gabriel Nützi; +Cc: git@vger.kernel.org On Wed, Aug 23, 2023 at 06:23:36PM +0200, Gabriel Nützi wrote: > # Add 3 credentials, 2 specifics with `path=` > # 1 with general host. > { > echo "protocol=https" > echo "host=www.server.com" > echo "path=repos/1.git" > echo "username=banana" > echo "password=banana1" > } | git credential approve > > { > echo "protocol=https" > echo "host=www.server.com" > echo "path=repos/2.git" > echo "username=banana" > echo "password=banana2" > } | git credential approve > > { > echo "protocol=https" > echo "host=www.server.com" > echo "username=banana" > echo "password=general" > } | git credential approve I don't think we ever planned around this kind of "sometimes paths are important, and sometimes not", and I'm not surprised it doesn't work. The "useHTTPPath" flag is only read by the by the main Git side, and just tells it whether to pass a "path" entry. On the helper side, any omitted entry ("path" in the final case) means "match anything". So that final command translates (from the helper's view) to "store this, and delete any other credentials we have stored for https://banana@www.server.com". It might be possible to change the handling on the helper side to distinguish between entries with no path and entries with a path, and consider them separately. I don't know what gotchas we might see in that case, though. I suspect at least in credential-store's on-disk format, there is not really room to distinguish the empty-string path from "no path given". If you set credential.useHTTPPaths (so that it is applied consistently), I think path-matching should work. But then you'd have to independently store credentials for each path that could match the "generic" case. As a workaround, you could use two different stores/caches. Something like: [credential] # store most stuff here helper = store [credential "https://www.server.com/repos/1.git"] # turn off the main helper, and use a path-specific file instead helper = helper = store --file=$HOME/.git-credentials-path useHttpPath = true -Peff ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Git credential-cache manager is not treating `path=` correctly 2023-08-23 19:22 ` Jeff King @ 2023-08-23 21:02 ` Ganriel Nützi 2023-08-24 14:44 ` Jeff King 0 siblings, 1 reply; 4+ messages in thread From: Ganriel Nützi @ 2023-08-23 21:02 UTC (permalink / raw) To: Jeff King; +Cc: git Thanks a lot for this informations. What I did not get from the documentation ist that a “store” of a generic (without path) credential , e.g https://www.server.com will just overwrite the more specific ones already in there. (So that is the case in my test, right? And the prompt happens in the first fill because useHttpPath=true but there is nomore any credential entry in the cache which would match (only the generic but that does not match), right?) I selectively applied useHttpPath for certain urls such that any other url not using httpPath matches the generic one (urls for submodules which I dont want to add credentials). So I just have to make sure the generic ones are added first and then the more specific ones (with path) I am not sure but I thought that using cache is safer than store because i generally dont want to have credentials on a disk. - Gabriel Von meinem iPhone gesendet > Am 23.08.2023 um 21:22 schrieb Jeff King <peff@peff.net>: > > On Wed, Aug 23, 2023 at 06:23:36PM +0200, Gabriel Nützi wrote: > >> # Add 3 credentials, 2 specifics with `path=` >> # 1 with general host. >> { >> echo "protocol=https" >> echo "host=www.server.com" >> echo "path=repos/1.git" >> echo "username=banana" >> echo "password=banana1" >> } | git credential approve >> >> { >> echo "protocol=https" >> echo "host=www.server.com" >> echo "path=repos/2.git" >> echo "username=banana" >> echo "password=banana2" >> } | git credential approve >> >> { >> echo "protocol=https" >> echo "host=www.server.com" >> echo "username=banana" >> echo "password=general" >> } | git credential approve > > I don't think we ever planned around this kind of "sometimes paths are > important, and sometimes not", and I'm not surprised it doesn't work. > > The "useHTTPPath" flag is only read by the by the main Git side, and > just tells it whether to pass a "path" entry. On the helper side, any > omitted entry ("path" in the final case) means "match anything". > > So that final command translates (from the helper's view) to "store > this, and delete any other credentials we have stored for > https://banana@www.server.com". > > It might be possible to change the handling on the helper side to > distinguish between entries with no path and entries with a path, and > consider them separately. I don't know what gotchas we might see in that > case, though. I suspect at least in credential-store's on-disk format, > there is not really room to distinguish the empty-string path from "no > path given". > > If you set credential.useHTTPPaths (so that it is applied consistently), > I think path-matching should work. But then you'd have to independently > store credentials for each path that could match the "generic" case. > > As a workaround, you could use two different stores/caches. Something > like: > > [credential] > # store most stuff here > helper = store > > [credential "https://www.server.com/repos/1.git"] > # turn off the main helper, and use a path-specific file instead > helper = > helper = store --file=$HOME/.git-credentials-path > useHttpPath = true > > -Peff ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Git credential-cache manager is not treating `path=` correctly 2023-08-23 21:02 ` Ganriel Nützi @ 2023-08-24 14:44 ` Jeff King 0 siblings, 0 replies; 4+ messages in thread From: Jeff King @ 2023-08-24 14:44 UTC (permalink / raw) To: Ganriel Nützi; +Cc: git On Wed, Aug 23, 2023 at 11:02:44PM +0200, Ganriel Nützi wrote: > What I did not get from the documentation ist that a “store” of a > generic (without path) credential , e.g https://www.server.com will > just overwrite the more specific ones already in there. (So that is > the case in my test, right? And the prompt happens in the first fill > because useHttpPath=true but there is nomore any credential entry in > the cache which would match (only the generic but that does not > match), right?) Right, exactly. It's possible that other helpers may behave differently here, but certainly the scheme used by both "store" and "cache" is to delete/replace anything that matches with the new credential. > I am not sure but I thought that using cache is safer than store > because i generally dont want to have credentials on a disk. It is safer. I used the "store" one while testing because it is easy to look at its internal state at any point with "cat ~/.git-credentials". :) But the same logic should apply to "cache", and my "use two helpers" trick should work by giving it a separate socket, like: [credential] helper = cache [credential "https://www.server.com/repos/1.git"] # separate socket/daemon for path-respecting entries helper = helper = credential --socket=$HOME/.git-credential-cache/socket-path useHttpPath = true -Peff ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-08-24 14:45 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-08-23 16:23 Git credential-cache manager is not treating `path=` correctly Gabriel Nützi 2023-08-23 19:22 ` Jeff King 2023-08-23 21:02 ` Ganriel Nützi 2023-08-24 14:44 ` Jeff King
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).