Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / AppModel / CookieHandler.cs / 1305600 / CookieHandler.cs
//+------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// Description:
// A helper class for access to HTTP cookies and attaching cookies to HttpWebRequests and storing
// cookies from HttpWebResponses.
//
// In standalone WPF applications, the WinInet cookie store is used. PresentationHost intercepts calls
// to the WinInet cookie functions and delegates them to the browser. See host\DLL\CookieShim.hxx.
//
// History:
// 2007/04/11 [....] Created
//
//-----------------------------------------------------------------------
using System;
using System.Net;
using System.Security;
using System.Diagnostics;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Interop;
using MS.Win32;
using MS.Internal.PresentationCore;
namespace MS.Internal.AppModel
{
static class CookieHandler
{
internal static void HandleWebRequest(WebRequest request)
{
HttpWebRequest httpRequest = request as HttpWebRequest;
if (httpRequest != null)
{
try
{
string cookies = GetCookie(httpRequest.RequestUri, false/*throwIfNoCookie*/);
if(!string.IsNullOrEmpty(cookies))
{
if (httpRequest.CookieContainer == null)
{
httpRequest.CookieContainer = new CookieContainer();
}
// CookieContainer.SetCookies() expects multiple cookie definitions to be separated by
// comma, but GetCookie() returns them separated by ';', so we change that.
// Comma is generally not valid within a cookie (except in the 'expires' date setting, but
// we don't get that from GetCookie()).
// ClickOnce does the same in System.Deployment.Application.SystemNetDownloader.DownloadSingleFile().
httpRequest.CookieContainer.SetCookies(httpRequest.RequestUri, cookies.Replace(';', ','));
}
}
catch (Exception ex) // Attaching cookies shouldn't fail a web request.
{
if (CriticalExceptions.IsCriticalException(ex))
throw;
}
}
}
///
/// Extracts cookies from a (Http)WebResponse and stores them.
///
///
/// Critical: Calls SetCookieUnsafe().
/// An authentic WebResponse is expected, not altered by untrusted code. P3P headers fabricated by the
/// application cannot be trusted. And the application should have been able to make the web request in
/// the first place. Otherwise there is danger of overwriting someone else's cookies.
///
[SecurityCritical]
internal static void HandleWebResponse(WebResponse response)
{
HttpWebResponse httpResponse = response as HttpWebResponse;
if (httpResponse != null)
{
// Not relying on httpResponse.Cookies, because the original cookie header is needed, with all
// attributes. (A CookieCollection can be stuffed in a CookieContainer, but CookieContainer.
// GetCookieHeader() returns only name=value pairs.)
WebHeaderCollection headers = httpResponse.Headers;
// Further complication: headers["Set-cookie"] returns all cookies comma-separated. Splitting them
// is not trivial, because expiration dates have commas.
// Plan B fails too: headers.GetValues("Set-Cookie") returns the cookies broken: It does some
// "normalization" and munging and apparently confuses the commas in cookie expiration dates for
// cookie separators...
// The working solution is to find the index of the header and get all individual raw values
// associated with it. (WebHeaderCollection's internal storage is a string->ArrayList(of string) map.)
for (int i = headers.Count-1; i >= 0; i--)
{
if (string.Compare(headers.Keys[i], "Set-Cookie", StringComparison.OrdinalIgnoreCase) == 0)
{
string p3pHeader = httpResponse.Headers["P3P"];
foreach (string cookie in headers.GetValues(i))
{
try
{
SetCookieUnsafe(httpResponse.ResponseUri, cookie, p3pHeader);
}
catch (Exception ex) // A malformed cookie shouldn't fail the whole web request.
{
if (CriticalExceptions.IsCriticalException(ex))
throw;
}
}
break;
}
}
}
}
///
/// Critical: Calls the native InternetGetCookieEx(). There is potential for information disclosure.
/// Safe: A WebPermission demand is made for the given URI.
///
[SecurityCritical, SecurityTreatAsSafe]
[FriendAccessAllowed] // called by PF.Application.GetCookie()
[SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke",
Justification="It's okay now. Be careful on change.")]
internal static string GetCookie(Uri uri, bool throwIfNoCookie)
{
// Always demand in order to prevent any cross-domain information leak.
SecurityHelper.DemandWebPermission(uri);
UInt32 size = 0;
string uriString = BindUriHelper.UriToString(uri);
if (UnsafeNativeMethods.InternetGetCookieEx(uriString, null, null, ref size, 0, IntPtr.Zero))
{
Debug.Assert(size > 0);
size++;
System.Text.StringBuilder sb = new System.Text.StringBuilder((int)size);
// PresentationHost intercepts InternetGetCookieEx(). It will set the INTERNET_COOKIE_THIRD_PARTY
// flag if necessary.
if (UnsafeNativeMethods.InternetGetCookieEx(uriString, null, sb, ref size, 0, IntPtr.Zero))
{
return sb.ToString();
}
}
if (!throwIfNoCookie && Marshal.GetLastWin32Error() == NativeMethods.ERROR_NO_MORE_ITEMS)
return null;
throw new Win32Exception(/*uses last error code*/);
}
///
/// Critical: Calls SetCookieUnsafe().
/// Safe: A WebPermission is demanded for the cookie URI, and no P3P header is passed.
///
[SecurityCritical, SecurityTreatAsSafe]
[FriendAccessAllowed] // called by PF.Application.SetCookie()
internal static bool SetCookie(Uri uri, string cookieData)
{
SecurityHelper.DemandWebPermission(uri);
return SetCookieUnsafe(uri, cookieData, null);
}
///
/// Critical: Sets cookies via the native InternetSetCookieEx(); doesn't demand WebPermission for the given
/// URI. This creates danger of overwriting someone else's cookies.
/// The P3P header has to be from an authentic web response in order to be trusted at all.
///
[SecurityCritical]
private static bool SetCookieUnsafe(Uri uri, string cookieData, string p3pHeader)
{
string uriString = BindUriHelper.UriToString(uri);
// PresentationHost intercepts InternetSetCookieEx(). It will set the INTERNET_COOKIE_THIRD_PARTY
// flag if necessary. (This doesn't look very elegant but is much simpler than having to make the
// 3rd party decision here as well or calling into the native code (from PresentationCore).)
uint res = UnsafeNativeMethods.InternetSetCookieEx(
uriString, null, cookieData, UnsafeNativeMethods.INTERNET_COOKIE_EVALUATE_P3P, p3pHeader);
if(res == 0)
throw new Win32Exception(/*uses last error code*/);
return res != UnsafeNativeMethods.COOKIE_STATE_REJECT;
}
};
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SuppressMessageAttribute.cs
- _WebProxyDataBuilder.cs
- HttpGetServerProtocol.cs
- ModifierKeysConverter.cs
- Keyboard.cs
- XmlSerializerFactory.cs
- UnmanagedMemoryStream.cs
- IntSecurity.cs
- DataListItemCollection.cs
- EdmProperty.cs
- SimpleRecyclingCache.cs
- DockPattern.cs
- InvokeWebService.cs
- CompleteWizardStep.cs
- TextSimpleMarkerProperties.cs
- Parameter.cs
- WebBrowserNavigatingEventHandler.cs
- Buffer.cs
- QueryOutputWriter.cs
- StreamingContext.cs
- NativeRightsManagementAPIsStructures.cs
- DrawingVisualDrawingContext.cs
- WindowsAuthenticationModule.cs
- ObjectDataSourceView.cs
- HelpKeywordAttribute.cs
- DocumentPageViewAutomationPeer.cs
- PersonalizationStateInfoCollection.cs
- QueryNode.cs
- TcpClientChannel.cs
- Span.cs
- XmlNodeChangedEventArgs.cs
- ViewManager.cs
- NamespaceList.cs
- RemoteWebConfigurationHost.cs
- VisualTreeUtils.cs
- HotSpotCollection.cs
- WindowsPrincipal.cs
- JpegBitmapEncoder.cs
- PropertyRef.cs
- HttpResponseBase.cs
- odbcmetadatafactory.cs
- SoapSchemaMember.cs
- InputReport.cs
- AttachedPropertyMethodSelector.cs
- SafeCoTaskMem.cs
- DisplayToken.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- OdbcConnectionOpen.cs
- HierarchicalDataBoundControlAdapter.cs
- AttributeQuery.cs
- EncodingFallbackAwareXmlTextWriter.cs
- GeneratedView.cs
- baseaxisquery.cs
- WSSecureConversationDec2005.cs
- EventMappingSettingsCollection.cs
- XmlElement.cs
- Util.cs
- ExceptionValidationRule.cs
- FirstMatchCodeGroup.cs
- MessageDecoder.cs
- ExpressionEditorAttribute.cs
- ResolveMatchesCD1.cs
- LoginCancelEventArgs.cs
- MultiTargetingUtil.cs
- GatewayIPAddressInformationCollection.cs
- ToolStripRenderer.cs
- WindowsClientElement.cs
- storepermissionattribute.cs
- PromptBuilder.cs
- SafeEventLogWriteHandle.cs
- MethodBuilder.cs
- XmlArrayItemAttributes.cs
- AutoGeneratedField.cs
- EdmRelationshipRoleAttribute.cs
- NameValuePermission.cs
- SingleAnimationUsingKeyFrames.cs
- InkCanvas.cs
- XmlRawWriter.cs
- ListView.cs
- EncryptedReference.cs
- XsdDateTime.cs
- _SslState.cs
- GridViewColumn.cs
- WindowsTooltip.cs
- MatchingStyle.cs
- TableLayoutCellPaintEventArgs.cs
- WriteableOnDemandPackagePart.cs
- SqlClientMetaDataCollectionNames.cs
- SqlUnionizer.cs
- FastEncoder.cs
- DataMisalignedException.cs
- PKCS1MaskGenerationMethod.cs
- SchemaName.cs
- storepermissionattribute.cs
- ColumnMapCopier.cs
- TrackingRecord.cs
- DecimalAnimationBase.cs
- HttpServerUtilityBase.cs
- Misc.cs
- ServiceMemoryGates.cs