@@ -35,7 +35,7 @@ static void *xmalloc(size_t size)
35
35
}
36
36
37
37
static WCHAR * wusername , * password , * protocol , * host , * path , target [1024 ],
38
- * password_expiry_utc ;
38
+ * password_expiry_utc , * oauth_refresh_token ;
39
39
40
40
static void write_item (const char * what , LPCWSTR wbuf , int wlen )
41
41
{
@@ -140,6 +140,11 @@ static void get_credential(void)
140
140
DWORD num_creds ;
141
141
int i ;
142
142
CREDENTIAL_ATTRIBUTEW * attr ;
143
+ WCHAR * secret ;
144
+ WCHAR * line ;
145
+ WCHAR * remaining_lines ;
146
+ WCHAR * part ;
147
+ WCHAR * remaining_parts ;
143
148
144
149
if (!CredEnumerateW (L"git:*" , 0 , & num_creds , & creds ))
145
150
return ;
@@ -149,9 +154,17 @@ static void get_credential(void)
149
154
if (match_cred (creds [i ], 0 )) {
150
155
write_item ("username" , creds [i ]-> UserName ,
151
156
creds [i ]-> UserName ? wcslen (creds [i ]-> UserName ) : 0 );
152
- write_item ("password" ,
153
- (LPCWSTR )creds [i ]-> CredentialBlob ,
154
- creds [i ]-> CredentialBlobSize / sizeof (WCHAR ));
157
+ secret = xmalloc (creds [i ]-> CredentialBlobSize );
158
+ wcsncpy_s (secret , creds [i ]-> CredentialBlobSize , (LPCWSTR )creds [i ]-> CredentialBlob , creds [i ]-> CredentialBlobSize / sizeof (WCHAR ));
159
+ line = wcstok_s (secret , L"\r\n" , & remaining_lines );
160
+ write_item ("password" , line , wcslen (line ));
161
+ while (line != NULL ) {
162
+ part = wcstok_s (line , L"=" , & remaining_parts );
163
+ if (!wcscmp (part , L"oauth_refresh_token" )) {
164
+ write_item ("oauth_refresh_token" , remaining_parts , wcslen (remaining_parts ));
165
+ }
166
+ line = wcstok_s (NULL , L"\r\n" , & remaining_lines );
167
+ }
155
168
for (int j = 0 ; j < creds [i ]-> AttributeCount ; j ++ ) {
156
169
attr = creds [i ]-> Attributes + j ;
157
170
if (!wcscmp (attr -> Keyword , L"git_password_expiry_utc" )) {
@@ -160,6 +173,7 @@ static void get_credential(void)
160
173
break ;
161
174
}
162
175
}
176
+ free (secret );
163
177
break ;
164
178
}
165
179
@@ -170,16 +184,26 @@ static void store_credential(void)
170
184
{
171
185
CREDENTIALW cred ;
172
186
CREDENTIAL_ATTRIBUTEW expiry_attr ;
187
+ WCHAR * secret ;
188
+ int wlen ;
173
189
174
190
if (!wusername || !password )
175
191
return ;
176
192
193
+ if (oauth_refresh_token ) {
194
+ wlen = _scwprintf (L"%s\r\noauth_refresh_token=%s" , password , oauth_refresh_token );
195
+ secret = xmalloc (sizeof (WCHAR ) * wlen );
196
+ _snwprintf_s (secret , sizeof (WCHAR ) * wlen , wlen , L"%s\r\noauth_refresh_token=%s" , password , oauth_refresh_token );
197
+ } else {
198
+ secret = _wcsdup (password );
199
+ }
200
+
177
201
cred .Flags = 0 ;
178
202
cred .Type = CRED_TYPE_GENERIC ;
179
203
cred .TargetName = target ;
180
204
cred .Comment = L"saved by git-credential-wincred" ;
181
- cred .CredentialBlobSize = ( wcslen (password ) ) * sizeof (WCHAR );
182
- cred .CredentialBlob = (LPVOID )password ;
205
+ cred .CredentialBlobSize = wcslen (secret ) * sizeof (WCHAR );
206
+ cred .CredentialBlob = (LPVOID )_wcsdup ( secret ) ;
183
207
cred .Persist = CRED_PERSIST_LOCAL_MACHINE ;
184
208
cred .AttributeCount = 0 ;
185
209
cred .Attributes = NULL ;
@@ -194,6 +218,8 @@ static void store_credential(void)
194
218
cred .TargetAlias = NULL ;
195
219
cred .UserName = wusername ;
196
220
221
+ free (secret );
222
+
197
223
if (!CredWriteW (& cred , 0 ))
198
224
die ("CredWrite failed" );
199
225
}
@@ -265,6 +291,8 @@ static void read_credential(void)
265
291
password = utf8_to_utf16_dup (v );
266
292
else if (!strcmp (buf , "password_expiry_utc" ))
267
293
password_expiry_utc = utf8_to_utf16_dup (v );
294
+ else if (!strcmp (buf , "oauth_refresh_token" ))
295
+ oauth_refresh_token = utf8_to_utf16_dup (v );
268
296
/*
269
297
* Ignore other lines; we don't know what they mean, but
270
298
* this future-proofs us when later versions of git do
0 commit comments