Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / SecurityVerifiedMessage.cs / 1 / SecurityVerifiedMessage.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Security { using System.ServiceModel.Channels; using System.ServiceModel; using System.Diagnostics; using System.IO; using System.Xml; using System.ServiceModel.Diagnostics; sealed class SecurityVerifiedMessage : DelegatingMessage { byte[] decryptedBuffer; XmlDictionaryReader cachedDecryptedBodyContentReader; XmlAttributeHolder[] envelopeAttributes; XmlAttributeHolder[] headerAttributes; XmlAttributeHolder[] bodyAttributes; string envelopePrefix; bool bodyDecrypted; BodyState state = BodyState.Created; string bodyPrefix; bool isDecryptedBodyStatusDetermined; bool isDecryptedBodyFault; bool isDecryptedBodyEmpty; XmlDictionaryReader cachedReaderAtSecurityHeader; readonly ReceiveSecurityHeader securityHeader; XmlBuffer messageBuffer; bool canDelegateCreateBufferedCopyToInnerMessage; public SecurityVerifiedMessage(Message messageToProcess, ReceiveSecurityHeader securityHeader) : base(messageToProcess) { this.securityHeader = securityHeader; if (securityHeader.RequireMessageProtection) { XmlDictionaryReader messageReader; BufferedMessage bufferedMessage = this.InnerMessage as BufferedMessage; if (bufferedMessage != null && this.Headers.ContainsOnlyBufferedMessageHeaders) { messageReader = bufferedMessage.GetMessageReader(); } else { this.messageBuffer = new XmlBuffer(int.MaxValue); XmlDictionaryWriter writer = this.messageBuffer.OpenSection(this.securityHeader.ReaderQuotas); this.InnerMessage.WriteMessage(writer); this.messageBuffer.CloseSection(); this.messageBuffer.Close(); messageReader = this.messageBuffer.GetReader(0); } MoveToSecurityHeader(messageReader, securityHeader.HeaderIndex, true); this.cachedReaderAtSecurityHeader = messageReader; this.state = BodyState.Buffered; } else { this.envelopeAttributes = XmlAttributeHolder.emptyArray; this.headerAttributes = XmlAttributeHolder.emptyArray; this.bodyAttributes = XmlAttributeHolder.emptyArray; this.canDelegateCreateBufferedCopyToInnerMessage = true; } } public override bool IsEmpty { get { if (this.IsDisposed) { // PreSharp Bug: Property get methods should not throw exceptions. #pragma warning suppress 56503 throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); } if (!this.bodyDecrypted) { return this.InnerMessage.IsEmpty; } EnsureDecryptedBodyStatusDetermined(); return this.isDecryptedBodyEmpty; } } public override bool IsFault { get { if (this.IsDisposed) { // PreSharp Bug: Property get methods should not throw exceptions. #pragma warning suppress 56503 throw TraceUtility.ThrowHelperError(CreateMessageDisposedException(), this); } if (!this.bodyDecrypted) { return this.InnerMessage.IsFault; } EnsureDecryptedBodyStatusDetermined(); return this.isDecryptedBodyFault; } } internal byte[] PrimarySignatureValue { get { return this.securityHeader.PrimarySignatureValue; } } internal ReceiveSecurityHeader ReceivedSecurityHeader { get { return this.securityHeader; } } Exception CreateBadStateException(string operation) { return new InvalidOperationException(SR.GetString(SR.MessageBodyOperationNotValidInBodyState, operation, this.state)); } public XmlDictionaryReader CreateFullBodyReader() { switch (this.state) { case BodyState.Buffered: return CreateFullBodyReaderFromBufferedState(); case BodyState.Decrypted: return CreateFullBodyReaderFromDecryptedState(); default: throw TraceUtility.ThrowHelperError(CreateBadStateException("CreateFullBodyReader"), this); } } XmlDictionaryReader CreateFullBodyReaderFromBufferedState() { if (this.messageBuffer != null) { XmlDictionaryReader reader = this.messageBuffer.GetReader(0); MoveToBody(reader); return reader; } else { return ((BufferedMessage) this.InnerMessage).GetBufferedReaderAtBody(); } } XmlDictionaryReader CreateFullBodyReaderFromDecryptedState() { XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(this.decryptedBuffer, 0, this.decryptedBuffer.Length, this.securityHeader.ReaderQuotas); MoveToBody(reader); return reader; } void EnsureDecryptedBodyStatusDetermined() { if (!this.isDecryptedBodyStatusDetermined) { XmlDictionaryReader reader = CreateFullBodyReader(); if (Message.ReadStartBody(reader, this.InnerMessage.Version.Envelope, out this.isDecryptedBodyFault, out this.isDecryptedBodyEmpty)) { this.cachedDecryptedBodyContentReader = reader; } else { reader.Close(); } this.isDecryptedBodyStatusDetermined = true; } } public XmlAttributeHolder[] GetEnvelopeAttributes() { return this.envelopeAttributes; } public XmlAttributeHolder[] GetHeaderAttributes() { return this.headerAttributes; } XmlDictionaryReader GetReaderAtEnvelope() { if (this.messageBuffer != null) { return this.messageBuffer.GetReader(0); } else { return ((BufferedMessage) this.InnerMessage).GetMessageReader(); } } public XmlDictionaryReader GetReaderAtFirstHeader() { XmlDictionaryReader reader = GetReaderAtEnvelope(); MoveToHeaderBlock(reader, false); reader.ReadStartElement(); return reader; } public XmlDictionaryReader GetReaderAtSecurityHeader() { if (this.cachedReaderAtSecurityHeader != null) { XmlDictionaryReader result = this.cachedReaderAtSecurityHeader; this.cachedReaderAtSecurityHeader = null; return result; } return this.Headers.GetReaderAtHeader(this.securityHeader.HeaderIndex); } void MoveToBody(XmlDictionaryReader reader) { if (reader.NodeType != XmlNodeType.Element) { reader.MoveToContent(); } reader.ReadStartElement(); if (reader.IsStartElement(XD.MessageDictionary.Header, this.Version.Envelope.DictionaryNamespace)) { reader.Skip(); } if (reader.NodeType != XmlNodeType.Element) { reader.MoveToContent(); } } void MoveToHeaderBlock(XmlDictionaryReader reader, bool captureAttributes) { if (reader.NodeType != XmlNodeType.Element) { reader.MoveToContent(); } if (captureAttributes) { this.envelopePrefix = reader.Prefix; this.envelopeAttributes = XmlAttributeHolder.ReadAttributes(reader); } reader.ReadStartElement(); reader.MoveToStartElement(XD.MessageDictionary.Header, this.Version.Envelope.DictionaryNamespace); if (captureAttributes) { this.headerAttributes = XmlAttributeHolder.ReadAttributes(reader); } } void MoveToSecurityHeader(XmlDictionaryReader reader, int headerIndex, bool captureAttributes) { MoveToHeaderBlock(reader, captureAttributes); reader.ReadStartElement(); while (true) { if (reader.NodeType != XmlNodeType.Element) { reader.MoveToContent(); } if (headerIndex == 0) { break; } reader.Skip(); headerIndex--; } } protected override void OnBodyToString(XmlDictionaryWriter writer) { if (this.state == BodyState.Created) { base.OnBodyToString(writer); } else { OnWriteBodyContents(writer); } } protected override void OnClose() { if (this.cachedDecryptedBodyContentReader != null) { try { this.cachedDecryptedBodyContentReader.Close(); } catch (System.IO.IOException exception) { // // We only want to catch and log the I/O exception here // assuming reader only throw those exceptions // DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Warning); } finally { this.cachedDecryptedBodyContentReader = null; } } if (this.cachedReaderAtSecurityHeader != null) { try { this.cachedReaderAtSecurityHeader.Close(); } catch (System.IO.IOException exception) { // // We only want to catch and log the I/O exception here // assuming reader only throw those exceptions // DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Warning); } finally { this.cachedReaderAtSecurityHeader = null; } } this.messageBuffer = null; this.decryptedBuffer = null; this.state = BodyState.Disposed; this.InnerMessage.Close(); } protected override XmlDictionaryReader OnGetReaderAtBodyContents() { if (this.state == BodyState.Created) { return this.InnerMessage.GetReaderAtBodyContents(); } if (this.bodyDecrypted) { EnsureDecryptedBodyStatusDetermined(); } if (this.cachedDecryptedBodyContentReader != null) { XmlDictionaryReader result = this.cachedDecryptedBodyContentReader; this.cachedDecryptedBodyContentReader = null; return result; } else { XmlDictionaryReader reader = CreateFullBodyReader(); reader.ReadStartElement(); reader.MoveToContent(); return reader; } } protected override MessageBuffer OnCreateBufferedCopy(int maxBufferSize) { if (this.canDelegateCreateBufferedCopyToInnerMessage && this.InnerMessage is BufferedMessage) { return this.InnerMessage.CreateBufferedCopy(maxBufferSize); } else { return base.OnCreateBufferedCopy(maxBufferSize); } } internal void OnMessageProtectionPassComplete(bool atLeastOneHeaderOrBodyEncrypted) { this.canDelegateCreateBufferedCopyToInnerMessage = !atLeastOneHeaderOrBodyEncrypted; } internal void OnUnencryptedPart(string name, string ns) { if (ns == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.RequiredMessagePartNotEncrypted, name)), this); } else { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.RequiredMessagePartNotEncryptedNs, name, ns)), this); } } internal void OnUnsignedPart(string name, string ns) { if (ns == null) { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.RequiredMessagePartNotSigned, name)), this); } else { throw TraceUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.RequiredMessagePartNotSignedNs, name, ns)), this); } } protected override void OnWriteStartBody(XmlDictionaryWriter writer) { if (this.state == BodyState.Created) { this.InnerMessage.WriteStartBody(writer); return; } XmlDictionaryReader reader = CreateFullBodyReader(); reader.MoveToContent(); writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); writer.WriteAttributes(reader, false); reader.Close(); } protected override void OnWriteBodyContents(XmlDictionaryWriter writer) { if (this.state == BodyState.Created) { this.InnerMessage.WriteBodyContents(writer); return; } XmlDictionaryReader reader = CreateFullBodyReader(); reader.ReadStartElement(); while (reader.NodeType != XmlNodeType.EndElement) writer.WriteNode(reader, false); reader.ReadEndElement(); reader.Close(); } public void SetBodyPrefixAndAttributes(XmlDictionaryReader bodyReader) { this.bodyPrefix = bodyReader.Prefix; this.bodyAttributes = XmlAttributeHolder.ReadAttributes(bodyReader); } public void SetDecryptedBody(byte[] decryptedBodyContent) { if (this.state != BodyState.Buffered) { throw TraceUtility.ThrowHelperError(CreateBadStateException("SetDecryptedBody"), this); } MemoryStream stream = new MemoryStream(); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream); writer.WriteStartElement(this.envelopePrefix, XD.MessageDictionary.Envelope, this.Version.Envelope.DictionaryNamespace); XmlAttributeHolder.WriteAttributes(this.envelopeAttributes, writer); writer.WriteStartElement(this.bodyPrefix, XD.MessageDictionary.Body, this.Version.Envelope.DictionaryNamespace); XmlAttributeHolder.WriteAttributes(this.bodyAttributes, writer); writer.WriteString(" "); // ensure non-empty element writer.WriteEndElement(); writer.WriteEndElement(); writer.Flush(); this.decryptedBuffer = ContextImportHelper.SpliceBuffers(decryptedBodyContent, stream.GetBuffer(), (int) stream.Length, 2); this.bodyDecrypted = true; this.state = BodyState.Decrypted; } enum BodyState { Created, Buffered, Decrypted, Disposed, } } // Adding wrapping tags using a writer is a temporary feature to // support interop with a partner. Eventually, the serialization // team will add a feature to XmlUTF8TextReader to directly // support the addition of outer namespaces before creating a // Reader. This roundabout way of supporting context-sensitive // decryption can then be removed. static class ContextImportHelper { internal static XmlDictionaryReader CreateSplicedReader(byte[] decryptedBuffer, XmlAttributeHolder[] outerContext1, XmlAttributeHolder[] outerContext2, XmlAttributeHolder[] outerContext3, XmlDictionaryReaderQuotas quotas) { const string wrapper1 = "x"; const string wrapper2 = "y"; const string wrapper3 = "z"; const int wrappingDepth = 3; MemoryStream stream = new MemoryStream(); XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream); writer.WriteStartElement(wrapper1); WriteNamespaceDeclarations(outerContext1, writer); writer.WriteStartElement(wrapper2); WriteNamespaceDeclarations(outerContext2, writer); writer.WriteStartElement(wrapper3); WriteNamespaceDeclarations(outerContext3, writer); writer.WriteString(" "); // ensure non-empty element writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndElement(); writer.Flush(); byte[] splicedBuffer = SpliceBuffers(decryptedBuffer, stream.GetBuffer(), (int) stream.Length, wrappingDepth); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(splicedBuffer, quotas); reader.ReadStartElement(wrapper1); reader.ReadStartElement(wrapper2); reader.ReadStartElement(wrapper3); if (reader.NodeType != XmlNodeType.Element) { reader.MoveToContent(); } return reader; } internal static string GetPrefixIfNamespaceDeclaration(string prefix, string localName) { if (prefix == "xmlns") { return localName; } if (prefix.Length == 0 && localName == "xmlns") { return string.Empty; } return null; } static bool IsNamespaceDeclaration(string prefix, string localName) { return GetPrefixIfNamespaceDeclaration(prefix, localName) != null; } internal static byte[] SpliceBuffers(byte[] middle, byte[] wrapper, int wrapperLength, int wrappingDepth) { const byte openChar = (byte) '<'; int openCharsFound = 0; int openCharIndex; for (openCharIndex = wrapperLength - 1; openCharIndex >= 0; openCharIndex--) { if (wrapper[openCharIndex] == openChar) { openCharsFound++; if (openCharsFound == wrappingDepth) { break; } } } DiagnosticUtility.DebugAssert(openCharIndex > 0, ""); byte[] splicedBuffer = DiagnosticUtility.Utility.AllocateByteArray(checked(middle.Length + wrapperLength - 1)); int offset = 0; int count = openCharIndex - 1; Buffer.BlockCopy(wrapper, 0, splicedBuffer, offset, count); offset += count; count = middle.Length; Buffer.BlockCopy(middle, 0, splicedBuffer, offset, count); offset += count; count = wrapperLength - openCharIndex; Buffer.BlockCopy(wrapper, openCharIndex, splicedBuffer, offset, count); return splicedBuffer; } static void WriteNamespaceDeclarations(XmlAttributeHolder[] attributes, XmlWriter writer) { if (attributes != null) { for (int i = 0; i < attributes.Length; i++) { XmlAttributeHolder a = attributes[i]; if (IsNamespaceDeclaration(a.Prefix, a.LocalName)) { a.WriteTo(writer); } } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PartialTrustHelpers.cs
- VScrollBar.cs
- Rotation3DKeyFrameCollection.cs
- SqlComparer.cs
- DiscardableAttribute.cs
- SubstitutionList.cs
- AuthorizationRuleCollection.cs
- regiisutil.cs
- DataSetSchema.cs
- InternalTransaction.cs
- DBPropSet.cs
- OrderedDictionary.cs
- IntSecurity.cs
- GeneratedView.cs
- ByteRangeDownloader.cs
- M3DUtil.cs
- SocketInformation.cs
- OdbcParameter.cs
- SafeHandle.cs
- Decorator.cs
- CrossContextChannel.cs
- GlyphCollection.cs
- SerializationEventsCache.cs
- LOSFormatter.cs
- IsolatedStorageFileStream.cs
- WpfXamlMember.cs
- SubstitutionList.cs
- DocumentsTrace.cs
- ZipArchive.cs
- MultiSelector.cs
- Tag.cs
- ToolStripPanelCell.cs
- StreamGeometry.cs
- SecurityAlgorithmSuite.cs
- EmbeddedObject.cs
- DictionaryKeyPropertyAttribute.cs
- Rect.cs
- securitycriticaldataClass.cs
- MimeObjectFactory.cs
- WebServicesInteroperability.cs
- CatalogPartChrome.cs
- QilLoop.cs
- safelink.cs
- DeviceContext2.cs
- DefaultProxySection.cs
- ToolStripDesigner.cs
- SyndicationDeserializer.cs
- ColorKeyFrameCollection.cs
- TypeConstant.cs
- GenerateHelper.cs
- SafeFileMappingHandle.cs
- _AutoWebProxyScriptWrapper.cs
- ErrorProvider.cs
- EnumMember.cs
- ElementAtQueryOperator.cs
- MessageBox.cs
- TextParagraphView.cs
- CopyAction.cs
- XsdBuildProvider.cs
- ComboBoxItem.cs
- AudioFormatConverter.cs
- ListChangedEventArgs.cs
- InertiaTranslationBehavior.cs
- PropertyEntry.cs
- PropertyGroupDescription.cs
- LinearGradientBrush.cs
- SchemaHelper.cs
- DelayDesigner.cs
- SmtpCommands.cs
- AdjustableArrowCap.cs
- CryptoHelper.cs
- LineGeometry.cs
- SettingsContext.cs
- EmbeddedMailObjectsCollection.cs
- VectorValueSerializer.cs
- SqlResolver.cs
- HiddenFieldDesigner.cs
- FieldNameLookup.cs
- WsatProxy.cs
- LexicalChunk.cs
- CellPartitioner.cs
- ApplicationBuildProvider.cs
- FuncCompletionCallbackWrapper.cs
- DefaultHttpHandler.cs
- XmlLoader.cs
- ToolStripCollectionEditor.cs
- X509ThumbprintKeyIdentifierClause.cs
- EventManager.cs
- Single.cs
- DataBoundControlAdapter.cs
- XmlILAnnotation.cs
- SecurityTokenRequirement.cs
- XmlNode.cs
- CategoryGridEntry.cs
- StrokeCollectionDefaultValueFactory.cs
- OleDbParameterCollection.cs
- DefaultParameterValueAttribute.cs
- PointConverter.cs
- BrowserDefinitionCollection.cs
- DropShadowEffect.cs