1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //------------------------------------------------------------
4 namespace System.ServiceModel.Security
5 {
6     using System.Security.Principal;
7     using System.ServiceModel.Channels;
8     using System.Xml;
9 
10     sealed class ImpersonatingMessage : Message
11     {
12         Message innerMessage;
13 
ImpersonatingMessage(Message innerMessage)14         public ImpersonatingMessage(Message innerMessage)
15         {
16             if (innerMessage == null)
17             {
18                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerMessage");
19             }
20             this.innerMessage = innerMessage;
21         }
22 
23         public override bool IsEmpty
24         {
25             get
26             {
27                 return this.innerMessage.IsEmpty;
28             }
29         }
30 
31         public override bool IsFault
32         {
33             get { return this.innerMessage.IsFault; }
34         }
35 
36         public override MessageHeaders Headers
37         {
38             get { return this.innerMessage.Headers; }
39         }
40 
41         public override MessageProperties Properties
42         {
43             get { return this.innerMessage.Properties; }
44         }
45 
46         public override MessageVersion Version
47         {
48             get { return this.innerMessage.Version; }
49         }
50 
51         internal override RecycledMessageState RecycledMessageState
52         {
53             get
54             {
55                 return this.innerMessage.RecycledMessageState;
56             }
57         }
58 
OnClose()59         protected override void OnClose()
60         {
61             base.OnClose();
62             this.innerMessage.Close();
63         }
64 
65         //Runs impersonated.
OnBeginWriteMessage(XmlDictionaryWriter writer, AsyncCallback callback, object state)66         protected override IAsyncResult OnBeginWriteMessage(XmlDictionaryWriter writer, AsyncCallback callback, object state)
67         {
68             ImpersonateOnSerializingReplyMessageProperty impersonationProperty = null;
69             IDisposable impersonationContext = null;
70             IPrincipal originalPrincipal = null;
71             bool isThreadPrincipalSet = false;
72 
73             if (!ImpersonateOnSerializingReplyMessageProperty.TryGet(this.innerMessage, out impersonationProperty))
74             {
75                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToImpersonateWhileSerializingReponse)));
76             }
77 
78             try
79             {
80                 impersonationProperty.StartImpersonation(out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
81                 return this.innerMessage.BeginWriteMessage(writer, callback, state);
82             }
83             finally
84             {
85                 try
86                 {
87                     impersonationProperty.StopImpersonation(impersonationContext, originalPrincipal, isThreadPrincipalSet);
88                 }
89 #pragma warning suppress 56500 // covered by FxCOP
90                 catch
91                 {
92                     string message = null;
93                     try
94                     {
95                         message = SR.GetString(SR.SFxRevertImpersonationFailed0);
96                     }
97                     finally
98                     {
99                         DiagnosticUtility.FailFast(message);
100                     }
101                 }
102             }
103         }
104 
105         //Runs impersonated.
OnWriteMessage(XmlDictionaryWriter writer)106         protected override void OnWriteMessage(XmlDictionaryWriter writer)
107         {
108             this.ImpersonateCall(() => this.innerMessage.WriteMessage(writer));
109         }
110 
OnEndWriteMessage(IAsyncResult result)111         protected override void OnEndWriteMessage(IAsyncResult result)
112         {
113             this.innerMessage.EndWriteMessage(result);
114         }
115 
OnWriteStartEnvelope(XmlDictionaryWriter writer)116         protected override void OnWriteStartEnvelope(XmlDictionaryWriter writer)
117         {
118             this.innerMessage.WriteStartEnvelope(writer);
119         }
120 
OnWriteStartHeaders(XmlDictionaryWriter writer)121         protected override void OnWriteStartHeaders(XmlDictionaryWriter writer)
122         {
123             this.innerMessage.WriteStartHeaders(writer);
124         }
125 
OnWriteStartBody(XmlDictionaryWriter writer)126         protected override void OnWriteStartBody(XmlDictionaryWriter writer)
127         {
128             this.innerMessage.WriteStartBody(writer);
129         }
130 
OnGetBodyAttribute(string localName, string ns)131         protected override string OnGetBodyAttribute(string localName, string ns)
132         {
133             return this.innerMessage.GetBodyAttribute(localName, ns);
134         }
135 
OnCreateBufferedCopy(int maxBufferSize)136         protected override MessageBuffer OnCreateBufferedCopy(int maxBufferSize)
137         {
138             return this.innerMessage.CreateBufferedCopy(maxBufferSize);
139         }
140 
OnBeginWriteBodyContents(XmlDictionaryWriter writer, AsyncCallback callback, object state)141         protected override IAsyncResult OnBeginWriteBodyContents(XmlDictionaryWriter writer, AsyncCallback callback, object state)
142         {
143             ImpersonateOnSerializingReplyMessageProperty impersonationProperty = null;
144             IDisposable impersonationContext = null;
145             IPrincipal originalPrincipal = null;
146             bool isThreadPrincipalSet = false;
147 
148             if (!ImpersonateOnSerializingReplyMessageProperty.TryGet(this.innerMessage, out impersonationProperty))
149             {
150                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToImpersonateWhileSerializingReponse)));
151             }
152 
153             try
154             {
155                 impersonationProperty.StartImpersonation(out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
156                 return this.innerMessage.BeginWriteBodyContents(writer, callback, state);
157             }
158             finally
159             {
160                 try
161                 {
162                     impersonationProperty.StopImpersonation(impersonationContext, originalPrincipal, isThreadPrincipalSet);
163                 }
164 #pragma warning suppress 56500 // covered by FxCOP
165                 catch
166                 {
167                     string message = null;
168                     try
169                     {
170                         message = SR.GetString(SR.SFxRevertImpersonationFailed0);
171                     }
172                     finally
173                     {
174                         DiagnosticUtility.FailFast(message);
175                     }
176                 }
177             }
178 
179 
180         }
181 
OnWriteBodyContents(XmlDictionaryWriter writer)182         protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
183         {
184           this.ImpersonateCall( () => this.innerMessage.WriteBodyContents(writer));
185         }
186 
OnEndWriteBodyContents(IAsyncResult result)187         protected override void OnEndWriteBodyContents(IAsyncResult result)
188         {
189             this.innerMessage.EndWriteBodyContents(result);
190         }
191 
192         //Runs impersonated.
OnBodyToString(XmlDictionaryWriter writer)193         protected override void OnBodyToString(XmlDictionaryWriter writer)
194         {
195             this.ImpersonateCall(() => this.innerMessage.BodyToString(writer));
196         }
197 
ImpersonateCall(Action callToImpersonate)198         void ImpersonateCall(Action callToImpersonate)
199         {
200             ImpersonateOnSerializingReplyMessageProperty impersonationProperty = null;
201             IDisposable impersonationContext = null;
202             IPrincipal originalPrincipal = null;
203             bool isThreadPrincipalSet = false;
204 
205             if (!ImpersonateOnSerializingReplyMessageProperty.TryGet(this.innerMessage, out impersonationProperty))
206             {
207                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnableToImpersonateWhileSerializingReponse)));
208             }
209 
210             try
211             {
212                 impersonationProperty.StartImpersonation(out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
213                 callToImpersonate();
214             }
215             finally
216             {
217                 try
218                 {
219                     impersonationProperty.StopImpersonation(impersonationContext, originalPrincipal, isThreadPrincipalSet);
220                 }
221 #pragma warning suppress 56500 // covered by FxCOP
222                 catch
223                 {
224                     string message = null;
225                     try
226                     {
227                         message = SR.GetString(SR.SFxRevertImpersonationFailed0);
228                     }
229                     finally
230                     {
231                         DiagnosticUtility.FailFast(message);
232                     }
233                 }
234             }
235         }
236     }
237 }
238