Hans Leidekker : rpcrt4: Use InternetSetCookie to set the session cookie.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu May 21 07:24:24 CDT 2015
Module: wine
Branch: master
Commit: 852721863abc4b807a443aef3993dc4bd63403d0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=852721863abc4b807a443aef3993dc4bd63403d0
Author: Hans Leidekker <hans at codeweavers.com>
Date: Thu May 21 10:46:44 2015 +0200
rpcrt4: Use InternetSetCookie to set the session cookie.
This ensures that the cookie is preserved when the server sets an additional cookie.
---
dlls/rpcrt4/rpc_transport.c | 85 +++++++++++++++++++++++++++------------------
1 file changed, 52 insertions(+), 33 deletions(-)
diff --git a/dlls/rpcrt4/rpc_transport.c b/dlls/rpcrt4/rpc_transport.c
index a6438a7..c6bd21e 100644
--- a/dlls/rpcrt4/rpc_transport.c
+++ b/dlls/rpcrt4/rpc_transport.c
@@ -2873,30 +2873,6 @@ static RPC_STATUS authorize_request(RpcConnection_http *httpc, HINTERNET request
return status;
}
-static RPC_STATUS insert_cookie_header(HINTERNET request, const WCHAR *value)
-{
- static const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '};
- WCHAR *header, *ptr;
- int len;
- RPC_STATUS status = RPC_S_SERVER_UNAVAILABLE;
-
- if (!value) return RPC_S_OK;
-
- len = strlenW(value);
- if ((header = HeapAlloc(GetProcessHeap(), 0, sizeof(cookieW) + (len + 3) * sizeof(WCHAR))))
- {
- memcpy(header, cookieW, sizeof(cookieW));
- ptr = header + sizeof(cookieW) / sizeof(cookieW[0]);
- memcpy(ptr, value, len * sizeof(WCHAR));
- ptr[len++] = '\r';
- ptr[len++] = '\n';
- ptr[len] = 0;
- if ((HttpAddRequestHeadersW(request, header, -1, HTTP_ADDREQ_FLAG_ADD_IF_NEW))) status = RPC_S_OK;
- HeapFree(GetProcessHeap(), 0, header);
- }
- return status;
-}
-
static BOOL has_credentials(RpcConnection_http *httpc)
{
RPC_HTTP_TRANSPORT_CREDENTIALS_W *creds;
@@ -2922,6 +2898,51 @@ static BOOL is_secure(RpcConnection_http *httpc)
(httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL);
}
+static RPC_STATUS set_auth_cookie(RpcConnection_http *httpc, const WCHAR *value)
+{
+ static WCHAR httpW[] = {'h','t','t','p',0};
+ static WCHAR httpsW[] = {'h','t','t','p','s',0};
+ URL_COMPONENTSW uc;
+ DWORD len;
+ WCHAR *url;
+ BOOL ret;
+
+ if (!value) return RPC_S_OK;
+
+ uc.dwStructSize = sizeof(uc);
+ uc.lpszScheme = is_secure(httpc) ? httpsW : httpW;
+ uc.dwSchemeLength = 0;
+ uc.lpszHostName = httpc->servername;
+ uc.dwHostNameLength = 0;
+ uc.nPort = 0;
+ uc.lpszUserName = NULL;
+ uc.dwUserNameLength = 0;
+ uc.lpszPassword = NULL;
+ uc.dwPasswordLength = 0;
+ uc.lpszUrlPath = NULL;
+ uc.dwUrlPathLength = 0;
+ uc.lpszExtraInfo = NULL;
+ uc.dwExtraInfoLength = 0;
+
+ if (!InternetCreateUrlW(&uc, 0, NULL, &len) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
+ return RPC_S_SERVER_UNAVAILABLE;
+
+ if (!(url = HeapAlloc(GetProcessHeap(), 0, len))) return RPC_S_OUT_OF_MEMORY;
+
+ len = len / sizeof(WCHAR) - 1;
+ if (!InternetCreateUrlW(&uc, 0, url, &len))
+ {
+ HeapFree(GetProcessHeap(), 0, url);
+ return RPC_S_SERVER_UNAVAILABLE;
+ }
+
+ ret = InternetSetCookieW(url, NULL, value);
+ HeapFree(GetProcessHeap(), 0, url);
+ if (!ret) return RPC_S_SERVER_UNAVAILABLE;
+
+ return RPC_S_OK;
+}
+
static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection)
{
RpcConnection_http *httpc = (RpcConnection_http *)Connection;
@@ -2975,6 +2996,12 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection)
if (secure) flags |= INTERNET_FLAG_SECURE;
if (credentials) flags |= INTERNET_FLAG_NO_AUTH;
+ status = set_auth_cookie(httpc, Connection->CookieAuth);
+ if (status != RPC_S_OK)
+ {
+ HeapFree(GetProcessHeap(), 0, url);
+ return status;
+ }
httpc->in_request = HttpOpenRequestW(httpc->session, wszVerbIn, url, NULL, NULL, wszAcceptTypes,
flags, (DWORD_PTR)httpc->async_data);
if (!httpc->in_request)
@@ -2983,12 +3010,7 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection)
HeapFree(GetProcessHeap(), 0, url);
return RPC_S_SERVER_UNAVAILABLE;
}
- status = insert_cookie_header(httpc->in_request, Connection->CookieAuth);
- if (status != RPC_S_OK)
- {
- HeapFree(GetProcessHeap(), 0, url);
- return status;
- }
+
if (credentials)
{
status = authorize_request(httpc, httpc->in_request);
@@ -3014,9 +3036,6 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection)
ERR("HttpOpenRequestW failed with error %d\n", GetLastError());
return RPC_S_SERVER_UNAVAILABLE;
}
- status = insert_cookie_header(httpc->out_request, Connection->CookieAuth);
- if (status != RPC_S_OK)
- return status;
if (credentials)
{
More information about the wine-cvs
mailing list