git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] contrib: add win32 credential-helper
@ 2012-04-19 18:45 Erik Faye-Lund
  2012-04-22 18:07 ` Jeff King
  2012-04-24 20:40 ` Jeff King
  0 siblings, 2 replies; 6+ messages in thread
From: Erik Faye-Lund @ 2012-04-19 18:45 UTC (permalink / raw)
  To: git; +Cc: msysgit, peff

Since the Windows port of Git expects binary pipes, we need to make
sure the helper-end also sets up binary pipes.

Side-step CRLF-issue in test to make it pass.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
---

Here's an updated version of my Windows credential-helper.

The most important difference is that it doesn't suck as much as
it used to ;)

Basically, I'm now using the attribute-system to store the meta-data
for the credentials.

This passes the test for me, and seems to work OK.

 contrib/credential/wincred/Makefile                |    8 +
 .../credential/wincred/git-credential-wincred.c    |  352 ++++++++++++++++++++
 t/lib-credential.sh                                |    4 +
 3 files changed, 364 insertions(+), 0 deletions(-)
 create mode 100644 contrib/credential/wincred/Makefile
 create mode 100644 contrib/credential/wincred/git-credential-wincred.c

diff --git a/contrib/credential/wincred/Makefile b/contrib/credential/wincred/Makefile
new file mode 100644
index 0000000..b4f098f
--- /dev/null
+++ b/contrib/credential/wincred/Makefile
@@ -0,0 +1,8 @@
+all: git-credential-wincred.exe
+
+CC = gcc
+RM = rm -f
+CFLAGS = -O2 -Wall
+
+git-credential-wincred.exe : git-credential-wincred.c
+	$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
new file mode 100644
index 0000000..e63575f
--- /dev/null
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -0,0 +1,352 @@
+/*
+ * A git credential helper that interface with Windows' Credential Manager
+ *
+ */
+#include <windows.h>
+#include <stdio.h>
+#include <io.h>
+#include <fcntl.h>
+
+/* common helpers */
+
+static void die(const char *err, ...)
+{
+	char msg[4096];
+	va_list params;
+	va_start(params, err);
+	vsnprintf(msg, sizeof(msg), err, params);
+	fprintf(stderr, "%s\n", msg);
+	va_end(params);
+	exit(1);
+}
+
+static void *xmalloc(size_t size)
+{
+	void *ret = malloc(size);
+	if (!ret && !size)
+		ret = malloc(1);
+	if (!ret)
+		 die("Out of memory");
+	return ret;
+}
+
+static char *xstrdup(const char *str)
+{
+	char *ret = strdup(str);
+	if (!ret)
+		die("Out of memory");
+	return ret;
+}
+
+/* MinGW doesn't have wincred.h, so we need to define stuff */
+
+typedef struct _CREDENTIAL_ATTRIBUTEW {
+	LPWSTR Keyword;
+	DWORD  Flags;
+	DWORD  ValueSize;
+	LPBYTE Value;
+} CREDENTIAL_ATTRIBUTEW, *PCREDENTIAL_ATTRIBUTEW;
+
+typedef struct _CREDENTIALW {
+	DWORD                  Flags;
+	DWORD                  Type;
+	LPWSTR                 TargetName;
+	LPWSTR                 Comment;
+	FILETIME               LastWritten;
+	DWORD                  CredentialBlobSize;
+	LPBYTE                 CredentialBlob;
+	DWORD                  Persist;
+	DWORD                  AttributeCount;
+	PCREDENTIAL_ATTRIBUTEW Attributes;
+	LPWSTR                 TargetAlias;
+	LPWSTR                 UserName;
+} CREDENTIALW, *PCREDENTIALW;
+
+#define CRED_TYPE_GENERIC 1
+#define CRED_PERSIST_LOCAL_MACHINE 2
+#define CRED_MAX_ATTRIBUTES 64
+
+typedef BOOL (WINAPI *CredWriteWT)(PCREDENTIALW, DWORD);
+typedef BOOL (WINAPI *CredUnPackAuthenticationBufferWT)(DWORD, PVOID, DWORD,
+    LPWSTR, DWORD *, LPWSTR, DWORD *, LPWSTR, DWORD *);
+typedef BOOL (WINAPI *CredEnumerateWT)(LPCWSTR, DWORD, DWORD *,
+    PCREDENTIALW **);
+typedef BOOL (WINAPI *CredPackAuthenticationBufferWT)(DWORD, LPWSTR, LPWSTR,
+    PBYTE, DWORD *);
+typedef VOID (WINAPI *CredFreeT)(PVOID);
+typedef BOOL (WINAPI *CredDeleteWT)(LPCWSTR, DWORD, DWORD);
+
+static HMODULE advapi, credui;
+static CredWriteWT CredWriteW;
+static CredUnPackAuthenticationBufferWT CredUnPackAuthenticationBufferW;
+static CredEnumerateWT CredEnumerateW;
+static CredPackAuthenticationBufferWT CredPackAuthenticationBufferW;
+static CredFreeT CredFree;
+static CredDeleteWT CredDeleteW;
+
+static void load_cred_funcs(void)
+{
+	/* load DLLs */
+	advapi = LoadLibrary("advapi32.dll");
+	credui = LoadLibrary("credui.dll");
+	if (!advapi || !credui)
+		die("failed to load DLLs");
+
+	/* get function pointers */
+	CredWriteW = (CredWriteWT)GetProcAddress(advapi, "CredWriteW");
+	CredUnPackAuthenticationBufferW = (CredUnPackAuthenticationBufferWT)
+	    GetProcAddress(credui, "CredUnPackAuthenticationBufferW");
+	CredEnumerateW = (CredEnumerateWT)GetProcAddress(advapi,
+	    "CredEnumerateW");
+	CredPackAuthenticationBufferW = (CredPackAuthenticationBufferWT)
+	    GetProcAddress(credui, "CredPackAuthenticationBufferW");
+	CredFree = (CredFreeT)GetProcAddress(advapi, "CredFree");
+	CredDeleteW = (CredDeleteWT)GetProcAddress(advapi, "CredDeleteW");
+	if (!CredWriteW || !CredUnPackAuthenticationBufferW ||
+	    !CredEnumerateW || !CredPackAuthenticationBufferW || !CredFree ||
+	    !CredDeleteW)
+		die("failed to load functions");
+}
+
+static char target_buf[1024];
+static char *protocol, *host, *path, *username;
+static WCHAR *wusername, *password, *target;
+
+static void write_item(const char *what, WCHAR *wbuf)
+{
+	char *buf;
+	int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, NULL, 0, NULL,
+	    FALSE);
+	buf = xmalloc(len);
+
+	if (!WideCharToMultiByte(CP_UTF8, 0, wbuf, -1, buf, len, NULL, FALSE))
+		die("WideCharToMultiByte failed!");
+
+	printf("%s=", what);
+	fwrite(buf, 1, len - 1, stdout);
+	putchar('\n');
+	free(buf);
+}
+
+static int match_attr(const CREDENTIALW *cred, const WCHAR *keyword,
+    const char *want)
+{
+	int i;
+	if (!want)
+		return 1;
+
+	for (i = 0; i < cred->AttributeCount; ++i)
+		if (!wcscmp(cred->Attributes[i].Keyword, keyword))
+			return !strcmp((const char *)cred->Attributes[i].Value,
+			    want);
+
+	return 0; /* not found */
+}
+
+static int match_cred(const CREDENTIALW *cred)
+{
+	return (!wusername || !wcscmp(wusername, cred->UserName)) &&
+	    match_attr(cred, L"git_protocol", protocol) &&
+	    match_attr(cred, L"git_host", host) &&
+	    match_attr(cred, L"git_path", path);
+}
+
+static void get_credential(void)
+{
+	WCHAR *user_buf, *pass_buf;
+	DWORD user_buf_size = 0, pass_buf_size = 0;
+	CREDENTIALW **creds, *cred = NULL;
+	DWORD num_creds;
+	int i;
+
+	if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds))
+		return;
+
+	/* search for the first credential that matches username */
+	for (i = 0; i < num_creds; ++i)
+		if (match_cred(creds[i])) {
+			cred = creds[i];
+			break;
+		}
+	if (!cred)
+		return;
+
+	CredUnPackAuthenticationBufferW(0, cred->CredentialBlob,
+	    cred->CredentialBlobSize, NULL, &user_buf_size, NULL, NULL,
+	    NULL, &pass_buf_size);
+
+	user_buf = xmalloc(user_buf_size * sizeof(WCHAR));
+	pass_buf = xmalloc(pass_buf_size * sizeof(WCHAR));
+
+	if (!CredUnPackAuthenticationBufferW(0, cred->CredentialBlob,
+	    cred->CredentialBlobSize, user_buf, &user_buf_size, NULL, NULL,
+	    pass_buf, &pass_buf_size))
+		die("CredUnPackAuthenticationBuffer failed");
+
+	CredFree(creds);
+
+	/* zero-terminate (sizes include zero-termination) */
+	user_buf[user_buf_size - 1] = L'\0';
+	pass_buf[pass_buf_size - 1] = L'\0';
+
+	write_item("username", user_buf);
+	write_item("password", pass_buf);
+
+	free(user_buf);
+	free(pass_buf);
+}
+
+static void write_attr(CREDENTIAL_ATTRIBUTEW *attr, const WCHAR *keyword,
+    const char *value)
+{
+	attr->Keyword = (LPWSTR)keyword;
+	attr->Flags = 0;
+	attr->ValueSize = strlen(value) + 1; /* store zero-termination */
+	attr->Value = (LPBYTE)value;
+}
+
+static void store_credential(void)
+{
+	CREDENTIALW cred;
+	BYTE *auth_buf;
+	DWORD auth_buf_size = 0;
+	CREDENTIAL_ATTRIBUTEW attrs[CRED_MAX_ATTRIBUTES];
+
+	if (!wusername || !password)
+		return;
+
+	/* query buffer size */
+	CredPackAuthenticationBufferW(0, wusername, password,
+	    NULL, &auth_buf_size);
+
+	auth_buf = xmalloc(auth_buf_size);
+
+	if (!CredPackAuthenticationBufferW(0, wusername, password,
+	    auth_buf, &auth_buf_size))
+		die("CredPackAuthenticationBuffer failed");
+
+	cred.Flags = 0;
+	cred.Type = CRED_TYPE_GENERIC;
+	cred.TargetName = target;
+	cred.Comment = L"saved by git-credential-wincred";
+	cred.CredentialBlobSize = auth_buf_size;
+	cred.CredentialBlob = auth_buf;
+	cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
+	cred.AttributeCount = 2;
+	cred.Attributes = attrs;
+	cred.TargetAlias = NULL;
+	cred.UserName = wusername;
+
+	write_attr(attrs, L"git_protocol", protocol);
+	write_attr(attrs + 1, L"git_host", host);
+
+	if (path) {
+		write_attr(attrs + 2, L"git_path", path);
+		cred.AttributeCount++;
+	}
+
+	if (!CredWriteW(&cred, 0))
+		die("CredWrite failed");
+}
+
+static void erase_credential(void)
+{
+	CREDENTIALW **creds;
+	DWORD num_creds;
+	int i;
+
+	if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds))
+		return;
+
+	for (i = 0; i < num_creds; ++i) {
+		if (match_cred(creds[i]))
+			CredDeleteW(creds[i]->TargetName, creds[i]->Type, 0);
+	}
+
+	CredFree(creds);
+}
+
+static WCHAR *utf8_to_utf16_dup(const char *str)
+{
+	int wlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
+	WCHAR *wstr = xmalloc(sizeof(WCHAR) * wlen);
+	MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, wlen);
+	return wstr;
+}
+
+static void read_credential(void)
+{
+	char buf[1024];
+
+	while (fgets(buf, sizeof(buf), stdin)) {
+		char *v;
+
+		if (!strcmp(buf, "\n"))
+			break;
+		buf[strlen(buf)-1] = '\0';
+
+		v = strchr(buf, '=');
+		if (!v)
+			die("bad input: %s", buf);
+		*v++ = '\0';
+
+		if (!strcmp(buf, "protocol"))
+			protocol = xstrdup(v);
+		else if (!strcmp(buf, "host"))
+			host = xstrdup(v);
+		else if (!strcmp(buf, "path"))
+			path = xstrdup(v);
+		else if (!strcmp(buf, "username")) {
+			username = xstrdup(v);
+			wusername = utf8_to_utf16_dup(v);
+		} else if (!strcmp(buf, "password"))
+			password = utf8_to_utf16_dup(v);
+		else
+			die("unrecognized input");
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	const char *usage =
+	    "Usage: git credential-wincred <get|store|erase>\n";
+
+	if (!argv[1])
+		die(usage);
+
+	/* git use binary pipes to avoid CRLF-issues */
+	_setmode(_fileno(stdin), _O_BINARY);
+	_setmode(_fileno(stdout), _O_BINARY);
+
+	read_credential();
+
+	load_cred_funcs();
+
+	if (!protocol || !host)
+		return 0;
+
+	/* prepare 'target', the unique key for the credential */
+	strncat(target_buf, "git:", sizeof(target_buf));
+	strncat(target_buf, protocol, sizeof(target_buf));
+	strncat(target_buf, "://", sizeof(target_buf));
+	if (username) {
+		strncat(target_buf, username, sizeof(target_buf));
+		strncat(target_buf, "@", sizeof(target_buf));
+	}
+	strncat(target_buf, host, sizeof(target_buf));
+	if (path) {
+		strncat(target_buf, "/", sizeof(target_buf));
+		strncat(target_buf, path, sizeof(target_buf));
+	}
+
+	target = utf8_to_utf16_dup(target_buf);
+
+	if (!strcmp(argv[1], "get"))
+		get_credential();
+	else if (!strcmp(argv[1], "store"))
+		store_credential();
+	else if (!strcmp(argv[1], "erase"))
+		erase_credential();
+	/* otherwise, ignore unknown action */
+	return 0;
+}
diff --git a/t/lib-credential.sh b/t/lib-credential.sh
index 4a37cd7..d30ae8a 100755
--- a/t/lib-credential.sh
+++ b/t/lib-credential.sh
@@ -8,6 +8,10 @@ check() {
 	read_chunk >expect-stdout &&
 	read_chunk >expect-stderr &&
 	test-credential "$@" <stdin >stdout 2>stderr &&
+	if test_have_prereq MINGW
+	then
+		dos2unix -q stderr
+	fi &&
 	test_cmp expect-stdout stdout &&
 	test_cmp expect-stderr stderr
 }
-- 
1.7.9

-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***

*** Please avoid top-posting. ***

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] contrib: add win32 credential-helper
  2012-04-19 18:45 [PATCH v2] contrib: add win32 credential-helper Erik Faye-Lund
