[PATCH v2] credential/wincred: store password_expiry_utc
- From
M Hickford via GitGitGadget <gitgitgadget@gmail.com>
- Date
- Mar 30, 2023, 18:17 UTC
- Message-ID
- <pull.1477.v2.git.git.1680200278780.gitgitgadget@gmail.com>
- In-Reply-To
- <pull.1477.git.git.1679729956620.gitgitgadget@gmail.com>
From: M Hickford <mirth.hickford@gmail.com>
This attribute is important when storing OAuth credentials which may expire after as little as one hour. See https://github.com/git/git/commit/d208bfdfef97a1e8fb746763b5057e0ad91e283b
Signed-off-by: M Hickford <mirth.hickford@gmail.com>
---
credential/wincred: store password_expiry_utc
Help wanted from a Windows user to test. I tried testing on Linux with
Wine after cross-compiling [1] but Wine has incomplete support for
wincred.h [2]. To test:
cd contrib/credential/wincred/
make
echo host=example.com\nprotocol=https\nusername=tim\npassword=xyzzy\npassword_expiry_utc=2000 | ./git-credential-wincred.exe store
echo host=example.com\nprotocol=https | ./git-credential-wincred.exe get
Output of second command should include line password_expiry_utc=2000
[1] make CC="zig cc -target x86_64-windows-gnu" [2]
https://github.com/wine-mirror/wine/blob/bf9d15e3b1a29f73fedda0c34547a9b29d5e2789/dlls/advapi32/cred.c#L181-L186Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1477%2Fhickford%2Fwincred-expiry-v2 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1477/hickford/wincred-expiry-v2 Pull-Request: https://github.com/git/git/pull/1477
Range-diff vs v1:
1: 05340715ef2 ! 1: 51a9039bd15 credential/wincred: store password_expiry_utc
@@ Metadata
## Commit message ##
credential/wincred: store password_expiry_utc
+ This attribute is important when storing OAuth credentials which may
+ expire after as little as one hour. See
+ https://github.com/git/git/commit/d208bfdfef97a1e8fb746763b5057e0ad91e283b
+
Signed-off-by: M Hickford <mirth.hickford@gmail.com>
## contrib/credential/wincred/git-credential-wincred.c ##
@@ contrib/credential/wincred/git-credential-wincred.c: static void get_credential(
write_item("password",
(LPCWSTR)creds[i]->CredentialBlob,
creds[i]->CredentialBlobSize / sizeof(WCHAR));
-+ attr = creds[i]->Attributes;
+ for (int j = 0; j < creds[i]->AttributeCount; j++) {
-+ if (wcscmp(attr->Keyword, L"git_password_expiry_utc")) {
++ attr = creds[i]->Attributes + j;
++ if (!wcscmp(attr->Keyword, L"git_password_expiry_utc")) {
+ write_item("password_expiry_utc", (LPCWSTR)attr->Value,
+ attr->ValueSize / sizeof(WCHAR));
+ break;
+ }
-+ attr++;
+ }
break;
}.../wincred/git-credential-wincred.c | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index ead6e267c78..7b4e7fae675 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -91,7 +91,8 @@ static void load_cred_funcs(void) die("failed to load functions"); } -static WCHAR *wusername, *password, *protocol, *host, *path, target[1024]; +static WCHAR *wusername, *password, *protocol, *host, *path, target[1024], + *password_expiry_utc; static void write_item(const char *what, LPCWSTR wbuf, int wlen) { @@ -183,6 +184,7 @@ static void get_credential(void) CREDENTIALW **creds; DWORD num_creds; int i; + CREDENTIAL_ATTRIBUTEW *attr; if (!CredEnumerateW(L"git:*", 0, &num_creds, &creds)) return; @@ -195,6 +197,14 @@ static void get_credential(void) write_item("password", (LPCWSTR)creds[i]->CredentialBlob, creds[i]->CredentialBlobSize / sizeof(WCHAR)); + for (int j = 0; j < creds[i]->AttributeCount; j++) { + attr = creds[i]->Attributes + j; + if (!wcscmp(attr->Keyword, L"git_password_expiry_utc")) { + write_item("password_expiry_utc", (LPCWSTR)attr->Value, + attr->ValueSize / sizeof(WCHAR)); + break; + } + } break; } @@ -204,6 +214,7 @@ static void get_credential(void) static void store_credential(void) { CREDENTIALW cred; + CREDENTIAL_ATTRIBUTEW expiry_attr; if (!wusername || !password) return; @@ -217,6 +228,14 @@ static void store_credential(void) cred.Persist = CRED_PERSIST_LOCAL_MACHINE; cred.AttributeCount = 0; cred.Attributes = NULL; + if (password_expiry_utc != NULL) { + expiry_attr.Keyword = L"git_password_expiry_utc"; + expiry_attr.Value = (LPVOID)password_expiry_utc; + expiry_attr.ValueSize = (wcslen(password_expiry_utc)) * sizeof(WCHAR); + expiry_attr.Flags = 0; + cred.Attributes = &expiry_attr; + cred.AttributeCount = 1; + } cred.TargetAlias = NULL; cred.UserName = wusername; @@ -278,6 +297,8 @@ static void read_credential(void) wusername = utf8_to_utf16_dup(v); } else if (!strcmp(buf, "password")) password = utf8_to_utf16_dup(v); + else if (!strcmp(buf, "password_expiry_utc")) + password_expiry_utc = utf8_to_utf16_dup(v); /* * Ignore other lines; we don't know what they mean, but * this future-proofs us when later versions of git do @@ -292,7 +313,7 @@ int main(int argc, char *argv[]) "usage: git credential-wincred <get|store|erase>\n"; if (!argv[1]) - die(usage); + die("%s", usage); /* git use binary pipes to avoid CRLF-issues */ _setmode(_fileno(stdin), _O_BINARY); base-commit: 8d90352acc5c855620042fdcc6092f23a276af6d
-- gitgitgadget