From: "Bo Anderson via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Bo Anderson <mail@boanderson.me>, Bo Anderson <mail@boanderson.me>
Subject: [PATCH 4/4] osxkeychain: store new attributes
Date: Sat, 17 Feb 2024 23:34:56 +0000 [thread overview]
Message-ID: <f18435b2189bb08bcdba3b28523db1d4484f66cf.1708212896.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1667.git.1708212896.gitgitgadget@gmail.com>
From: Bo Anderson <mail@boanderson.me>
d208bfdfef (credential: new attribute password_expiry_utc, 2023-02-18)
and a5c76569e7 (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>
---
.../osxkeychain/git-credential-osxkeychain.c | 68 +++++++++++++++++--
1 file changed, 62 insertions(+), 6 deletions(-)
diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
index 9e742796336..6a40917b1ef 100644
--- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c
+++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
@@ -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
--
gitgitgadget
next prev parent reply other threads:[~2024-02-17 23:35 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-17 23:34 [PATCH 0/4] osxkeychain: bring in line with other credential helpers Bo Anderson via GitGitGadget
2024-02-17 23:34 ` [PATCH 1/4] osxkeychain: replace deprecated SecKeychain API Bo Anderson via GitGitGadget
2024-02-18 6:08 ` Eric Sunshine
2024-02-18 14:48 ` Bo Anderson
2024-02-18 18:39 ` Eric Sunshine
2024-02-17 23:34 ` [PATCH 2/4] osxkeychain: erase all matching credentials Bo Anderson via GitGitGadget
2024-02-17 23:34 ` [PATCH 3/4] osxkeychain: erase matching passwords only Bo Anderson via GitGitGadget
2024-02-17 23:34 ` Bo Anderson via GitGitGadget [this message]
2024-02-18 6:31 ` [PATCH 4/4] osxkeychain: store new attributes Eric Sunshine
2024-02-18 6:38 ` [PATCH 0/4] osxkeychain: bring in line with other credential helpers Eric Sunshine
2024-02-18 20:40 ` M Hickford
2024-02-18 23:23 ` Bo Anderson
2024-03-04 8:00 ` M Hickford
2024-03-07 9:47 ` Jeff King
2024-04-02 13:21 ` Robert Coup
2024-04-02 13:53 ` Bo Anderson
2024-04-02 14:54 ` Robert Coup
2024-04-01 21:40 ` M Hickford
2024-04-01 22:16 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f18435b2189bb08bcdba3b28523db1d4484f66cf.1708212896.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=mail@boanderson.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).