@ 2012-04-22 18:07 ` Jeff King
  2012-04-23 16:05   ` Erik Faye-Lund
  2012-04-24 20:40 ` Jeff King
  1 sibling, 1 reply; 6+ messages in thread
From: Jeff King @ 2012-04-22 18:07 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: git, msysgit

On Thu, Apr 19, 2012 at 08:45:22PM +0200, Erik Faye-Lund wrote:

> Here's an updated version of my Windows credential-helper.

Sorry, I've been traveling and haven't had a chance to look at this
in-depth yet. I'll do so next week. In the meantime, I wanted to point
out this similar project:

  https://github.com/anurse/git-credential-winstore

which somebody else pointed me to a few days ago. I don't know yet if
your approaches are the same, or if it would be worth combining efforts
or not.

-Peff

-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***

*** Please avoid top-posting. ***

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] contrib: add win32 credential-helper
  2012-04-22 18:07 ` Jeff King
@ 2012-04-23 16:05   ` Erik Faye-Lund
  2012-04-24 20:21     ` Jeff King
  0 siblings, 1 reply; 6+ messages in thread
From: Erik Faye-Lund @ 2012-04-23 16:05 UTC (permalink / raw)
  To: Jeff King; +Cc: git, msysgit

On Sun, Apr 22, 2012 at 8:07 PM, Jeff King <peff@peff.net> wrote:
> On Thu, Apr 19, 2012 at 08:45:22PM +0200, Erik Faye-Lund wrote:
>
>> Here's an updated version of my Windows credential-helper.
>
> Sorry, I've been traveling and haven't had a chance to look at this
> in-depth yet. I'll do so next week. In the meantime, I wanted to point
> out this similar project:
>
>  https://github.com/anurse/git-credential-winstore
>
> which somebody else pointed me to a few days ago. I don't know yet if
> your approaches are the same, or if it would be worth combining efforts
> or not.

