Why aren't my credentials being stored in the keychain app even after following the credential helper?
In 2024, you can still see that kind of error (credentials not stored), for a different reason, as detailed with Git 2.46 (Q3 2024), batch 8.
See commit e1ab45b, commit fcf5b74 (15 May 2024) by Koji Nakamaru (KojiNakamaru
).
(Merged by Junio C Hamano -- gitster
-- in commit 2a1a882, 28 May 2024)
osxkeychain
: exclusive lock to serialize execution of operations
Signed-off-by: Koji Nakamaru
Git passes a credential that has been used successfully to the helpers to record.
If git-credential-osxkeychain store
commands run in parallel (with fetch.parallel
configuration and/or by running multiple git
commands simultaneously), some of them may exit with the error "failed to store: -25299
".
This is because SecItemUpdate()
in add_internet_password()
may return errSecDuplicateItem
(-25299
) in this situation.
Apple's documentation also states as below:
In macOS, some of the functions of this API block while waiting for input from the user (for example, when the user is asked to unlock a keychain or give permission to change trust settings).
In general, it is safe to use this API in threads other than your main thread, but avoid calling the functions from multiple operations, work queues, or threads concurrently.
Instead, serialize function calls or confine them to a single thread.
The error has not been noticed before, because the former implementation ignored the error.
Introduce an exclusive lock to serialize execution of operations.
Also, the credential helper to talk to OSX keychain sometimes sent garbage bytes after the username, which has been corrected with Git 2.47 (Q4 2024), batch 4.
See commit b201316 (01 Aug 2024) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit 6c3c451, 14 Aug 2024)
Reported-by: Hong Jiang
Signed-off-by: Jeff King
Tested-by: Hong Jiang
This patch fixes a case where git-credential-osxkeychain
might output uninitialized bytes to stdout.
We need to get the username string from a system API using CFStringGetCString()
.
To do that, we get the max size for the string from CFStringGetMaximumSizeForEncoding()
, allocate a buffer based on that, and then read into it.
But then we print the entire buffer to stdout, including the trailing NUL and any extra bytes which were not needed.
Instead, we should stop at the NUL.
This code comes from 9abe31f ("osxkeychain
: replace deprecated SecKeychain API", 2024-02-17, Git v2.45.0-rc0 -- merge listed in batch #20).
The bug was probably overlooked back then because this code is only used as a fallback when we can't get the string via CFStringGetCStringPtr()
.
According to Apple's documentation:
Whether or not this function returns a valid pointer or NULL depends
on many factors, all of which depend on how the string was created and
its properties.
So it's not clear how we could make a test for this, and we'll have to rely on manually testing on a system that triggered the bug in the first place.
GIT_TRACE=1 git pull
- it will show what credential helper commands are being run – Seawaregit credential-osxkeychain get
. But the problem is the the credentials don't exist in the keychain at all. – Beforehandgit credential-osxkeychain store
after you type your password? That's the bit that should save it – SeawareGET_TRACE=1 git pull
, and after writing password, it does run10:32:53.145811 run-command.c:643 trace: run_command: 'git credential-osxkeychain store' 10:32:53.172351 git.c:669 trace: exec: git-credential-osxkeychain store
. But no entry on keychain. Any idea on this? – Allegorystore
command somehow did not actually store the credential in the keychain. I have to be on a bare bash session once to store the credential, and after thatget
works just fine even in a tmux session. – Adalai