mirror of
https://github.com/git/git.git
synced 2024-05-06 11:06:10 +02:00
osxkeychain: store new attributes
d208bfdfef
(credential: new attribute password_expiry_utc, 2023-02-18) anda5c76569e7
(credential: new attribute oauth_refresh_token, 2023-04-21) introduced new credential attributes but support was missing from git-credential-osxkeychain. Support these attributes by appending the data to the password in the keychain, separated by line breaks. Line breaks cannot appear in a git credential password so it is an appropriate separator. Fixes the remaining test failures with osxkeychain: 18 - helper (osxkeychain) gets password_expiry_utc 19 - helper (osxkeychain) overwrites when password_expiry_utc changes 21 - helper (osxkeychain) gets oauth_refresh_token Signed-off-by: Bo Anderson <mail@boanderson.me> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
e3cef40db8
commit
d5b35bba86
|
@ -6,10 +6,12 @@
|
|||
#define ENCODING kCFStringEncodingUTF8
|
||||
static CFStringRef protocol; /* Stores constant strings - not memory managed */
|
||||
static CFStringRef host;
|
||||
static CFNumberRef port;
|
||||
static CFStringRef path;
|
||||
static CFStringRef username;
|
||||
static CFDataRef password;
|
||||
static CFNumberRef port;
|
||||
static CFDataRef password_expiry_utc;
|
||||
static CFDataRef oauth_refresh_token;
|
||||
|
||||
static void clear_credential(void)
|
||||
{
|
||||
|
@ -17,6 +19,10 @@ static void clear_credential(void)
|
|||
CFRelease(host);
|
||||
host = NULL;
|
||||
}
|
||||
if (port) {
|
||||
CFRelease(port);
|
||||
port = NULL;
|
||||
}
|
||||
if (path) {
|
||||
CFRelease(path);
|
||||
path = NULL;
|
||||
|
@ -29,12 +35,18 @@ static void clear_credential(void)
|
|||
CFRelease(password);
|
||||
password = NULL;
|
||||
}
|
||||
if (port) {
|
||||
CFRelease(port);
|
||||
port = NULL;
|
||||
if (password_expiry_utc) {
|
||||
CFRelease(password_expiry_utc);
|
||||
password_expiry_utc = NULL;
|
||||
}
|
||||
if (oauth_refresh_token) {
|
||||
CFRelease(oauth_refresh_token);
|
||||
oauth_refresh_token = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#define STRING_WITH_LENGTH(s) s, sizeof(s) - 1
|
||||
|
||||
__attribute__((format (printf, 1, 2), __noreturn__))
|
||||
static void die(const char *err, ...)
|
||||
{
|
||||
|
@ -197,9 +209,27 @@ static OSStatus delete_ref(const void *itemRef)
|
|||
CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
|
||||
result = SecItemCopyMatching(query, (CFTypeRef *)&data);
|
||||
if (!result) {
|
||||
if (CFEqual(data, password))
|
||||
CFDataRef kc_password;
|
||||
const UInt8 *raw_data;
|
||||
const UInt8 *line;
|
||||
|
||||
/* Don't match appended metadata */
|
||||
raw_data = CFDataGetBytePtr(data);
|
||||
line = memchr(raw_data, '\n', CFDataGetLength(data));
|
||||
if (line)
|
||||
kc_password = CFDataCreateWithBytesNoCopy(
|
||||
kCFAllocatorDefault,
|
||||
raw_data,
|
||||
line - raw_data,
|
||||
kCFAllocatorNull);
|
||||
else
|
||||
kc_password = data;
|
||||
|
||||
if (CFEqual(kc_password, password))
|
||||
result = SecItemDelete(delete_query);
|
||||
|
||||
if (line)
|
||||
CFRelease(kc_password);
|
||||
CFRelease(data);
|
||||
}
|
||||
|
||||
|
@ -250,6 +280,7 @@ static OSStatus delete_internet_password(void)
|
|||
|
||||
static OSStatus add_internet_password(void)
|
||||
{
|
||||
CFMutableDataRef data;
|
||||
CFDictionaryRef attrs;
|
||||
OSStatus result;
|
||||
|
||||
|
@ -257,7 +288,23 @@ static OSStatus add_internet_password(void)
|
|||
if (!protocol || !host || !username || !password)
|
||||
return -1;
|
||||
|
||||
attrs = CREATE_SEC_ATTRIBUTES(kSecValueData, password,
|
||||
data = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, password);
|
||||
if (password_expiry_utc) {
|
||||
CFDataAppendBytes(data,
|
||||
(const UInt8 *)STRING_WITH_LENGTH("\npassword_expiry_utc="));
|
||||
CFDataAppendBytes(data,
|
||||
CFDataGetBytePtr(password_expiry_utc),
|
||||
CFDataGetLength(password_expiry_utc));
|
||||
}
|
||||
if (oauth_refresh_token) {
|
||||
CFDataAppendBytes(data,
|
||||
(const UInt8 *)STRING_WITH_LENGTH("\noauth_refresh_token="));
|
||||
CFDataAppendBytes(data,
|
||||
CFDataGetBytePtr(oauth_refresh_token),
|
||||
CFDataGetLength(oauth_refresh_token));
|
||||
}
|
||||
|
||||
attrs = CREATE_SEC_ATTRIBUTES(kSecValueData, data,
|
||||
NULL);
|
||||
|
||||
result = SecItemAdd(attrs, NULL);
|
||||
|
@ -268,6 +315,7 @@ static OSStatus add_internet_password(void)
|
|||
CFRelease(query);
|
||||
}
|
||||
|
||||
CFRelease(data);
|
||||
CFRelease(attrs);
|
||||
|
||||
return result;
|
||||
|
@ -339,6 +387,14 @@ static void read_credential(void)
|
|||
password = CFDataCreate(kCFAllocatorDefault,
|
||||
(UInt8 *)v,
|
||||
strlen(v));
|
||||
else if (!strcmp(buf, "password_expiry_utc"))
|
||||
password_expiry_utc = CFDataCreate(kCFAllocatorDefault,
|
||||
(UInt8 *)v,
|
||||
strlen(v));
|
||||
else if (!strcmp(buf, "oauth_refresh_token"))
|
||||
oauth_refresh_token = CFDataCreate(kCFAllocatorDefault,
|
||||
(UInt8 *)v,
|
||||
strlen(v));
|
||||
/*
|
||||
* Ignore other lines; we don't know what they mean, but
|
||||
* this future-proofs us when later versions of git do
|
||||
|
|
Loading…
Reference in New Issue