Yeah, I saw that one a couple of days ago myself.

They use the same credential store, and I actually tried to make sure
they can use the same data.

But apart from that, they work quite differently. My credential-helper
only does storage, and passes the test-suite. The one you linked to
seems to ignore any password being sent to it, and instead prompts the
user if it doesn't already have a credential. It also does not seem to
support storing credentials for multiple users for a domain/path.

But probably the biggest problem for Git for Windows is that it's
written in C#, and we don't have a C# compiler in our tool-chain.

So I don't think there's much I can use from that helper, and I think
my helper is in a healthier state. But I'm obviously biased.

-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***

*** Please avoid top-posting. ***

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] contrib: add win32 credential-helper
  2012-04-23 16:05   ` Erik Faye-Lund
@ 2012-04-24 20:21     ` Jeff King
  0 siblings, 0 replies; 6+ messages in thread
From: Jeff King @ 2012-04-24 20:21 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: git, msysgit

On Mon, Apr 23, 2012 at 06:05:57PM +0200, Erik Faye-Lund wrote:

> > Sorry, I've been traveling and haven't had a chance to look at this
> > in-depth yet. I'll do so next week. In the meantime, I wanted to point
> > out this similar project:
> >
> >  https://github.com/anurse/git-credential-winstore
> [...]
> But probably the biggest problem for Git for Windows is that it's
> written in C#, and we don't have a C# compiler in our tool-chain.

