All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] add lame win32 credential-helper
@ 2011-09-15 20:25 Erik Faye-Lund
  2011-09-15 21:40 ` Jeff King
  2011-09-30 14:42 ` Erik Faye-Lund
  0 siblings, 2 replies; 5+ messages in thread
From: Erik Faye-Lund @ 2011-09-15 20:25 UTC (permalink / raw)
  To: git; +Cc: jaysoffian, peff, gitster

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

I got curious what a credential-helper that uses Windows'
Credential Manager would look like; this is the result.

Some parts of the code is heavily inspired by Jay Soffian's
OSX-keychain work.

Not that it's useful yet, since the core-git code for the
credential-helper support doesn't compile on Windows. So
it's not fully tested, I've only read the interface
documentation and experimented with it from the command
line.

 contrib/credential-wincred/Makefile                |    8 +
 .../credential-wincred/git-credential-wincred.c    |  271 ++++++++++++++++++++
 2 files changed, 279 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..5c0e2d3
--- /dev/null
+++ b/contrib/credential-wincred/git-credential-wincred.c
@@ -0,0 +1,271 @@
+#include <windows.h>
+#include <stdio.h>
+
+/* MinGW doesn't have wincred.h, let's extract the stuff we need instead */
+
+typedef struct _CREDENTIAL_ATTRIBUTE {
+	LPWSTR Keyword;
+	DWORD  Flags;
+	DWORD  ValueSize;
+	LPBYTE Value;
+} CREDENTIAL_ATTRIBUTE, *PCREDENTIAL_ATTRIBUTE;
+
+typedef struct _CREDENTIALW {
+	DWORD                 Flags;
+	DWORD                 Type;
+	LPWSTR                TargetName;
+	LPWSTR                Comment;
+	FILETIME              LastWritten;
+	DWORD                 CredentialBlobSize;
+	LPBYTE                CredentialBlob;
+	DWORD                 Persist;
+	DWORD                 AttributeCount;
+	PCREDENTIAL_ATTRIBUTE Attributes;
+	LPWSTR                TargetAlias;
+	LPWSTR                UserName;
+} CREDENTIALW, *PCREDENTIALW;
+
+typedef struct _CREDUI_INFOW {
+	DWORD   cbSize;
+	HWND    hwndParent;
+	LPWSTR  pszMessageText;
+	LPWSTR  pszCaptionText;
+	HBITMAP hbmBanner;
+} CREDUI_INFOW, *PCREDUI_INFOW;
+
+#define CRED_TYPE_GENERIC 1
+#define CRED_PERSIST_LOCAL_MACHINE 2
+#define CREDUIWIN_GENERIC 1
+#define CREDUIWIN_CHECKBOX 2
+#define CREDUIWIN_IN_CRED_ONLY 32
+#define CRED_PACK_GENERIC_CREDENTIALS 4
+
+
+typedef BOOL (WINAPI *CredWriteWT)(PCREDENTIALW, DWORD);
+typedef BOOL (WINAPI *CredUnPackAuthenticationBufferWT)(DWORD, PVOID, DWORD,
+    LPWSTR, DWORD *, LPWSTR, DWORD *, LPWSTR, DWORD *);
+typedef DWORD (WINAPI *CredUIPromptForWindowsCredentialsWT)(PCREDUI_INFOW,
+    DWORD, ULONG *, LPCVOID, ULONG, LPVOID *, ULONG *, BOOL *, 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 CredUIPromptForWindowsCredentialsWT CredUIPromptForWindowsCredentialsW;
+static CredEnumerateWT CredEnumerateW;
+static CredPackAuthenticationBufferWT CredPackAuthenticationBufferW;
+static CredFreeT CredFree;
+static CredDeleteWT CredDeleteW;
+
+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 emit_user_pass(WCHAR *username, WCHAR *password)
+{
+	if (username)
+		wprintf(L"username=%s\n", username);
+	if (password)
+		wprintf(L"password=%s\n", password);
+}
+
+static int find_credentials(WCHAR *target, WCHAR *username)
+{
+	WCHAR user_buf[256], pass_buf[256];
+	DWORD user_buf_size = sizeof(user_buf) - 1,
+	      pass_buf_size = sizeof(pass_buf) - 1;
+	CREDENTIALW **creds, *cred = NULL;
+	DWORD num_creds;
+
+	if (!CredEnumerateW(target, 0, &num_creds, &creds))
+		return -1;
+
+	if (!username) {
+		/* no username was specified, just pick the first one */
+		cred = creds[0];
+	} else {
+		/* search for the first credential that matches username */
+		int i;
+		for (i = 0; i < num_creds; ++i)
+			if (!wcscmp(username, creds[i]->UserName)) {
+				cred = creds[i];
+				break;
+			}
+		if (!cred)
+			return -1;
+	}
+
+	if (!CredUnPackAuthenticationBufferW(0, cred->CredentialBlob,
+	    cred->CredentialBlobSize, user_buf, &user_buf_size, NULL, NULL,
+	    pass_buf, &pass_buf_size))
+		return -1;
+
+	CredFree(creds);
+
+	/* zero terminate */
+	user_buf[user_buf_size] = L'\0';
+	pass_buf[pass_buf_size] = L'\0';
+
+	emit_user_pass(user_buf, pass_buf);
+	return 0;
+}
+
+/* also saves the credentials if the user tells it to */
+static int ask_credentials(WCHAR *target, WCHAR *comment, WCHAR *username)
+{
+	BOOL save = FALSE;
+	LPVOID auth_buf = NULL;
+	ULONG auth_buf_size = 0;
+	WCHAR user_buf[256], pass_buf[256];
+	DWORD user_buf_size = sizeof(user_buf) - 1,
+	      pass_buf_size = sizeof(pass_buf) - 1;
+	BYTE in_buf[1024];
+	DWORD in_buf_size = sizeof(in_buf);
+	DWORD err;
+	ULONG package = 0;
+	CREDUI_INFOW info = {
+		sizeof(info), NULL,
+		comment ? comment : target, L"Enter password", NULL
+	};
+
+	if (username)
+		CredPackAuthenticationBufferW(0, username, L"",
+		    in_buf, &in_buf_size);
+	err = CredUIPromptForWindowsCredentialsW(&info, 0, &package,
+	    in_buf, in_buf_size, &auth_buf, &auth_buf_size,
+	    &save, CREDUIWIN_GENERIC | CREDUIWIN_CHECKBOX);
+	if (err == ERROR_CANCELLED)
+		return 0;
+	if (err != ERROR_SUCCESS)
+		return -1;
+
+	if (!CredUnPackAuthenticationBufferW(0, auth_buf, auth_buf_size,
+	    user_buf, &user_buf_size, NULL, NULL,
+	    pass_buf, &pass_buf_size))
+		return -1;
+
+	/* zero terminate */
+	user_buf[user_buf_size] = L'\0';
+	pass_buf[pass_buf_size] = L'\0';
+
+	emit_user_pass(user_buf, pass_buf);
+
+	if (save) {
+		CREDENTIALW cred;
+		cred.Flags = 0;
+		cred.Type = CRED_TYPE_GENERIC;
+		cred.TargetName = target;
+		cred.Comment = comment;
+		cred.CredentialBlobSize = auth_buf_size;
+		cred.CredentialBlob = auth_buf;
+		cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
+		cred.AttributeCount = 0;
+		cred.Attributes = NULL;
+		cred.TargetAlias = NULL;
+		cred.UserName = user_buf;
+		if (!CredWriteW(&cred, 0))
+			fprintf(stderr, "failed to write credentials\n");
+	}
+	return 0;
+}
+
+static void delete_credentials(WCHAR *target, WCHAR *username)
+{
+	WCHAR temp[4096];
+
+	wcscpy(temp, target);
+	if (username) {
+		wcscat(temp, L"|");
+		wcscat(temp, username);
+	}
+	if (!CredDeleteW(target, CRED_TYPE_GENERIC, 0))
+		die("failed to delete credentials");
+}
+
+int main(int argc, char *argv[])
+{
+	const char *usage =
+	    "Usage: git credential-osxkeychain --unique=TOKEN [options]\n"
+	    "Options:\n"
+	    "    --description=DESCRIPTION\n"
+	    "    --username=USERNAME\n"
+	    "    --reject";
+	WCHAR desc_buf[4096], *description = NULL,
+	      user_buf[256], *username = NULL,
+	      unique_buf[1024], *unique = NULL;
+	int i, reject = 0;
+
+	for (i = 1; i < argc; ++i) {
+		const char *arg = argv[i];
+		if (!strncmp(arg, "--description=", 14)) {
+			MultiByteToWideChar(CP_UTF8, 0, arg + 14, -1,
+			    desc_buf, sizeof(desc_buf));
+			description = desc_buf;
+		} else if (!strncmp(arg, "--username=", 11)) {
+			MultiByteToWideChar(CP_UTF8, 0, arg + 11, -1,
+			    user_buf, sizeof(user_buf));
+			username = user_buf;
+		} else if (!strncmp(arg, "--unique=", 9)) {
+			MultiByteToWideChar(CP_UTF8, 0, arg + 9, -1,
+			    unique_buf, sizeof(unique_buf));
+			unique = unique_buf;
+		} else if (!strcmp(arg, "--reject")) {
+			reject = 1;
+		} else if (!strcmp(arg, "--help")) {
+			die(usage);
+		} else
+			die("Unrecognized argument `%s'; try --help", arg);
+	}
+
+	if (!unique)
+		die("Must specify --unique=TOKEN; try --help");
+
+	/* 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");
+	CredUIPromptForWindowsCredentialsW =
+	    (CredUIPromptForWindowsCredentialsWT)GetProcAddress(credui,
+	    "CredUIPromptForWindowsCredentialsW");
+	CredEnumerateW = (CredEnumerateWT)GetProcAddress(advapi,
+	    "CredEnumerateW");
+	CredPackAuthenticationBufferW = (CredPackAuthenticationBufferWT)
+	    GetProcAddress(credui, "CredPackAuthenticationBufferW");
+	CredFree = (CredFreeT)GetProcAddress(advapi, "CredFree");
+	CredDeleteW = (CredDeleteWT)GetProcAddress(advapi, "CredDeleteW");
+	if (!CredWriteW || !CredUnPackAuthenticationBufferW ||
+	    !CredUIPromptForWindowsCredentialsW || !CredEnumerateW ||
+	    !CredPackAuthenticationBufferW || !CredFree || !CredDeleteW)
+		die("failed to load functions");
+
+	if (reject) {
+		delete_credentials(unique, username);
+		return 0;
+	}
+
+	if (!find_credentials(unique, username))
+		return 0;
+
+	if (!ask_credentials(unique, description, username))
+		return 0;
+
+	return -1;
+}
-- 
1.7.6.355.g842ba.dirty

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

* Re: [PATCH/RFC] add lame win32 credential-helper
  2011-09-15 20:25 [PATCH/RFC] add lame win32 credential-helper Erik Faye-Lund
@ 2011-09-15 21:40 ` Jeff King
  2011-09-15 21:48   ` Erik Faye-Lund
  2011-09-30 14:42 ` Erik Faye-Lund
  1 sibling, 1 reply; 5+ messages in thread
From: Jeff King @ 2011-09-15 21:40 UTC (permalink / raw)
  To: Erik Faye-Lund; +Cc: git, jaysoffian, gitster

On Thu, Sep 15, 2011 at 10:25:24PM +0200, Erik Faye-Lund wrote:

> Not that it's useful yet, since the core-git code for the
> credential-helper support doesn't compile on Windows. So
> it's not fully tested, I've only read the interface
> documentation and experimented with it from the command
> line.

Which parts of the credential-helper code don't compile? I wouldn't be
surprised if the cache helper doesn't work (because it uses unix domain
sockets for communication). If it's too hard to adapt it to whatever IPC
mechanism would be appropriate on Windows, we can just leave it out on
that platform.

But the core code in git itself should be pretty straight forward. Let
me know what I can do to help.

-Peff

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

* Re: [PATCH/RFC] add lame win32 credential-helper
  2011-09-15 21:40 ` Jeff King
@ 2011-09-15 21:48   ` Erik Faye-Lund
  2011-09-16 12:59     ` Stephen Bash
  0 siblings, 1 reply; 5+ messages in thread
From: Erik Faye-Lund @ 2011-09-15 21:48 UTC (permalink / raw)
  To: Jeff King; +Cc: git, jaysoffian, gitster

On Thu, Sep 15, 2011 at 11:40 PM, Jeff King <peff@peff.net> wrote:
> On Thu, Sep 15, 2011 at 10:25:24PM +0200, Erik Faye-Lund wrote:
>
>> Not that it's useful yet, since the core-git code for the
>> credential-helper support doesn't compile on Windows. So
>> it's not fully tested, I've only read the interface
>> documentation and experimented with it from the command
>> line.
>
> Which parts of the credential-helper code don't compile? I wouldn't be
> surprised if the cache helper doesn't work (because it uses unix domain
> sockets for communication).

That's exactly it:

unix-socket.c:12: warning: 'struct sockaddr_un' declared inside parameter list
unix-socket.c:12: warning: its scope is only this definition or declaration, whi
ch is probably not what you want
unix-socket.c: In function 'unix_sockaddr_init':
unix-socket.c:15: error: dereferencing pointer to incomplete type
unix-socket.c:17: error: dereferencing pointer to incomplete type
unix-socket.c:18: error: dereferencing pointer to incomplete type
unix-socket.c:19: error: dereferencing pointer to incomplete type
unix-socket.c: In function 'unix_stream_connect':
unix-socket.c:25: error: storage size of 'sa' isn't known
unix-socket.c: In function 'unix_stream_listen':
unix-socket.c:39: error: storage size of 'sa' isn't known
make: *** [unix-socket.o] Error 1
make: *** Waiting for unfinished jobs....

> If it's too hard to adapt it to whatever IPC
> mechanism would be appropriate on Windows, we can just leave it out on
> that platform.
>
> But the core code in git itself should be pretty straight forward.

I didn't mean that it was impossible to port, just that it didn't compile
as-is. I haven't looked into fixing up the code so it compiles on Windows
again myself. And I'm not really planning to; I have little git-time these
days, and little knowledge of how unix-sockets works...

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

* Re: [PATCH/RFC] add lame win32 credential-helper
  2011-09-15 21:48   ` Erik Faye-Lund
@ 2011-09-16 12:59     ` Stephen Bash
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Bash @ 2011-09-16 12:59 UTC (permalink / raw)
  To: kusmabite; +Cc: git, jaysoffian, gitster, Jeff King

----- Original Message -----
> From: "Erik Faye-Lund" <kusmabite@gmail.com>
> To: "Jeff King" <peff@peff.net>
> Cc: git@vger.kernel.org, jaysoffian@gmail.com, gitster@pobox.com
> Sent: Thursday, September 15, 2011 5:48:30 PM
> Subject: Re: [PATCH/RFC] add lame win32 credential-helper
> 
> > If it's too hard to adapt it to whatever IPC
> > mechanism would be appropriate on Windows, we can just leave it out
> > on that platform.
> >
> > But the core code in git itself should be pretty straight forward.
> 
> I didn't mean that it was impossible to port, just that it didn't compile
> as-is. I haven't looked into fixing up the code so it compiles on Windows
> again myself. And I'm not really planning to; I have little git-time
> these days, and little knowledge of how unix-sockets works...

This may be common knowledge, but from our brief experiment with them last fall, Windows Named Pipes are fairly similar to Unix Domain Sockets (not named FIFOs as one would expect...).  We didn't quite get a perfect replacement using preprocessor macros, but I think you can get pretty close (we eventually dumped the idea in favor of straight TCP sockets that behave the same on all our platforms of interest).

HTH,
Stephen

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

* Re: [PATCH/RFC] add lame win32 credential-helper
  2011-09-15 20:25 [PATCH/RFC] add lame win32 credential-helper Erik Faye-Lund
  2011-09-15 21:40 ` Jeff King
@ 2011-09-30 14:42 ` Erik Faye-Lund
  1 sibling, 0 replies; 5+ messages in thread
From: Erik Faye-Lund @ 2011-09-30 14:42 UTC (permalink / raw)
  To: git; +Cc: jaysoffian, peff, gitster

On Thu, Sep 15, 2011 at 10:25 PM, Erik Faye-Lund <kusmabite@gmail.com> wrote:
> Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
> ---
>
> I got curious what a credential-helper that uses Windows'
> Credential Manager would look like; this is the result.
>
> Some parts of the code is heavily inspired by Jay Soffian's
> OSX-keychain work.
>
> Not that it's useful yet, since the core-git code for the
> credential-helper support doesn't compile on Windows. So
> it's not fully tested, I've only read the interface
> documentation and experimented with it from the command
> line.
>

...aaand with the following patch applied on top, it pass the
credential-helper test that peff wrote:

---8<---
Subject: [PATCH] fix helper to pass test

---
 .../credential-wincred/git-credential-wincred.c    |   87 +++++++++++---------
 1 files changed, 47 insertions(+), 40 deletions(-)

diff --git a/contrib/credential-wincred/git-credential-wincred.c
b/contrib/credential-wincred/git-credential-wincred.c
index 072c002..278dd80 100644
--- a/contrib/credential-wincred/git-credential-wincred.c
+++ b/contrib/credential-wincred/git-credential-wincred.c
@@ -84,31 +84,35 @@ static void emit_user_pass(WCHAR *username, WCHAR *password)
 		wprintf(L"password=%s\n", password);
 }

-static int find_credentials(WCHAR *target, WCHAR *username)
+static WCHAR *get_target(WCHAR *unique, WCHAR *username)
 {
+	static WCHAR target_buf[4096];
+	_snwprintf(target_buf, sizeof(target_buf), L"gitcred:%s:%s",
+	    unique, username);
+	return target_buf;
+}
+
+static int find_credentials(WCHAR *unique, WCHAR *username)
+{
+	int i;
 	WCHAR user_buf[256], pass_buf[256];
 	DWORD user_buf_size = sizeof(user_buf) - 1,
 	      pass_buf_size = sizeof(pass_buf) - 1;
 	CREDENTIALW **creds, *cred = NULL;
 	DWORD num_creds;

-	if (!CredEnumerateW(target, 0, &num_creds, &creds))
+	if (!CredEnumerateW(get_target(unique, username ? username : L"*"),
+	    0, &num_creds, &creds))
 		return -1;

-	if (!username) {
-		/* no username was specified, just pick the first one */
-		cred = creds[0];
-	} else {
-		/* search for the first credential that matches username */
-		int i;
-		for (i = 0; i < num_creds; ++i)
-			if (!wcscmp(username, creds[i]->UserName)) {
-				cred = creds[i];
-				break;
-			}
-		if (!cred)
-			return -1;
-	}
+	/* search for the first credential that matches username */
+	for (i = 0; i < num_creds; ++i)
+		if (!username || !wcscmp(username, creds[i]->UserName)) {
+			cred = creds[i];
+			break;
+		}
+	if (!cred)
+		return -1;

 	if (!CredUnPackAuthenticationBufferW(0, cred->CredentialBlob,
 	    cred->CredentialBlobSize, user_buf, &user_buf_size, NULL, NULL,
@@ -126,9 +130,9 @@ static int find_credentials(WCHAR *target, WCHAR *username)
 }

 /* also saves the credentials if the user tells it to */
-static int ask_credentials(WCHAR *target, WCHAR *comment, WCHAR *username)
+static int ask_credentials(WCHAR *unique, WCHAR *comment, WCHAR *username)
 {
-	BOOL save = FALSE;
+	BOOL save = unique != NULL;
 	LPVOID auth_buf = NULL;
 	ULONG auth_buf_size = 0;
 	WCHAR user_buf[256], pass_buf[256];
@@ -140,7 +144,7 @@ static int ask_credentials(WCHAR *target, WCHAR
*comment, WCHAR *username)
 	ULONG package = 0;
 	CREDUI_INFOW info = {
 		sizeof(info), NULL,
-		comment ? comment : target, L"Enter password", NULL
+		comment ? comment : unique, L"Enter password", NULL
 	};

 	if (username)
@@ -148,7 +152,7 @@ static int ask_credentials(WCHAR *target, WCHAR
*comment, WCHAR *username)
 		    in_buf, &in_buf_size);
 	err = CredUIPromptForWindowsCredentialsW(&info, 0, &package,
 	    in_buf, in_buf_size, &auth_buf, &auth_buf_size,
-	    &save, CREDUIWIN_GENERIC | CREDUIWIN_CHECKBOX);
+	    &save, CREDUIWIN_GENERIC | (unique ? CREDUIWIN_CHECKBOX : 0));
 	if (err == ERROR_CANCELLED)
 		return 0;
 	if (err != ERROR_SUCCESS)
@@ -169,7 +173,7 @@ static int ask_credentials(WCHAR *target, WCHAR
*comment, WCHAR *username)
 		CREDENTIALW cred;
 		cred.Flags = 0;
 		cred.Type = CRED_TYPE_GENERIC;
-		cred.TargetName = target;
+		cred.TargetName = get_target(unique, user_buf);
 		cred.Comment = comment;
 		cred.CredentialBlobSize = auth_buf_size;
 		cred.CredentialBlob = auth_buf;
@@ -184,17 +188,21 @@ static int ask_credentials(WCHAR *target, WCHAR
*comment, WCHAR *username)
 	return 0;
 }

