<pre style='margin:0'>
Herby Gillot (herbygillot) pushed a commit to branch master
in repository macports-ports.
</pre>
<p><a href="https://github.com/macports/macports-ports/commit/4182aebb5c3389a8588ae4e9ca920c65d7258385">https://github.com/macports/macports-ports/commit/4182aebb5c3389a8588ae4e9ca920c65d7258385</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new 4182aebb5c3 git-devel: update patch for < 10.7
</span>4182aebb5c3 is described below
<span style='display:block; white-space:pre;color:#808000;'>commit 4182aebb5c3389a8588ae4e9ca920c65d7258385
</span>Author: Sergey Fedorov <barracuda@macos-powerpc.org>
AuthorDate: Sun Sep 15 16:55:29 2024 +0800
<span style='display:block; white-space:pre;color:#404040;'> git-devel: update patch for < 10.7
</span>---
devel/git/Portfile | 24 +-
...atch-git-devel-Revert-breaking-osxkeychain.diff | 535 +++++++++++++++++++++
2 files changed, 551 insertions(+), 8 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/git/Portfile b/devel/git/Portfile
</span><span style='display:block; white-space:pre;color:#808080;'>index 997b5310a55..3e0b260645c 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/devel/git/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/git/Portfile
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -43,6 +43,8 @@ categories devel
</span> license GPL-2 LGPL-2.1+
installs_libs no
<span style='display:block; white-space:pre;background:#e0ffe0;'>+patch.pre_args-replace -p0 -p1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if {${name} eq ${subport}} {
# RELEASE VERSION
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -71,6 +73,13 @@ if {${name} eq ${subport}} {
</span>
conflicts git-devel
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Reverts breakage introduced by 51c15ac1b6ab15d8e29651d0bd364d8f62dc6509
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # and later commits.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # TODO: consider convising upstream to restore fallback code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {${os.platform} eq "darwin" && ${os.major} < 11} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ patchfiles-append patch-Revert-breaking-osxkeychain.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> livecheck.type regexm
livecheck.regex {<span class="version">.*?(\d+\.\d+\.\d+).*?</span>}
} else {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -88,6 +97,13 @@ if {${name} eq ${subport}} {
</span> build.target all man html
conflicts git
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # Reverts breakage introduced by 51c15ac1b6ab15d8e29651d0bd364d8f62dc6509
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # and later commits.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ # TODO: consider convising upstream to restore fallback code.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if {${os.platform} eq "darwin" && ${os.major} < 11} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ patchfiles-append patch-git-devel-Revert-breaking-osxkeychain.diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> }
perl5.require_variant false
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -112,14 +128,6 @@ patchfiles-append patch-Makefile.diff \
</span> patch-sha1dc-older-apple-gcc-versions.diff \
patch-gitk-git-gitk.diff
<span style='display:block; white-space:pre;background:#ffe0e0;'>-patch.pre_args-replace -p0 -p1
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# Reverts breakage introduced by:
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-# https://github.com/git/git/commit/51c15ac1b6ab15d8e29651d0bd364d8f62dc6509
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-if {${os.platform} eq "darwin" && ${os.major} < 11} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- patchfiles-append patch-Revert-breaking-osxkeychain.diff
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> # Git 2.36.0 implements a new FSEvent listener that uses
# the API available in Yosemite and newer.
if {${os.platform} eq "darwin" && ${os.major} < 14} {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/devel/git/files/patch-git-devel-Revert-breaking-osxkeychain.diff b/devel/git/files/patch-git-devel-Revert-breaking-osxkeychain.diff
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..1133d309b88
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/devel/git/files/patch-git-devel-Revert-breaking-osxkeychain.diff
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,535 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From ac042352b4910134c4c4d74b68f30061bde145b1 Mon Sep 17 00:00:00 2001
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+From: Sergey Fedorov <barracuda@macos-powerpc.org>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Date: Sun, 15 Sep 2024 15:44:12 +0800
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+Subject: [PATCH] Revert breaking osxkeychain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit e1ab45b2dab51f94db9548666dfd7af626d2aa7e.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit fcf5b74e59c1c0d18a8e8e939475007b3b5f83ad.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit d5b35bba86e6fdf0484ea71bf5b8ef1167f14015.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit e3cef40db89f5a7c91f4e9d6c4959ca1e41f4647.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit 9032bcad82f45a403e4a8de86e1fcb4bfd1ab282.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit 9abe31f5f161be4d69118bdfae00103cd6efa510.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+This reverts commit b201316835bbf2c49c2780f23cfd6146f6b8d1a2.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+---
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ contrib/credential/osxkeychain/Makefile | 3 +-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ .../osxkeychain/git-credential-osxkeychain.c | 390 +++---------------
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ 2 files changed, 69 insertions(+), 324 deletions(-)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/contrib/credential/osxkeychain/Makefile b/contrib/credential/osxkeychain/Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 238f5f8c36..4b3a08a2ba 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/contrib/credential/osxkeychain/Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/contrib/credential/osxkeychain/Makefile
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -8,8 +8,7 @@ CFLAGS = -g -O2 -Wall
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ -include ../../../config.mak
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git-credential-osxkeychain: git-credential-osxkeychain.o
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- -framework Security -framework CoreFoundation
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -Wl,-framework -Wl,Security
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ git-credential-osxkeychain.o: git-credential-osxkeychain.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ $(CC) -c $(CFLAGS) $<
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+index 1c8310d7fe..5f2e5f16c8 100644
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -3,52 +3,14 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ #include <Security/Security.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#define ENCODING kCFStringEncodingUTF8
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFStringRef protocol; /* Stores constant strings - not memory managed */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFStringRef host;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFNumberRef port;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFStringRef path;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFStringRef username;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFDataRef password;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFDataRef password_expiry_utc;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFDataRef oauth_refresh_token;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static int state_seen;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static void clear_credential(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (host) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(host);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- host = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (port) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(port);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- port = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (path) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(path);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- path = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (username) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(username);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- username = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (password) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(password);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- password = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (password_expiry_utc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(password_expiry_utc);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- password_expiry_utc = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (oauth_refresh_token) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(oauth_refresh_token);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- oauth_refresh_token = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#define STRING_WITH_LENGTH(s) s, sizeof(s) - 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-__attribute__((format (printf, 1, 2), __noreturn__))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static SecProtocolType protocol;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static char *host;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static char *path;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static char *username;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static char *password;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static UInt16 port;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++__attribute__((format (printf, 1, 2)))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static void die(const char *err, ...)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char msg[4096];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -57,202 +19,70 @@ static void die(const char *err, ...)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ vsnprintf(msg, sizeof(msg), err, params);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(stderr, "%s\n", msg);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ va_end(params);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- clear_credential();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ exit(1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static void *xmalloc(size_t len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void *xstrdup(const char *s1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- void *ret = malloc(len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void *ret = strdup(s1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!ret)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ die("Out of memory");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static CFDictionaryRef create_dictionary(CFAllocatorRef allocator, ...)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- va_list args;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const void *key;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFMutableDictionaryRef result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = CFDictionaryCreateMutable(allocator,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- &kCFTypeDictionaryKeyCallBacks,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- &kCFTypeDictionaryValueCallBacks);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- va_start(args, allocator);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- while ((key = va_arg(args, const void *)) != NULL) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const void *value;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- value = va_arg(args, const void *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (value)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionarySetValue(result, key, value);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- va_end(args);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-#define CREATE_SEC_ATTRIBUTES(...) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- create_dictionary(kCFAllocatorDefault, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecClass, kSecClassInternetPassword, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrServer, host, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrAccount, username, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrPath, path, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrPort, port, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrProtocol, protocol, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrAuthenticationType, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecAttrAuthenticationTypeDefault, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- __VA_ARGS__);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static void write_item(const char *what, const char *buf, size_t len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define KEYCHAIN_ITEM(x) (x ? strlen(x) : 0), x
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++#define KEYCHAIN_ARGS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NULL, /* default keychain */ \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ KEYCHAIN_ITEM(host), \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ 0, NULL, /* account domain */ \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ KEYCHAIN_ITEM(username), \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ KEYCHAIN_ITEM(path), \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ port, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol, \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ kSecAuthenticationTypeDefault
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void write_item(const char *what, const char *buf, int len)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf("%s=", what);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fwrite(buf, 1, len, stdout);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ putchar('\n');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static void find_username_in_item(CFDictionaryRef item)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void find_username_in_item(SecKeychainItemRef item)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFStringRef account_ref;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- char *username_buf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFIndex buffer_len;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainAttributeList list;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainAttribute attr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- account_ref = CFDictionaryGetValue(item, kSecAttrAccount);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!account_ref)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- write_item("username", "", 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ list.count = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ list.attr = &attr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ attr.tag = kSecAccountItemAttr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- username_buf = (char *)CFStringGetCStringPtr(account_ref, ENCODING);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (username_buf)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- write_item("username", username_buf, strlen(username_buf));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (SecKeychainItemCopyContent(item, NULL, &list, NULL, NULL))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* If we can't get a CString pointer then
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- * we need to allocate our own buffer */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- buffer_len = CFStringGetMaximumSizeForEncoding(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFStringGetLength(account_ref), ENCODING) + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- username_buf = xmalloc(buffer_len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (CFStringGetCString(account_ref,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- username_buf,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- buffer_len,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- ENCODING)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- write_item("username", username_buf, strlen(username_buf));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- free(username_buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ write_item("username", attr.data, attr.length);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainItemFreeContent(&list, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static OSStatus find_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void find_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionaryRef attrs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionaryRef item;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataRef data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- OSStatus result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ void *buf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ UInt32 len;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainItemRef item;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- attrs = CREATE_SEC_ATTRIBUTES(kSecMatchLimit, kSecMatchLimitOne,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecReturnAttributes, kCFBooleanTrue,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecReturnData, kCFBooleanTrue,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemCopyMatching(attrs, (CFTypeRef *)&item);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- goto out;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- data = CFDictionaryGetValue(item, kSecValueData);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (SecKeychainFindInternetPassword(KEYCHAIN_ARGS, &len, &buf, &item))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- write_item("password",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (const char *)CFDataGetBytePtr(data),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataGetLength(data));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ write_item("password", buf, len);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!username)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ find_username_in_item(item);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(item);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- write_item("capability[]", "state", strlen("state"));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- write_item("state[]", "osxkeychain:seen=1", strlen("osxkeychain:seen=1"));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-out:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(attrs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* We consider not found to not be an error */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (result == errSecItemNotFound)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = errSecSuccess;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static OSStatus delete_ref(const void *itemRef)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFArrayRef item_ref_list;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionaryRef delete_query;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- OSStatus result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- item_ref_list = CFArrayCreate(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- &itemRef,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- 1,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- &kCFTypeArrayCallBacks);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- delete_query = create_dictionary(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecClass, kSecClassInternetPassword,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecMatchItemList, item_ref_list,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (password) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* We only want to delete items with a matching password */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFIndex capacity;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFMutableDictionaryRef query;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataRef data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- capacity = CFDictionaryGetCount(delete_query) + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- query = CFDictionaryCreateMutableCopy(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- capacity,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- delete_query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemCopyMatching(query, (CFTypeRef *)&data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataRef kc_password;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const UInt8 *raw_data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- const UInt8 *line;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* Don't match appended metadata */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- raw_data = CFDataGetBytePtr(data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- line = memchr(raw_data, '\n', CFDataGetLength(data));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (line)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kc_password = CFDataCreateWithBytesNoCopy(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- raw_data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- line - raw_data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kCFAllocatorNull);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kc_password = data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (CFEqual(kc_password, password))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemDelete(delete_query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (line)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(kc_password);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemDelete(delete_query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(delete_query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(item_ref_list);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainItemFreeContent(NULL, buf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static OSStatus delete_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void delete_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionaryRef attrs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFArrayRef refs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- OSStatus result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainItemRef item;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Require at least a protocol and host for removal, which is what git
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -260,72 +90,25 @@ static OSStatus delete_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Keychain manager.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!protocol || !host)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- attrs = CREATE_SEC_ATTRIBUTES(kSecMatchLimit, kSecMatchLimitAll,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kSecReturnRef, kCFBooleanTrue,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemCopyMatching(attrs, (CFTypeRef *)&refs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(attrs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!result) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- for (CFIndex i = 0; !result && i < CFArrayGetCount(refs); i++)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = delete_ref(CFArrayGetValueAtIndex(refs, i));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(refs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* We consider not found to not be an error */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (result == errSecItemNotFound)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = errSecSuccess;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (SecKeychainFindInternetPassword(KEYCHAIN_ARGS, 0, NULL, &item))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ SecKeychainItemDelete(item);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-static OSStatus add_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++static void add_internet_password(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFMutableDataRef data;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionaryRef attrs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- OSStatus result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (state_seen)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return errSecSuccess;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Only store complete credentials */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!protocol || !host || !username || !password)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- data = CFDataCreateMutableCopy(kCFAllocatorDefault, 0, password);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (password_expiry_utc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataAppendBytes(data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (const UInt8 *)STRING_WITH_LENGTH("\npassword_expiry_utc="));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataAppendBytes(data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataGetBytePtr(password_expiry_utc),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataGetLength(password_expiry_utc));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (oauth_refresh_token) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataAppendBytes(data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (const UInt8 *)STRING_WITH_LENGTH("\noauth_refresh_token="));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataAppendBytes(data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataGetBytePtr(oauth_refresh_token),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDataGetLength(oauth_refresh_token));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- attrs = CREATE_SEC_ATTRIBUTES(kSecValueData, data,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemAdd(attrs, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (result == errSecDuplicateItem) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFDictionaryRef query;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- query = CREATE_SEC_ATTRIBUTES(NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = SecItemUpdate(query, attrs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(query);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(data);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- CFRelease(attrs);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- return result;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ if (SecKeychainAddInternetPassword(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ KEYCHAIN_ARGS,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ KEYCHAIN_ITEM(password),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ NULL))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ static void read_credential(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -348,64 +131,36 @@ static void read_credential(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!strcmp(buf, "protocol")) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!strcmp(v, "imap"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolIMAP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeIMAP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(v, "imaps"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolIMAPS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeIMAPS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(v, "ftp"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolFTP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeFTP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(v, "ftps"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolFTPS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeFTPS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(v, "https"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolHTTPS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeHTTPS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(v, "http"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolHTTP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeHTTP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(v, "smtp"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- protocol = kSecAttrProtocolSMTP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- /* we don't yet handle other protocols */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- clear_credential();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ protocol = kSecProtocolTypeSMTP;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ else /* we don't yet handle other protocols */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ exit(0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(buf, "host")) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char *colon = strchr(v, ':');
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (colon) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- UInt16 port_i;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *colon++ = '\0';
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- port_i = atoi(colon);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- port = CFNumberCreate(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kCFNumberShortType,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- &port_i);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ port = atoi(colon);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- host = CFStringCreateWithCString(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- v,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- ENCODING);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ host = xstrdup(v);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(buf, "path"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- path = CFStringCreateWithCString(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- v,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- ENCODING);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ path = xstrdup(v);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(buf, "username"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- username = CFStringCreateWithCString(
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- v,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- ENCODING);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ username = xstrdup(v);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(buf, "password"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- password = CFDataCreate(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (UInt8 *)v,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- strlen(v));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else if (!strcmp(buf, "password_expiry_utc"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- password_expiry_utc = CFDataCreate(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (UInt8 *)v,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- strlen(v));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else if (!strcmp(buf, "oauth_refresh_token"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- oauth_refresh_token = CFDataCreate(kCFAllocatorDefault,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- (UInt8 *)v,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- strlen(v));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- else if (!strcmp(buf, "state[]")) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (!strcmp(v, "osxkeychain:seen=1"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- state_seen = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ password = xstrdup(v);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Ignore other lines; we don't know what they mean, but
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * this future-proofs us when later versions of git do
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+@@ -418,30 +173,21 @@ static void read_credential(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int main(int argc, const char **argv)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- OSStatus result = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const char *usage =
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ "usage: git credential-osxkeychain <get|store|erase>";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!argv[1])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ die("%s", usage);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (open(argv[0], O_RDONLY | O_EXLOCK) == -1)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- die("failed to lock %s", argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ read_credential();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!strcmp(argv[1], "get"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = find_internet_password();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ find_internet_password();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(argv[1], "store"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = add_internet_password();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ add_internet_password();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if (!strcmp(argv[1], "erase"))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- result = delete_internet_password();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>++ delete_internet_password();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* otherwise, ignore unknown action */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- if (result)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- die("failed to %s: %d", argv[1], (int)result);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+- clear_credential();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+-
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span></pre><pre style='margin:0'>
</pre>