Yeah, that seems like a big one. I think it would be awesome if msysgit
could eventually ship with a credential helper, without people needing
to grab something externally.

-Peff

-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***

*** Please avoid top-posting. ***

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] contrib: add win32 credential-helper
  2012-04-19 18:45 [PATCH v2] contrib: add win32 credential-helper Erik Faye-Lund
  2012-04-22 18:07 ` Jeff King
@ 2012-04-24 20:40 ` Jeff King
  2012-06-22 16:29   ` Erik Faye-Lund
  1 sibling, 1 reply; 6+ messages in thread
From: Jeff King @ 2012-04-24 20:40 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: git, msysgit

On Thu, Apr 19, 2012 at 08:45:22PM +0200, Erik Faye-Lund wrote:

> Here's an updated version of my Windows credential-helper.
> 
> The most important difference is that it doesn't suck as much as
> it used to ;)
> 
> Basically, I'm now using the attribute-system to store the meta-data
> for the credentials.
> 
> This passes the test for me, and seems to work OK.

This looks much better. As usual, I can't comment on the Windows-y
parts, but the credential logic looks good. One minor comment:

> +int main(int argc, char *argv[])
> +{
> [...]
> +	if (!protocol || !host)
> +		return 0;

You could have a protocol that does not have a "host" component. Git
will produce this for a cached certificate password (which will then
always have a "path" field). I don't know if anybody is using it to
cache certificate passwords, and I admit that it is not very well tested
by me, either. So I'm not sure anybody will actually care.

The credential-store helper uses this logic:

  $ sed -n '70,79p' credential-store.c
        /*
         * Sanity check that what we are storing is actually sensible.
         * In particular, we can't make a URL without a protocol field.
         * Without either a host or pathname (depending on the scheme),
         * we have no primary key. And without a username and password,
         * we are not actually storing a credential.
         */
        if (!c->protocol || !(c->host || c->path) ||
            !c->username || !c->password)
                return;

I'm pretty sure the OS X helper does not handle certificate passwords at
all. It is harder there, because I map directly to native protocol
types, and I haven't checked to see whether OS X handles this type. But
since you are just storing whatever protocol information git hands you,
I think for you it is just a matter of letting it through (and handling
the "!host" case when writing).

-Peff

-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***

*** Please avoid top-posting. ***

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] contrib: add win32 credential-helper
  2012-04-24 20:40 ` Jeff King
@ 2012-06-22 16:29   ` Erik Faye-Lund
  0 siblings, 0 replies; 6+ messages in thread
From: Erik Faye-Lund @ 2012-06-22 16:29 UTC (permalink / raw)
  To: Jeff King; +Cc: git, msysgit

On Tue, Apr 24, 2012 at 10:40 PM, Jeff King <peff@peff.net> wrote:
> On Thu, Apr 19, 2012 at 08:45:22PM +0200, Erik Faye-Lund wrote:
>
>> Here's an updated version of my Windows credential-helper.
>>
>> The most important difference is that it doesn't suck as much as
>> it used to ;)
>>
>> Basically, I'm now using the attribute-system to store the meta-data
>> for the credentials.
>>
>> This passes the test for me, and seems to work OK.
>
> This looks much better. As usual, I can't comment on the Windows-y
> parts, but the credential logic looks good. One minor comment:
>
>> +int main(int argc, char *argv[])
>> +{
>> [...]
>> +     if (!protocol || !host)
>> +             return 0;
>
> You could have a protocol that does not have a "host" component. Git
> will produce this for a cached certificate password (which will then
> always have a "path" field). I don't know if anybody is using it to
> cache certificate passwords, and I admit that it is not very well tested
> by me, either. So I'm not sure anybody will actually care.
>
> The credential-store helper uses this logic:
>
>  $ sed -n '70,79p' credential-store.c
>        /*
>         * Sanity check that what we are storing is actually sensible.
>         * In particular, we can't make a URL without a protocol field.
>         * Without either a host or pathname (depending on the scheme),
>         * we have no primary key. And without a username and password,
>         * we are not actually storing a credential.
>         */
>        if (!c->protocol || !(c->host || c->path) ||
>            !c->username || !c->password)
>                return;
>
> I'm pretty sure the OS X helper does not handle certificate passwords at
> all. It is harder there, because I map directly to native protocol
> types, and I haven't checked to see whether OS X handles this type.

Right. I copied this logic from the OSX helper.

> But
> since you are just storing whatever protocol information git hands you,
> I think for you it is just a matter of letting it through (and handling
> the "!host" case when writing).

Yeah, I agree. This on top should do it:

diff --git a/contrib/credential/wincred/git-credential-wincred.c
b/contrib/credential/wincred/git-credential-wincred.c
index e63575f..cbaec5f 100644
--- a/contrib/credential/wincred/git-credential-wincred.c
+++ b/contrib/credential/wincred/git-credential-wincred.c
@@ -232,16 +232,20 @@ static void store_credential(void)
 	cred.CredentialBlobSize = auth_buf_size;
 	cred.CredentialBlob = auth_buf;
 	cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
-	cred.AttributeCount = 2;
+	cred.AttributeCount = 1;
 	cred.Attributes = attrs;
 	cred.TargetAlias = NULL;
 	cred.UserName = wusername;

 	write_attr(attrs, L"git_protocol", protocol);
-	write_attr(attrs + 1, L"git_host", host);
+
+	if (host) {
+		write_attr(attrs + cred.AttributeCount, L"git_host", host);
+		cred.AttributeCount++;
+	}

 	if (path) {
-		write_attr(attrs + 2, L"git_path", path);
+		write_attr(attrs + cred.AttributeCount, L"git_path", path);
 		cred.AttributeCount++;
 	}

@@ -322,7 +326,7 @@ int main(int argc, char *argv[])

 	load_cred_funcs();

-	if (!protocol || !host)
+	if (!protocol || !(host || path))
 		return 0;

 	/* prepare 'target', the unique key for the credential */
@@ -333,7 +337,8 @@ int main(int argc, char *argv[])
 		strncat(target_buf, username, sizeof(target_buf));
 		strncat(target_buf, "@", sizeof(target_buf));
 	}
-	strncat(target_buf, host, sizeof(target_buf));
+	if (host)
+		strncat(target_buf, host, sizeof(target_buf));
 	if (path) {
 		strncat(target_buf, "/", sizeof(target_buf));
 		strncat(target_buf, path, sizeof(target_buf));

-- 
*** Please reply-to-all at all times ***
*** (do not pretend to know who is subscribed and who is not) ***
*** Please avoid top-posting. ***
The msysGit Wiki is here: https://github.com/msysgit/msysgit/wiki - Github accounts are free.

You received this message because you are subscribed to the Google
Groups "msysGit" group.
To post to this group, send email to msysgit@googlegroups.com
To unsubscribe from this group, send email to
msysgit+unsubscribe@googlegroups.com
For more options, and view previous threads, visit this group at
http://groups.google.com/group/msysgit?hl=en_US?hl=en

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-06-22 16:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-19 18:45 [PATCH v2] contrib: add win32 credential-helper Erik Faye-Lund
2012-04-22 18:07 ` Jeff King
2012-04-23 16:05   ` Erik Faye-Lund
2012-04-24 20:21     ` Jeff King
2012-04-24 20:40 ` Jeff King
2012-06-22 16:29   ` Erik Faye-Lund

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 NNTP newsgroup(s).