-static void delete_credentials(WCHAR *target, WCHAR *username)
+static void delete_credentials(WCHAR *unique, WCHAR *username)
 {
-	WCHAR temp[4096];
+	int i;
+	CREDENTIALW **creds;
+	DWORD num_creds;

-	wcscpy(temp, target);
-	if (username) {
-		wcscat(temp, L"|");
-		wcscat(temp, username);
-	}
-	if (!CredDeleteW(target, CRED_TYPE_GENERIC, 0))
-		die("failed to delete credentials");
+	if (!CredEnumerateW(get_target(unique, username ? username : L"*"),
+	    0, &num_creds, &creds))
+		return;
+
+	for (i = 0; i < num_creds; ++i)
+		if (!CredDeleteW(get_target(unique, creds[i]->UserName),
+		    CRED_TYPE_GENERIC, 0))
+			die("failed to delete credentials");
+	CredFree(creds);
 }

 int main(int argc, char *argv[])
@@ -232,9 +240,6 @@ int main(int argc, char *argv[])
 			die("Unrecognized argument `%s'; try --help", arg);
 	}

-	if (!unique)
-		die("Must specify --unique=TOKEN; try --help");
-
 	/* load DLLs */
 	advapi = LoadLibrary("advapi32.dll");
 	credui = LoadLibrary("credui.dll");
