1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "HttpWinUtils.h"
#include "nsIURI.h"
#include "nsHttpChannel.h"
#include "mozilla/ClearOnShutdown.h"
#include <proofofpossessioncookieinfo.h>
namespace mozilla {
namespace net {
static StaticRefPtr<IProofOfPossessionCookieInfoManager> sPopCookieManager;
static bool sPopCookieManagerAvailable = true;
void AddWindowsSSO(nsHttpChannel* channel) {
if (!sPopCookieManagerAvailable) {
return;
}
HRESULT hr;
if (!sPopCookieManager) {
GUID CLSID_ProofOfPossessionCookieInfoManager;
GUID IID_IProofOfPossessionCookieInfoManager;
CLSIDFromString(L"{A9927F85-A304-4390-8B23-A75F1C668600}",
&CLSID_ProofOfPossessionCookieInfoManager);
IIDFromString(L"{CDAECE56-4EDF-43DF-B113-88E4556FA1BB}",
&IID_IProofOfPossessionCookieInfoManager);
hr = CoCreateInstance(CLSID_ProofOfPossessionCookieInfoManager, NULL,
CLSCTX_INPROC_SERVER,
IID_IProofOfPossessionCookieInfoManager,
reinterpret_cast<void**>(&sPopCookieManager));
if (FAILED(hr)) {
sPopCookieManagerAvailable = false;
return;
}
RunOnShutdown([&] {
if (sPopCookieManager) {
sPopCookieManager = nullptr;
}
});
}
DWORD cookieCount = 0;
ProofOfPossessionCookieInfo* cookieInfo = nullptr;
nsCOMPtr<nsIURI> uri;
channel->GetURI(getter_AddRefs(uri));
nsAutoCString urispec;
uri->GetSpec(urispec);
hr = sPopCookieManager->GetCookieInfoForUri(
NS_ConvertUTF8toUTF16(urispec).get(), &cookieCount, &cookieInfo);
if (FAILED(hr)) {
return;
}
nsAutoCString host;
uri->GetHost(host);
bool addCookies = false;
if (StringEndsWith(host, ".live.com"_ns)) {
addCookies = true;
}
nsAutoString allCookies;
for (DWORD i = 0; i < cookieCount; i++) {
nsAutoString cookieData;
cookieData.Assign(cookieInfo[i].data);
// Strip old Set-Cookie info for WinInet
int32_t semicolon = cookieData.FindChar(';');
if (semicolon >= 0) {
cookieData.SetLength(semicolon);
}
if (StringBeginsWith(nsDependentString(cookieInfo[i].name), u"x-ms-"_ns)) {
channel->SetRequestHeader(NS_ConvertUTF16toUTF8(cookieInfo[i].name),
NS_ConvertUTF16toUTF8(cookieData),
true /* merge */);
} else if (addCookies) {
if (!allCookies.IsEmpty()) {
allCookies.AppendLiteral("; ");
}
allCookies.Append(cookieInfo[i].name);
allCookies.AppendLiteral("=");
allCookies.Append(cookieData);
}
}
// Merging cookie headers doesn't work correctly as it separates the new
// cookies using commas instead of semicolons, so we have to replace
// the entire header.
if (!allCookies.IsEmpty()) {
nsAutoCString cookieHeader;
channel->GetRequestHeader(nsHttp::Cookie.val(), cookieHeader);
if (!cookieHeader.IsEmpty()) {
cookieHeader.AppendLiteral("; ");
}
cookieHeader.Append(NS_ConvertUTF16toUTF8(allCookies));
channel->SetRequestHeader(nsHttp::Cookie.val(), cookieHeader, false);
}
if (cookieInfo) {
FreeProofOfPossessionCookieInfoArray(cookieInfo, cookieCount);
}
}
} // namespace net
} // namespace mozilla
|