wincred: handle empty username/password correctly
authorJakub Bereżański <kuba@berezanscy.pl>
Mon, 30 Oct 2017 17:20:44 +0000 (18:20 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 1 Nov 2017 04:46:39 +0000 (13:46 +0900)
Empty (length 0) usernames and/or passwords, when saved in the Windows
Credential Manager, come back as null when reading the credential.

One use case for such empty credentials is with NTLM authentication, where
empty username and password instruct libcurl to authenticate using the
credentials of the currently logged-on user (single sign-on).

When locating the relevant credentials, make empty username match null.
When outputting the credentials, handle nulls correctly.

Signed-off-by: Jakub Bereżański <kuba@berezanscy.pl>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
contrib/credential/wincred/git-credential-wincred.c
index 006134043a472edd54720d6d4237e9484476d3a3..86518cd93d9c58d8b9f02d7cb8a67adf7b3fb3b6 100644 (file)
@@ -94,6 +94,12 @@ static WCHAR *wusername, *password, *protocol, *host, *path, target[1024];
 static void write_item(const char *what, LPCWSTR wbuf, int wlen)
 {
        char *buf;
+
+       if (!wbuf || !wlen) {
+               printf("%s=\n", what);
+               return;
+       }
+
        int len = WideCharToMultiByte(CP_UTF8, 0, wbuf, wlen, NULL, 0, NULL,
            FALSE);
        buf = xmalloc(len);
@@ -160,7 +166,7 @@ static int match_part_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim)
 static int match_cred(const CREDENTIALW *cred)
 {
        LPCWSTR target = cred->TargetName;
-       if (wusername && wcscmp(wusername, cred->UserName))
+       if (wusername && wcscmp(wusername, cred->UserName ? cred->UserName : L""))
                return 0;
 
        return match_part(&target, L"git", L":") &&
@@ -183,7 +189,7 @@ static void get_credential(void)
        for (i = 0; i < num_creds; ++i)
                if (match_cred(creds[i])) {
                        write_item("username", creds[i]->UserName,
-                               wcslen(creds[i]->UserName));
+                               creds[i]->UserName ? wcslen(creds[i]->UserName) : 0);
                        write_item("password",
                                (LPCWSTR)creds[i]->CredentialBlob,
                                creds[i]->CredentialBlobSize / sizeof(WCHAR));