Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
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
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a506d0aa
Commit
a506d0aa
authored
Apr 30, 2013
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 30, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winhttp: Add support for NTLM and Negotiate authentication.
parent
d63ef4d8
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
380 additions
and
75 deletions
+380
-75
request.c
dlls/winhttp/request.c
+350
-74
session.c
dlls/winhttp/session.c
+3
-0
winhttp_private.h
dlls/winhttp/winhttp_private.h
+27
-1
No files found.
dlls/winhttp/request.c
View file @
a506d0aa
...
...
@@ -1206,29 +1206,45 @@ BOOL WINAPI WinHttpSendRequest( HINTERNET hrequest, LPCWSTR headers, DWORD heade
#define ARRAYSIZE(array) (sizeof(array) / sizeof((array)[0]))
static
DWORD
auth_scheme_from_header
(
WCHAR
*
header
)
{
static
const
WCHAR
basic
[]
=
{
'B'
,
'a'
,
's'
,
'i'
,
'c'
};
static
const
WCHAR
ntlm
[]
=
{
'N'
,
'T'
,
'L'
,
'M'
};
static
const
WCHAR
passport
[]
=
{
'P'
,
'a'
,
's'
,
's'
,
'p'
,
'o'
,
'r'
,
't'
};
static
const
WCHAR
digest
[]
=
{
'D'
,
'i'
,
'g'
,
'e'
,
's'
,
't'
};
static
const
WCHAR
negotiate
[]
=
{
'N'
,
'e'
,
'g'
,
'o'
,
't'
,
'i'
,
'a'
,
't'
,
'e'
};
if
(
!
strncmpiW
(
header
,
basic
,
ARRAYSIZE
(
basic
)
)
&&
(
header
[
ARRAYSIZE
(
basic
)]
==
' '
||
!
header
[
ARRAYSIZE
(
basic
)]))
return
WINHTTP_AUTH_SCHEME_BASIC
;
static
const
WCHAR
basicW
[]
=
{
'B'
,
'a'
,
's'
,
'i'
,
'c'
,
0
};
static
const
WCHAR
ntlmW
[]
=
{
'N'
,
'T'
,
'L'
,
'M'
,
0
};
static
const
WCHAR
passportW
[]
=
{
'P'
,
'a'
,
's'
,
's'
,
'p'
,
'o'
,
'r'
,
't'
,
0
};
static
const
WCHAR
digestW
[]
=
{
'D'
,
'i'
,
'g'
,
'e'
,
's'
,
't'
,
0
};
static
const
WCHAR
negotiateW
[]
=
{
'N'
,
'e'
,
'g'
,
'o'
,
't'
,
'i'
,
'a'
,
't'
,
'e'
,
0
};
if
(
!
strncmpiW
(
header
,
ntlm
,
ARRAYSIZE
(
ntlm
)
)
&&
(
header
[
ARRAYSIZE
(
ntlm
)]
==
' '
||
!
header
[
ARRAYSIZE
(
ntlm
)]))
return
WINHTTP_AUTH_SCHEME_NTLM
;
static
const
struct
{
const
WCHAR
*
str
;
unsigned
int
len
;
DWORD
scheme
;
}
auth_schemes
[]
=
{
{
basicW
,
ARRAYSIZE
(
basicW
)
-
1
,
WINHTTP_AUTH_SCHEME_BASIC
},
{
ntlmW
,
ARRAYSIZE
(
ntlmW
)
-
1
,
WINHTTP_AUTH_SCHEME_NTLM
},
{
passportW
,
ARRAYSIZE
(
passportW
)
-
1
,
WINHTTP_AUTH_SCHEME_PASSPORT
},
{
digestW
,
ARRAYSIZE
(
digestW
)
-
1
,
WINHTTP_AUTH_SCHEME_DIGEST
},
{
negotiateW
,
ARRAYSIZE
(
negotiateW
)
-
1
,
WINHTTP_AUTH_SCHEME_NEGOTIATE
}
};
static
const
unsigned
int
num_auth_schemes
=
sizeof
(
auth_schemes
)
/
sizeof
(
auth_schemes
[
0
]);
if
(
!
strncmpiW
(
header
,
passport
,
ARRAYSIZE
(
passport
)
)
&&
(
header
[
ARRAYSIZE
(
passport
)]
==
' '
||
!
header
[
ARRAYSIZE
(
passport
)]))
return
WINHTTP_AUTH_SCHEME_PASSPORT
;
static
enum
auth_scheme
scheme_from_flag
(
DWORD
flag
)
{
int
i
;
if
(
!
strncmpiW
(
header
,
digest
,
ARRAYSIZE
(
digest
)
)
&&
(
header
[
ARRAYSIZE
(
digest
)]
==
' '
||
!
header
[
ARRAYSIZE
(
digest
)]))
return
WINHTTP_AUTH_SCHEME_DIGEST
;
for
(
i
=
0
;
i
<
num_auth_schemes
;
i
++
)
if
(
flag
==
auth_schemes
[
i
].
scheme
)
return
i
;
return
SCHEME_INVALID
;
}
if
(
!
strncmpiW
(
header
,
negotiate
,
ARRAYSIZE
(
negotiate
)
)
&&
(
header
[
ARRAYSIZE
(
negotiate
)]
==
' '
||
!
header
[
ARRAYSIZE
(
negotiate
)]))
return
WINHTTP_AUTH_SCHEME_NEGOTIATE
;
static
DWORD
auth_scheme_from_header
(
WCHAR
*
header
)
{
unsigned
int
i
;
for
(
i
=
0
;
i
<
num_auth_schemes
;
i
++
)
{
if
(
!
strncmpiW
(
header
,
auth_schemes
[
i
].
str
,
auth_schemes
[
i
].
len
)
&&
(
header
[
auth_schemes
[
i
].
len
]
==
' '
||
!
header
[
auth_schemes
[
i
].
len
]))
return
auth_schemes
[
i
].
scheme
;
}
return
0
;
}
...
...
@@ -1341,74 +1357,343 @@ static UINT encode_base64( const char *bin, unsigned int len, WCHAR *base64 )
return
n
;
}
static
BOOL
set_credentials
(
request_t
*
request
,
DWORD
target
,
DWORD
scheme
,
LPCWSTR
username
,
LPCWSTR
password
)
static
inline
char
decode_char
(
WCHAR
c
)
{
static
const
WCHAR
basic
[]
=
{
'B'
,
'a'
,
's'
,
'i'
,
'c'
,
' '
,
0
};
const
WCHAR
*
auth_scheme
,
*
auth_target
;
WCHAR
*
auth_header
;
DWORD
len
,
auth_data_len
;
char
*
auth_data
;
BOOL
ret
;
if
(
c
>=
'A'
&&
c
<=
'Z'
)
return
c
-
'A'
;
if
(
c
>=
'a'
&&
c
<=
'z'
)
return
c
-
'a'
+
26
;
if
(
c
>=
'0'
&&
c
<=
'9'
)
return
c
-
'0'
+
52
;
if
(
c
==
'+'
)
return
62
;
if
(
c
==
'/'
)
return
63
;
return
64
;
}
if
(
!
username
||
!
password
)
static
unsigned
int
decode_base64
(
const
WCHAR
*
base64
,
unsigned
int
len
,
char
*
buf
)
{
unsigned
int
i
=
0
;
char
c0
,
c1
,
c2
,
c3
;
const
WCHAR
*
p
=
base64
;
while
(
len
>=
4
)
{
set_last_error
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
if
((
c0
=
decode_char
(
p
[
0
]
))
>
63
)
return
0
;
if
((
c1
=
decode_char
(
p
[
1
]
))
>
63
)
return
0
;
if
((
c2
=
decode_char
(
p
[
2
]
))
>
63
)
return
0
;
if
((
c3
=
decode_char
(
p
[
3
]
))
>
63
)
return
0
;
if
(
buf
)
{
buf
[
i
+
0
]
=
(
c0
<<
2
)
|
(
c1
>>
4
);
buf
[
i
+
1
]
=
(
c1
<<
4
)
|
(
c2
>>
2
);
buf
[
i
+
2
]
=
(
c2
<<
6
)
|
c3
;
}
len
-=
4
;
i
+=
3
;
p
+=
4
;
}
if
(
p
[
2
]
==
'='
)
{
if
((
c0
=
decode_char
(
p
[
0
]
))
>
63
)
return
0
;
if
((
c1
=
decode_char
(
p
[
1
]
))
>
63
)
return
0
;
if
(
buf
)
buf
[
i
]
=
(
c0
<<
2
)
|
(
c1
>>
4
);
i
++
;
}
else
if
(
p
[
3
]
==
'='
)
{
if
((
c0
=
decode_char
(
p
[
0
]
))
>
63
)
return
0
;
if
((
c1
=
decode_char
(
p
[
1
]
))
>
63
)
return
0
;
if
((
c2
=
decode_char
(
p
[
2
]
))
>
63
)
return
0
;
if
(
buf
)
{
buf
[
i
+
0
]
=
(
c0
<<
2
)
|
(
c1
>>
4
);
buf
[
i
+
1
]
=
(
c1
<<
4
)
|
(
c2
>>
2
);
}
i
+=
2
;
}
return
i
;
}
static
struct
authinfo
*
alloc_authinfo
(
void
)
{
struct
authinfo
*
ret
;
if
(
!
(
ret
=
heap_alloc
(
sizeof
(
*
ret
)
)))
return
NULL
;
SecInvalidateHandle
(
&
ret
->
cred
);
SecInvalidateHandle
(
&
ret
->
ctx
);
memset
(
&
ret
->
exp
,
0
,
sizeof
(
ret
->
exp
)
);
ret
->
scheme
=
0
;
ret
->
attr
=
0
;
ret
->
max_token
=
0
;
ret
->
data
=
NULL
;
ret
->
data_len
=
0
;
ret
->
finished
=
FALSE
;
return
ret
;
}
void
destroy_authinfo
(
struct
authinfo
*
authinfo
)
{
if
(
!
authinfo
)
return
;
if
(
SecIsValidHandle
(
&
authinfo
->
ctx
))
DeleteSecurityContext
(
&
authinfo
->
ctx
);
if
(
SecIsValidHandle
(
&
authinfo
->
cred
))
FreeCredentialsHandle
(
&
authinfo
->
cred
);
heap_free
(
authinfo
->
data
);
heap_free
(
authinfo
);
}
static
BOOL
get_authvalue
(
request_t
*
request
,
DWORD
level
,
DWORD
scheme
,
WCHAR
*
buffer
,
DWORD
len
)
{
DWORD
size
,
index
=
0
;
for
(;;)
{
size
=
len
;
if
(
!
query_headers
(
request
,
level
,
NULL
,
buffer
,
&
size
,
&
index
))
return
FALSE
;
if
(
auth_scheme_from_header
(
buffer
)
==
scheme
)
break
;
}
return
TRUE
;
}
static
BOOL
do_authorization
(
request_t
*
request
,
DWORD
target
,
DWORD
scheme_flag
)
{
struct
authinfo
*
authinfo
,
**
auth_ptr
;
enum
auth_scheme
scheme
=
scheme_from_flag
(
scheme_flag
);
const
WCHAR
*
auth_target
,
*
username
,
*
password
;
WCHAR
auth_value
[
2048
],
*
auth_reply
;
DWORD
len
=
sizeof
(
auth_value
),
len_scheme
,
flags
;
BOOL
ret
;
if
(
scheme
==
SCHEME_INVALID
)
return
FALSE
;
switch
(
target
)
{
case
WINHTTP_AUTH_TARGET_SERVER
:
auth_target
=
attr_authorization
;
break
;
case
WINHTTP_AUTH_TARGET_PROXY
:
auth_target
=
attr_proxy_authorization
;
break
;
case
WINHTTP_AUTH_TARGET_SERVER
:
if
(
!
get_authvalue
(
request
,
WINHTTP_QUERY_WWW_AUTHENTICATE
,
scheme_flag
,
auth_value
,
len
))
return
FALSE
;
auth_ptr
=
&
request
->
authinfo
;
auth_target
=
attr_authorization
;
username
=
request
->
connect
->
username
;
password
=
request
->
connect
->
password
;
break
;
case
WINHTTP_AUTH_TARGET_PROXY
:
if
(
!
get_authvalue
(
request
,
WINHTTP_QUERY_PROXY_AUTHENTICATE
,
scheme_flag
,
auth_value
,
len
))
return
FALSE
;
auth_ptr
=
&
request
->
proxy_authinfo
;
auth_target
=
attr_proxy_authorization
;
username
=
request
->
connect
->
session
->
proxy_username
;
password
=
request
->
connect
->
session
->
proxy_password
;
break
;
default:
WARN
(
"unknown target %x
\n
"
,
target
);
return
FALSE
;
}
authinfo
=
*
auth_ptr
;
switch
(
scheme
)
{
case
WINHTTP_AUTH_
SCHEME_BASIC
:
case
SCHEME_BASIC
:
{
int
userlen
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
username
,
strlenW
(
username
),
NULL
,
0
,
NULL
,
NULL
);
int
passlen
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
password
,
strlenW
(
password
),
NULL
,
0
,
NULL
,
NULL
);
int
userlen
,
passlen
;
TRACE
(
"basic authentication
\n
"
);
if
(
!
username
||
!
password
)
return
FALSE
;
if
((
!
authinfo
&&
!
(
authinfo
=
alloc_authinfo
()))
||
authinfo
->
finished
)
return
FALSE
;
auth_scheme
=
basic
;
auth_data_len
=
userlen
+
1
+
passlen
;
if
(
!
(
auth_data
=
heap_alloc
(
auth_data_len
)))
return
FALSE
;
userlen
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
username
,
strlenW
(
username
),
NULL
,
0
,
NULL
,
NULL
);
passlen
=
WideCharToMultiByte
(
CP_UTF8
,
0
,
password
,
strlenW
(
password
),
NULL
,
0
,
NULL
,
NULL
);
WideCharToMultiByte
(
CP_UTF8
,
0
,
username
,
-
1
,
auth_data
,
userlen
,
NULL
,
NULL
);
auth_data
[
userlen
]
=
':'
;
WideCharToMultiByte
(
CP_UTF8
,
0
,
password
,
-
1
,
auth_data
+
userlen
+
1
,
passlen
,
NULL
,
NULL
);
authinfo
->
data_len
=
userlen
+
1
+
passlen
;
if
(
!
(
authinfo
->
data
=
heap_alloc
(
authinfo
->
data_len
)))
return
FALSE
;
WideCharToMultiByte
(
CP_UTF8
,
0
,
username
,
-
1
,
authinfo
->
data
,
userlen
,
NULL
,
NULL
);
authinfo
->
data
[
userlen
]
=
':'
;
WideCharToMultiByte
(
CP_UTF8
,
0
,
password
,
-
1
,
authinfo
->
data
+
userlen
+
1
,
passlen
,
NULL
,
NULL
);
authinfo
->
scheme
=
SCHEME_BASIC
;
authinfo
->
finished
=
TRUE
;
break
;
}
case
SCHEME_NTLM
:
case
SCHEME_NEGOTIATE
:
{
SECURITY_STATUS
status
;
SecBufferDesc
out_desc
,
in_desc
;
SecBuffer
out
,
in
;
ULONG
flags
=
ISC_REQ_CONNECTION
|
ISC_REQ_USE_DCE_STYLE
|
ISC_REQ_MUTUAL_AUTH
|
ISC_REQ_DELEGATE
;
const
WCHAR
*
p
;
BOOL
first
=
FALSE
;
if
(
!
authinfo
)
{
TimeStamp
exp
;
SEC_WINNT_AUTH_IDENTITY_W
id
;
WCHAR
*
domain
,
*
user
;
if
(
!
username
||
!
password
||
!
(
authinfo
=
alloc_authinfo
()))
return
FALSE
;
first
=
TRUE
;
domain
=
(
WCHAR
*
)
username
;
user
=
strchrW
(
username
,
'\\'
);
if
(
user
)
user
++
;
else
{
user
=
(
WCHAR
*
)
username
;
domain
=
NULL
;
}
id
.
Flags
=
SEC_WINNT_AUTH_IDENTITY_UNICODE
;
id
.
User
=
user
;
id
.
UserLength
=
strlenW
(
user
);
id
.
Domain
=
domain
;
id
.
DomainLength
=
domain
?
user
-
domain
-
1
:
0
;
id
.
Password
=
(
WCHAR
*
)
password
;
id
.
PasswordLength
=
strlenW
(
password
);
status
=
AcquireCredentialsHandleW
(
NULL
,
(
SEC_WCHAR
*
)
auth_schemes
[
scheme
].
str
,
SECPKG_CRED_OUTBOUND
,
NULL
,
&
id
,
NULL
,
NULL
,
&
authinfo
->
cred
,
&
exp
);
if
(
status
==
SEC_E_OK
)
{
PSecPkgInfoW
info
;
status
=
QuerySecurityPackageInfoW
(
(
SEC_WCHAR
*
)
auth_schemes
[
scheme
].
str
,
&
info
);
if
(
status
==
SEC_E_OK
)
{
authinfo
->
max_token
=
info
->
cbMaxToken
;
FreeContextBuffer
(
info
);
}
}
if
(
status
!=
SEC_E_OK
)
{
WARN
(
"AcquireCredentialsHandleW for scheme %s failed with error 0x%08x
\n
"
,
debugstr_w
(
auth_schemes
[
scheme
].
str
),
status
);
heap_free
(
authinfo
);
return
FALSE
;
}
authinfo
->
scheme
=
scheme
;
}
else
if
(
authinfo
->
finished
)
return
FALSE
;
if
((
strlenW
(
auth_value
)
<
auth_schemes
[
authinfo
->
scheme
].
len
||
strncmpiW
(
auth_value
,
auth_schemes
[
authinfo
->
scheme
].
str
,
auth_schemes
[
authinfo
->
scheme
].
len
)))
{
ERR
(
"authentication scheme changed from %s to %s
\n
"
,
debugstr_w
(
auth_schemes
[
authinfo
->
scheme
].
str
),
debugstr_w
(
auth_value
));
return
FALSE
;
}
in
.
BufferType
=
SECBUFFER_TOKEN
;
in
.
cbBuffer
=
0
;
in
.
pvBuffer
=
NULL
;
in_desc
.
ulVersion
=
0
;
in_desc
.
cBuffers
=
1
;
in_desc
.
pBuffers
=
&
in
;
p
=
auth_value
+
auth_schemes
[
scheme
].
len
;
if
(
*
p
==
' '
)
{
int
len
=
strlenW
(
++
p
);
in
.
cbBuffer
=
decode_base64
(
p
,
len
,
NULL
);
if
(
!
(
in
.
pvBuffer
=
heap_alloc
(
in
.
cbBuffer
)))
return
FALSE
;
decode_base64
(
p
,
len
,
in
.
pvBuffer
);
}
out
.
BufferType
=
SECBUFFER_TOKEN
;
out
.
cbBuffer
=
authinfo
->
max_token
;
if
(
!
(
out
.
pvBuffer
=
heap_alloc
(
authinfo
->
max_token
)))
{
heap_free
(
in
.
pvBuffer
);
return
FALSE
;
}
out_desc
.
ulVersion
=
0
;
out_desc
.
cBuffers
=
1
;
out_desc
.
pBuffers
=
&
out
;
status
=
InitializeSecurityContextW
(
first
?
&
authinfo
->
cred
:
NULL
,
first
?
NULL
:
&
authinfo
->
ctx
,
first
?
request
->
connect
->
servername
:
NULL
,
flags
,
0
,
SECURITY_NETWORK_DREP
,
in
.
pvBuffer
?
&
in_desc
:
NULL
,
0
,
&
authinfo
->
ctx
,
&
out_desc
,
&
authinfo
->
attr
,
&
authinfo
->
exp
);
heap_free
(
in
.
pvBuffer
);
if
(
status
==
SEC_E_OK
)
{
heap_free
(
authinfo
->
data
);
authinfo
->
data
=
out
.
pvBuffer
;
authinfo
->
data_len
=
out
.
cbBuffer
;
authinfo
->
finished
=
TRUE
;
TRACE
(
"sending last auth packet
\n
"
);
}
else
if
(
status
==
SEC_I_CONTINUE_NEEDED
)
{
heap_free
(
authinfo
->
data
);
authinfo
->
data
=
out
.
pvBuffer
;
authinfo
->
data_len
=
out
.
cbBuffer
;
TRACE
(
"sending next auth packet
\n
"
);
}
else
{
ERR
(
"InitializeSecurityContextW failed with error 0x%08x
\n
"
,
status
);
heap_free
(
out
.
pvBuffer
);
destroy_authinfo
(
authinfo
);
*
auth_ptr
=
NULL
;
return
FALSE
;
}
break
;
}
case
WINHTTP_AUTH_SCHEME_NTLM
:
case
WINHTTP_AUTH_SCHEME_PASSPORT
:
case
WINHTTP_AUTH_SCHEME_DIGEST
:
case
WINHTTP_AUTH_SCHEME_NEGOTIATE
:
FIXME
(
"unimplemented authentication scheme %x
\n
"
,
scheme
);
return
FALSE
;
default:
WARN
(
"unknown authentication scheme %x
\n
"
,
scheme
);
ERR
(
"invalid scheme %u
\n
"
,
scheme
);
return
FALSE
;
}
*
auth_ptr
=
authinfo
;
len
=
strlenW
(
auth_scheme
)
+
((
auth_data_len
+
2
)
*
4
)
/
3
;
if
(
!
(
auth_header
=
heap_alloc
(
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
{
heap_free
(
auth_data
);
return
FALSE
;
}
strcpyW
(
auth_header
,
auth_scheme
);
encode_base64
(
auth_data
,
auth_data_len
,
auth_header
+
strlenW
(
auth_header
)
);
len_scheme
=
auth_schemes
[
authinfo
->
scheme
].
len
;
len
=
len_scheme
+
1
+
((
authinfo
->
data_len
+
2
)
*
4
)
/
3
;
if
(
!
(
auth_reply
=
heap_alloc
(
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
return
FALSE
;
ret
=
process_header
(
request
,
auth_target
,
auth_header
,
WINHTTP_ADDREQ_FLAG_ADD
|
WINHTTP_ADDREQ_FLAG_REPLACE
,
TRUE
);
memcpy
(
auth_reply
,
auth_schemes
[
authinfo
->
scheme
].
str
,
len_scheme
*
sizeof
(
WCHAR
)
);
auth_reply
[
len_scheme
]
=
' '
;
encode_base64
(
authinfo
->
data
,
authinfo
->
data_len
,
auth_reply
+
len_scheme
+
1
);
heap_free
(
auth_data
);
heap_free
(
auth_header
);
flags
=
WINHTTP_ADDREQ_FLAG_ADD
|
WINHTTP_ADDREQ_FLAG_REPLACE
;
ret
=
process_header
(
request
,
auth_target
,
auth_reply
,
flags
,
TRUE
);
heap_free
(
auth_reply
);
return
ret
;
}
static
BOOL
set_credentials
(
request_t
*
request
,
DWORD
target
,
DWORD
scheme
,
const
WCHAR
*
username
,
const
WCHAR
*
password
)
{
if
(
!
username
||
!
password
)
{
set_last_error
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
switch
(
target
)
{
case
WINHTTP_AUTH_TARGET_SERVER
:
{
heap_free
(
request
->
connect
->
username
);
if
(
!
(
request
->
connect
->
username
=
strdupW
(
username
)))
return
FALSE
;
heap_free
(
request
->
connect
->
password
);
if
(
!
(
request
->
connect
->
password
=
strdupW
(
password
)))
return
FALSE
;
break
;
}
case
WINHTTP_AUTH_TARGET_PROXY
:
{
heap_free
(
request
->
connect
->
session
->
proxy_username
);
if
(
!
(
request
->
connect
->
session
->
proxy_username
=
strdupW
(
username
)))
return
FALSE
;
heap_free
(
request
->
connect
->
session
->
proxy_password
);
if
(
!
(
request
->
connect
->
session
->
proxy_password
=
strdupW
(
password
)))
return
FALSE
;
break
;
}
default:
WARN
(
"unknown target %u
\n
"
,
target
);
return
FALSE
;
}
return
TRUE
;
}
/***********************************************************************
* WinHttpSetCredentials (winhttp.@)
*/
...
...
@@ -1440,8 +1725,7 @@ BOOL WINAPI WinHttpSetCredentials( HINTERNET hrequest, DWORD target, DWORD schem
static
BOOL
handle_authorization
(
request_t
*
request
,
DWORD
status
)
{
DWORD
schemes
,
level
,
target
;
const
WCHAR
*
username
,
*
password
;
DWORD
i
,
schemes
,
first
,
level
,
target
;
switch
(
status
)
{
...
...
@@ -1460,23 +1744,15 @@ static BOOL handle_authorization( request_t *request, DWORD status )
return
FALSE
;
}
if
(
!
query_auth_schemes
(
request
,
level
,
&
schemes
,
NULL
))
return
FALSE
;
if
(
!
query_auth_schemes
(
request
,
level
,
&
schemes
,
&
first
))
return
FALSE
;
if
(
do_authorization
(
request
,
target
,
first
))
return
TRUE
;
if
(
target
==
WINHTTP_AUTH_TARGET_SERVER
)
schemes
&=
~
first
;
for
(
i
=
0
;
i
<
num_auth_schemes
;
i
++
)
{
username
=
request
->
connect
->
username
;
password
=
request
->
connect
->
password
;
}
else
{
username
=
request
->
connect
->
session
->
proxy_username
;
password
=
request
->
connect
->
session
->
proxy_password
;
if
(
!
(
schemes
&
auth_schemes
[
i
].
scheme
))
continue
;
if
(
do_authorization
(
request
,
target
,
auth_schemes
[
i
].
scheme
))
return
TRUE
;
}
if
(
schemes
&
WINHTTP_AUTH_SCHEME_BASIC
)
return
set_credentials
(
request
,
target
,
WINHTTP_AUTH_SCHEME_BASIC
,
username
,
password
);
FIXME
(
"unsupported authentication scheme
\n
"
);
return
FALSE
;
}
...
...
dlls/winhttp/session.c
View file @
a506d0aa
...
...
@@ -552,6 +552,9 @@ static void request_destroy( object_header_t *hdr )
release_object
(
&
request
->
connect
->
hdr
);
destroy_authinfo
(
request
->
authinfo
);
destroy_authinfo
(
request
->
proxy_authinfo
);
heap_free
(
request
->
verb
);
heap_free
(
request
->
path
);
heap_free
(
request
->
version
);
...
...
dlls/winhttp/winhttp_private.h
View file @
a506d0aa
...
...
@@ -148,6 +148,29 @@ typedef struct
BOOL
is_request
;
/* part of request headers? */
}
header_t
;
enum
auth_scheme
{
SCHEME_INVALID
=
-
1
,
SCHEME_BASIC
,
SCHEME_NTLM
,
SCHEME_PASSPORT
,
SCHEME_DIGEST
,
SCHEME_NEGOTIATE
};
struct
authinfo
{
enum
auth_scheme
scheme
;
CredHandle
cred
;
CtxtHandle
ctx
;
TimeStamp
exp
;
ULONG
attr
;
ULONG
max_token
;
char
*
data
;
unsigned
int
data_len
;
BOOL
finished
;
/* finished authenticating */
};
typedef
struct
{
object_header_t
hdr
;
...
...
@@ -174,6 +197,8 @@ typedef struct
DWORD
num_headers
;
WCHAR
**
accept_types
;
DWORD
num_accept_types
;
struct
authinfo
*
authinfo
;
struct
authinfo
*
proxy_authinfo
;
}
request_t
;
typedef
struct
_task_header_t
task_header_t
;
...
...
@@ -252,7 +277,8 @@ BOOL set_cookies( request_t *, const WCHAR * ) DECLSPEC_HIDDEN;
BOOL
add_cookie_headers
(
request_t
*
)
DECLSPEC_HIDDEN
;
BOOL
add_request_headers
(
request_t
*
,
LPCWSTR
,
DWORD
,
DWORD
)
DECLSPEC_HIDDEN
;
void
delete_domain
(
domain_t
*
)
DECLSPEC_HIDDEN
;
BOOL
set_server_for_hostname
(
connect_t
*
connect
,
LPCWSTR
server
,
INTERNET_PORT
port
)
DECLSPEC_HIDDEN
;
BOOL
set_server_for_hostname
(
connect_t
*
,
LPCWSTR
,
INTERNET_PORT
)
DECLSPEC_HIDDEN
;
void
destroy_authinfo
(
struct
authinfo
*
)
DECLSPEC_HIDDEN
;
extern
HRESULT
WinHttpRequest_create
(
IUnknown
*
,
void
**
)
DECLSPEC_HIDDEN
;
...
...
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