@@ -256,16 +261,18 @@ int main(int argc, char *argv[])
 	CredDeleteW = (CredDeleteWT)GetProcAddress(advapi, "CredDeleteW");
 	if (!CredWriteW || !CredUnPackAuthenticationBufferW ||
 	    !CredUIPromptForWindowsCredentialsW || !CredEnumerateW ||
-	    !CredPackAuthenticationBufferW || !CredFree || !CredDeleteW)
+	    !CredFree || !CredPackAuthenticationBufferW || !CredDeleteW)
 		die("failed to load functions");

-	if (reject) {
-		delete_credentials(unique, username);
-		return 0;
-	}
+	if (unique) {
+		if (reject) {
+			delete_credentials(unique, username);
+			return 0;
+		}

-	if (!find_credentials(unique, username))
-		return 0;
+		if (!find_credentials(unique, username))
+			return 0;
+	}

 	if (!ask_credentials(unique, description, username))
 		return 0;
-- 
1.7.7.rc0.257.g9fefc
---8<---

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

end of thread, other threads:[~2011-09-30 14:43 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-15 20:25 [PATCH/RFC] add lame win32 credential-helper Erik Faye-Lund
2011-09-15 21:40 ` Jeff King
2011-09-15 21:48   ` Erik Faye-Lund
2011-09-16 12:59     ` Stephen Bash
2011-09-30 14:42 ` Erik Faye-Lund

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.