osxkeychain: state to skip unnecessary store operations

git passes a credential that has been used successfully to the helpers
to record. If a credential is already stored,
"git-credential-osxkeychain store" just records the credential returned
by "git-credential-osxkeychain get", and unnecessary (sometimes
problematic) SecItemAdd() and/or SecItemUpdate() are performed.

We can skip such unnecessary operations by marking a credential returned
by "git-credential-osxkeychain get". This marking can be done by
utilizing the "state[]" feature:

- The "get" command sets the field "state[]=osxkeychain:seen=1".

- The "store" command skips its actual operation if the field
  "state[]=osxkeychain:seen=1" exists.

Introduce a new state "state[]=osxkeychain:seen=1".

Suggested-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Koji Nakamaru <koji.nakamaru@gree.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Koji Nakamaru 2024-05-15 19:21:07 +00:00 committed by Junio C Hamano
parent fcf5b74e59
commit e1ab45b2da
1 changed files with 11 additions and 0 deletions

View File

@ -12,6 +12,7 @@ static CFStringRef username;
static CFDataRef password; static CFDataRef password;
static CFDataRef password_expiry_utc; static CFDataRef password_expiry_utc;
static CFDataRef oauth_refresh_token; static CFDataRef oauth_refresh_token;
static int state_seen;


static void clear_credential(void) static void clear_credential(void)
{ {
@ -171,6 +172,9 @@ static OSStatus find_internet_password(void)


CFRelease(item); CFRelease(item);


write_item("capability[]", "state", strlen("state"));
write_item("state[]", "osxkeychain:seen=1", strlen("osxkeychain:seen=1"));

out: out:
CFRelease(attrs); CFRelease(attrs);


@ -284,6 +288,9 @@ static OSStatus add_internet_password(void)
CFDictionaryRef attrs; CFDictionaryRef attrs;
OSStatus result; OSStatus result;


if (state_seen)
return errSecSuccess;

/* Only store complete credentials */ /* Only store complete credentials */
if (!protocol || !host || !username || !password) if (!protocol || !host || !username || !password)
return -1; return -1;
@ -395,6 +402,10 @@ static void read_credential(void)
oauth_refresh_token = CFDataCreate(kCFAllocatorDefault, oauth_refresh_token = CFDataCreate(kCFAllocatorDefault,
(UInt8 *)v, (UInt8 *)v,
strlen(v)); strlen(v));
else if (!strcmp(buf, "state[]")) {
if (!strcmp(v, "osxkeychain:seen=1"))
state_seen = 1;
}
/* /*
* Ignore other lines; we don't know what they mean, but * Ignore other lines; we don't know what they mean, but
* this future-proofs us when later versions of git do * this future-proofs us when later versions of git do