Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
dd4c6962
Commit
dd4c6962
authored
Mar 18, 2014
by
Vicent Marti
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2192 from phkelley/development
Seamless support for NTLM/Kerberos auth on Windows
parents
a7af1f7d
1392418e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
14 deletions
+98
-14
include/git2/transport.h
+2
-1
src/transports/winhttp.c
+96
-13
No files found.
include/git2/transport.h
View file @
dd4c6962
...
@@ -185,7 +185,8 @@ GIT_EXTERN(int) git_cred_default_new(git_cred **out);
...
@@ -185,7 +185,8 @@ GIT_EXTERN(int) git_cred_default_new(git_cred **out);
* remote url, or NULL if not included.
* remote url, or NULL if not included.
* - allowed_types: A bitmask stating which cred types are OK to return.
* - allowed_types: A bitmask stating which cred types are OK to return.
* - payload: The payload provided when specifying this callback.
* - payload: The payload provided when specifying this callback.
* - returns 0 for success or non-zero to indicate an error
* - returns 0 for success, < 0 to indicate an error, > 0 to indicate
* no credential was acquired
*/
*/
typedef
int
(
*
git_cred_acquire_cb
)(
typedef
int
(
*
git_cred_acquire_cb
)(
git_cred
**
cred
,
git_cred
**
cred
,
...
...
src/transports/winhttp.c
View file @
dd4c6962
...
@@ -21,6 +21,10 @@
...
@@ -21,6 +21,10 @@
#include <strsafe.h>
#include <strsafe.h>
/* For IInternetSecurityManager zone check */
#include <objbase.h>
#include <urlmon.h>
/* For UuidCreate */
/* For UuidCreate */
#pragma comment(lib, "rpcrt4")
#pragma comment(lib, "rpcrt4")
...
@@ -141,12 +145,12 @@ on_error:
...
@@ -141,12 +145,12 @@ on_error:
static
int
apply_default_credentials
(
HINTERNET
request
)
static
int
apply_default_credentials
(
HINTERNET
request
)
{
{
/*
If we are explicitly asked to deliver default credentials, turn set
/*
Either the caller explicitly requested that default credentials be passed,
*
the security level to low which will guarantee they are delivered.
*
or our fallback credential callback was invoked and checked that the target
*
The default is "medium" which applies to the intranet and sound
s
*
URI was in the appropriate Internet Explorer security zone. By setting thi
s
*
like it would correspond to Internet Explorer security zones, bu
t
*
flag, we guarantee that the credentials are delivered by WinHTTP. The defaul
t
* i
n fact does not.
* i
s "medium" which applies to the intranet and sounds like it would correspond
*/
*
to Internet Explorer security zones, but in fact does not. *
/
DWORD
data
=
WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW
;
DWORD
data
=
WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW
;
if
(
!
WinHttpSetOption
(
request
,
WINHTTP_OPTION_AUTOLOGON_POLICY
,
&
data
,
sizeof
(
DWORD
)))
if
(
!
WinHttpSetOption
(
request
,
WINHTTP_OPTION_AUTOLOGON_POLICY
,
&
data
,
sizeof
(
DWORD
)))
...
@@ -155,6 +159,71 @@ static int apply_default_credentials(HINTERNET request)
...
@@ -155,6 +159,71 @@ static int apply_default_credentials(HINTERNET request)
return
0
;
return
0
;
}
}
static
int
fallback_cred_acquire_cb
(
git_cred
**
cred
,
const
char
*
url
,
const
char
*
username_from_url
,
unsigned
int
allowed_types
,
void
*
payload
)
{
int
error
=
1
;
/* If the target URI supports integrated Windows authentication
* as an authentication mechanism */
if
(
GIT_CREDTYPE_DEFAULT
&
allowed_types
)
{
LPWSTR
wide_url
;
DWORD
wide_len
;
/* Convert URL to wide characters */
wide_len
=
MultiByteToWideChar
(
CP_UTF8
,
MB_ERR_INVALID_CHARS
,
url
,
-
1
,
NULL
,
0
);
if
(
!
wide_len
)
{
giterr_set
(
GITERR_OS
,
"Failed to measure string for wide conversion"
);
return
-
1
;
}
wide_url
=
git__malloc
(
wide_len
*
sizeof
(
WCHAR
));
GITERR_CHECK_ALLOC
(
wide_url
);
if
(
!
MultiByteToWideChar
(
CP_UTF8
,
MB_ERR_INVALID_CHARS
,
url
,
-
1
,
wide_url
,
wide_len
))
{
giterr_set
(
GITERR_OS
,
"Failed to convert string to wide form"
);
git__free
(
wide_url
);
return
-
1
;
}
if
(
SUCCEEDED
(
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
)))
{
IInternetSecurityManager
*
pISM
;
/* And if the target URI is in the My Computer, Intranet, or Trusted zones */
if
(
SUCCEEDED
(
CoCreateInstance
(
&
CLSID_InternetSecurityManager
,
NULL
,
CLSCTX_ALL
,
&
IID_IInternetSecurityManager
,
(
void
**
)
&
pISM
)))
{
DWORD
dwZone
;
if
(
SUCCEEDED
(
pISM
->
lpVtbl
->
MapUrlToZone
(
pISM
,
wide_url
,
&
dwZone
,
0
))
&&
(
URLZONE_LOCAL_MACHINE
==
dwZone
||
URLZONE_INTRANET
==
dwZone
||
URLZONE_TRUSTED
==
dwZone
))
{
git_cred
*
existing
=
*
cred
;
if
(
existing
)
existing
->
free
(
existing
);
/* Then use default Windows credentials to authenticate this request */
error
=
git_cred_default_new
(
cred
);
}
pISM
->
lpVtbl
->
Release
(
pISM
);
}
CoUninitialize
();
}
git__free
(
wide_url
);
}
return
error
;
}
static
int
winhttp_stream_connect
(
winhttp_stream
*
s
)
static
int
winhttp_stream_connect
(
winhttp_stream
*
s
)
{
{
winhttp_subtransport
*
t
=
OWNING_SUBTRANSPORT
(
s
);
winhttp_subtransport
*
t
=
OWNING_SUBTRANSPORT
(
s
);
...
@@ -657,8 +726,7 @@ replay:
...
@@ -657,8 +726,7 @@ replay:
}
}
/* Handle authentication failures */
/* Handle authentication failures */
if
(
HTTP_STATUS_DENIED
==
status_code
&&
if
(
HTTP_STATUS_DENIED
==
status_code
&&
get_verb
==
s
->
verb
)
{
get_verb
==
s
->
verb
&&
t
->
owner
->
cred_acquire_cb
)
{
int
allowed_types
;
int
allowed_types
;
if
(
parse_unauthorized_response
(
s
->
request
,
&
allowed_types
,
&
t
->
auth_mechanism
)
<
0
)
if
(
parse_unauthorized_response
(
s
->
request
,
&
allowed_types
,
&
t
->
auth_mechanism
)
<
0
)
...
@@ -666,13 +734,27 @@ replay:
...
@@ -666,13 +734,27 @@ replay:
if
(
allowed_types
&&
if
(
allowed_types
&&
(
!
t
->
cred
||
0
==
(
t
->
cred
->
credtype
&
allowed_types
)))
{
(
!
t
->
cred
||
0
==
(
t
->
cred
->
credtype
&
allowed_types
)))
{
int
cred_error
=
1
;
int
error
=
t
->
owner
->
cred_acquire_cb
(
/* Start with the user-supplied credential callback, if present */
&
t
->
cred
,
t
->
owner
->
url
,
t
->
connection_data
.
user
,
if
(
t
->
owner
->
cred_acquire_cb
)
{
allowed_types
,
t
->
owner
->
cred_acquire_payload
);
cred_error
=
t
->
owner
->
cred_acquire_cb
(
&
t
->
cred
,
t
->
owner
->
url
,
if
(
error
<
0
)
t
->
connection_data
.
user
,
allowed_types
,
t
->
owner
->
cred_acquire_payload
);
return
error
;
if
(
cred_error
<
0
)
return
cred_error
;
}
/* Invoke the fallback credentials acquisition callback if necessary */
if
(
cred_error
>
0
)
{
cred_error
=
fallback_cred_acquire_cb
(
&
t
->
cred
,
t
->
owner
->
url
,
t
->
connection_data
.
user
,
allowed_types
,
NULL
);
if
(
cred_error
<
0
)
return
cred_error
;
}
if
(
!
cred_error
)
{
assert
(
t
->
cred
);
assert
(
t
->
cred
);
WinHttpCloseHandle
(
s
->
request
);
WinHttpCloseHandle
(
s
->
request
);
...
@@ -683,6 +765,7 @@ replay:
...
@@ -683,6 +765,7 @@ replay:
goto
replay
;
goto
replay
;
}
}
}
}
}
if
(
HTTP_STATUS_OK
!=
status_code
)
{
if
(
HTTP_STATUS_OK
!=
status_code
)
{
giterr_set
(
GITERR_NET
,
"Request failed with status code: %d"
,
status_code
);
giterr_set
(
GITERR_NET
,
"Request failed with status code: %d"
,
status_code
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment