From: Jay Soffian <jaysoffian@gmail.com>
To: git@vger.kernel.org
Cc: Jay Soffian <jaysoffian@gmail.com>,
Junio C Hamano <gitster@pobox.com>, Jeff King <peff@peff.net>,
John Szakmeister <john@szakmeister.net>
Subject: [PATCH] credential-osxkeychain: load Security framework dynamically
Date: Wed, 14 Sep 2011 18:55:26 -0400 [thread overview]
Message-ID: <1316040926-89429-1-git-send-email-jaysoffian@gmail.com> (raw)
In-Reply-To: <1316023117-84755-1-git-send-email-jaysoffian@gmail.com>
Use dlopen() / dysym() instead of dynmically linking to the
Security framework. A followup commit will refactor things such
that git-credential-osxkeychain can be hardlinked to git.
Signed-off-by: Jay Soffian <jaysoffian@gmail.com>
---
> Hmm, maybe it can be if I dlopen the security framework instead of linking
> against it.
Something like this. I'm going to pause here for feedback. Is the (not yet
existant) followup commit referenced above allowing git-credential-osxkeychain
to be a hard link to git a worthwhile endeavor? Or would a better approach be
to make git-credential-osxkeychain.c not use any git code?
contrib/credential-osxkeychain/Makefile | 12 +++-
.../credential-osxkeychain/generate_security.py | 73 ++++++++++++++++++++
2 files changed, 82 insertions(+), 3 deletions(-)
create mode 100755 contrib/credential-osxkeychain/generate_security.py
diff --git a/contrib/credential-osxkeychain/Makefile b/contrib/credential-osxkeychain/Makefile
index dc6bbbc3f9..001d695cb8 100644
--- a/contrib/credential-osxkeychain/Makefile
+++ b/contrib/credential-osxkeychain/Makefile
@@ -25,11 +25,17 @@ ifndef V
endif
endif
-git-credential-osxkeychain: git-credential-osxkeychain.o $(GIT_LIBS)
- $(QUIET_LINK)$(CC) -o $@ $< $(LIBS) -Wl,-framework -Wl,Security
+git-credential-osxkeychain: git-credential-osxkeychain.o security.o $(GIT_LIBS)
+ $(QUIET_LINK)$(CC) -o $@ $< security.o $(LIBS)
git-credential-osxkeychain.o: git-credential-osxkeychain.c
$(QUIET_CC)$(CC) -c $(CFLAGS) $<
+security.o: security.c
+ $(QUIET_CC)$(CC) -c $(CFLAGS) $<
+
+security.c: generate_security.py
+ python generate_security.py
+
clean:
- $(RM) git-credential-osxkeychain git-credential-osxkeychain.o
+ $(RM) git-credential-osxkeychain git-credential-osxkeychain.o security.?
diff --git a/contrib/credential-osxkeychain/generate_security.py b/contrib/credential-osxkeychain/generate_security.py
new file mode 100755
index 0000000000..db94672e95
--- /dev/null
+++ b/contrib/credential-osxkeychain/generate_security.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+import re
+
+func_decls = """
+OSStatus SecKeychainAddInternetPassword(SecKeychainRef keychain, UInt32 serverNameLength, const char *serverName, UInt32 securityDomainLength, const char *securityDomain, UInt32 accountNameLength, const char *accountName, UInt32 pathLength, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef);
+OSStatus SecKeychainFindInternetPassword(CFTypeRef keychainOrArray, UInt32 serverNameLength, const char *serverName, UInt32 securityDomainLength, const char *securityDomain, UInt32 accountNameLength, const char *accountName, UInt32 pathLength, const char *path, UInt16 port, SecProtocolType protocol, SecAuthenticationType authenticationType, UInt32 *passwordLength, void **passwordData, SecKeychainItemRef *itemRef);
+OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData);
+OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef);
+OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList *attrList, void *data);
+OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList *attrList, UInt32 length, const void *data);
+"""
+
+header = r"""
+#include <dlfcn.h>
+#include <Security/Security.h>
+#include "cache.h"
+
+const char *security_framework =
+ "/System/Library/Frameworks/Security.framework/Security";
+
+void *load_security()
+{
+ static void *security;
+ if (!security) {
+ if (!(security = dlopen(security_framework, RTLD_LAZY)))
+ die(_("dlopen(\"%s\") failed: %s"),
+ security_framework, dlerror());
+ }
+ return security;
+}
+"""
+
+func_tmpl = """
+%(func_decl)s
+{
+ %(func_rv)s (*func)(%(arg_types)s) =
+ dlsym(load_security(), "%(func_name)s");
+ if (!func)
+ die(_("dlsym(%(func_name)s) failed: %%s"), dlerror());
+ return func(%(arg_names)s);
+}
+"""
+
+def generate_func(decl):
+ func_rv, func_name, func_args = re.search(
+ r'^(.*?)\s+([^(]+)\((.*)\);$', decl).groups()
+ func_args = [s.strip() for s in func_args.split(',')]
+ arg_types = []
+ arg_names = []
+ for arg in func_args:
+ arg_type, arg_name = re.search(r'^(.*?)([a-zA-Z]+)$', arg).groups()
+ arg_types.append(arg_type.strip())
+ arg_names.append(arg_name.strip())
+ return func_tmpl % dict(
+ func_decl=decl.rstrip(';'),
+ func_name=func_name,
+ func_rv=func_rv,
+ arg_types=', '.join(arg_types),
+ arg_names=', '.join(arg_names),
+ )
+
+def main():
+ f = open('security.c', 'w')
+ f.write(header)
+ for decl in func_decls.splitlines():
+ decl = decl.strip()
+ if decl:
+ f.write(generate_func(decl))
+ f.close()
+
+if __name__ == '__main__':
+ main()
--
1.7.7.rc1.1.g011e1
next prev parent reply other threads:[~2011-09-14 22:55 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-14 17:58 [PATCH] contrib: add a credential helper for Mac OS X's keychain Jay Soffian
2011-09-14 18:19 ` Jay Soffian
2011-09-14 22:55 ` Jay Soffian [this message]
2011-09-14 23:08 ` [PATCH] credential-osxkeychain: load Security framework dynamically Jeff King
2011-09-14 23:56 ` Jay Soffian
2011-09-15 0:16 ` Jeff King
2011-09-14 23:18 ` 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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1316040926-89429-1-git-send-email-jaysoffian@gmail.com \
--to=jaysoffian@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=john@szakmeister.net \
--cc=peff@peff.net \
/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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.