Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / MS / Internal / AppModel / CookieHandler.cs / 1 / 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 ChangoV Created // //----------------------------------------------------------------------- using System; using System.Net; using System.Security; using System.Diagnostics; using System.ComponentModel; using System.Runtime.InteropServices; 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 before returning data. /// [SecurityCritical, SecurityTreatAsSafe] [FriendAccessAllowed] // called by PF.Application.GetCookie() internal static string GetCookie(Uri uri, bool throwIfNoCookie) { 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)) { SecurityHelper.DemandWebPermission(uri); 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. //+------------------------------------------------------------------------ // // 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 ChangoV Created // //----------------------------------------------------------------------- using System; using System.Net; using System.Security; using System.Diagnostics; using System.ComponentModel; using System.Runtime.InteropServices; 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 before returning data. /// [SecurityCritical, SecurityTreatAsSafe] [FriendAccessAllowed] // called by PF.Application.GetCookie() internal static string GetCookie(Uri uri, bool throwIfNoCookie) { 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)) { SecurityHelper.DemandWebPermission(uri); 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
- ForceCopyBuildProvider.cs
- MobileDeviceCapabilitiesSectionHandler.cs
- ToolboxItemAttribute.cs
- GB18030Encoding.cs
- Parser.cs
- FontUnit.cs
- FontUnit.cs
- ExclusiveCanonicalizationTransform.cs
- ExpressionVisitor.cs
- AssemblyBuilderData.cs
- XmlSchemaValidationException.cs
- SafeSystemMetrics.cs
- DbParameterCollectionHelper.cs
- LocalizedNameDescriptionPair.cs
- XmlILConstructAnalyzer.cs
- StreamSecurityUpgradeInitiator.cs
- IsolatedStorageException.cs
- DbReferenceCollection.cs
- AddInStore.cs
- WebPartDisplayModeCollection.cs
- SynchronousReceiveBehavior.cs
- Line.cs
- HtmlInputCheckBox.cs
- ClassicBorderDecorator.cs
- DataGridViewSortCompareEventArgs.cs
- InvokePattern.cs
- BooleanSwitch.cs
- XmlSchemaParticle.cs
- MaterialGroup.cs
- HtmlContainerControl.cs
- ConcurrentQueue.cs
- DecodeHelper.cs
- AttributeSetAction.cs
- WebPartConnectionCollection.cs
- SystemKeyConverter.cs
- FixUp.cs
- TableCellAutomationPeer.cs
- SchemaElement.cs
- KeyPullup.cs
- BroadcastEventHelper.cs
- RequestCacheManager.cs
- _UriTypeConverter.cs
- SqlFacetAttribute.cs
- Application.cs
- XmlSecureResolver.cs
- MultipleViewProviderWrapper.cs
- EndpointConfigContainer.cs
- HierarchicalDataBoundControlAdapter.cs
- HttpPostedFile.cs
- WriterOutput.cs
- StorageConditionPropertyMapping.cs
- EncodingTable.cs
- LayoutEngine.cs
- DesignTimeTemplateParser.cs
- SqlConnectionStringBuilder.cs
- formatter.cs
- RunClient.cs
- OleDbDataAdapter.cs
- TrustManager.cs
- DictionaryContent.cs
- GridViewRowPresenter.cs
- CompositeScriptReference.cs
- SimpleMailWebEventProvider.cs
- ProgressiveCrcCalculatingStream.cs
- ITreeGenerator.cs
- BindToObject.cs
- Guid.cs
- PackageProperties.cs
- ResXResourceWriter.cs
- NGCPageContentCollectionSerializerAsync.cs
- HandlerBase.cs
- CodeSnippetStatement.cs
- WebBrowserUriTypeConverter.cs
- LicenseException.cs
- AnnotationHighlightLayer.cs
- TransformConverter.cs
- SendKeys.cs
- DetailsViewRowCollection.cs
- WebPartManagerInternals.cs
- WpfMemberInvoker.cs
- TypeSystem.cs
- ResourceFallbackManager.cs
- RequestQueue.cs
- JournalEntryListConverter.cs
- Suspend.cs
- Section.cs
- ChtmlPhoneCallAdapter.cs
- ListBoxAutomationPeer.cs
- VoiceInfo.cs
- PropertyGridCommands.cs
- DataGridRelationshipRow.cs
- ButtonBase.cs
- FrameworkReadOnlyPropertyMetadata.cs
- BinaryFormatterWriter.cs
- DoubleLinkList.cs
- GetPageNumberCompletedEventArgs.cs
- AdornerHitTestResult.cs
- Configuration.cs
- XmlNodeComparer.cs
- CancellationState.cs