37d443c87cfe9b9ff0f608d342b9510ff59dbdfc
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Channels / StreamSecurityUpgradeInitiatorAsyncResult.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4 namespace System.ServiceModel.Channels
5 {
6     using System.IO;
7     using System.Runtime;
8     using System.Security.Authentication;
9     using System.ServiceModel.Security;
10
11     abstract class StreamSecurityUpgradeInitiatorAsyncResult : AsyncResult
12     {
13         Stream originalStream;
14         SecurityMessageProperty remoteSecurity;
15         Stream upgradedStream;
16
17         static AsyncCallback onAuthenticateAsClient = Fx.ThunkCallback(new AsyncCallback(OnAuthenticateAsClient));
18
19         public StreamSecurityUpgradeInitiatorAsyncResult(AsyncCallback callback, object state)
20             : base(callback, state)
21         {
22             // empty
23         }
24
25         public void Begin(Stream stream)
26         {
27             this.originalStream = stream;
28             IAsyncResult result;
29
30             try
31             {
32                 result = this.OnBeginAuthenticateAsClient(this.originalStream, onAuthenticateAsClient);
33             }
34             catch (AuthenticationException exception)
35             {
36                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message,
37                     exception));
38             }
39             catch (IOException ioException)
40             {
41                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(
42                     SR.GetString(SR.NegotiationFailedIO, ioException.Message), ioException));
43             }
44
45             if (!result.CompletedSynchronously)
46             {
47                 return;
48             }
49
50             CompleteAuthenticateAsClient(result);
51             base.Complete(true);
52         }
53
54         void CompleteAuthenticateAsClient(IAsyncResult result)
55         {
56             try
57             {
58                 this.upgradedStream = this.OnCompleteAuthenticateAsClient(result);
59             }
60             catch (AuthenticationException exception)
61             {
62                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(exception.Message,
63                     exception));
64             }
65             catch (IOException ioException)
66             {
67                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityNegotiationException(
68                     SR.GetString(SR.NegotiationFailedIO, ioException.Message), ioException));
69             }
70
71             this.remoteSecurity = this.ValidateCreateSecurity();
72         }
73
74         public static Stream End(IAsyncResult result, out SecurityMessageProperty remoteSecurity)
75         {
76             StreamSecurityUpgradeInitiatorAsyncResult thisPtr = AsyncResult.End<StreamSecurityUpgradeInitiatorAsyncResult>(result);
77             remoteSecurity = thisPtr.remoteSecurity;
78             return thisPtr.upgradedStream;
79         }
80
81         static void OnAuthenticateAsClient(IAsyncResult result)
82         {
83             if (result.CompletedSynchronously)
84             {
85                 return;
86             }
87
88             StreamSecurityUpgradeInitiatorAsyncResult thisPtr =
89                 (StreamSecurityUpgradeInitiatorAsyncResult)result.AsyncState;
90
91             Exception completionException = null;
92             try
93             {
94                 thisPtr.CompleteAuthenticateAsClient(result);
95             }
96 #pragma warning suppress 56500 // Microsoft, transferring exception to another thread
97             catch (Exception e)
98             {
99                 if (Fx.IsFatal(e))
100                 {
101                     throw;
102                 }
103
104                 completionException = e;
105             }
106             thisPtr.Complete(false, completionException);
107         }
108
109         protected abstract IAsyncResult OnBeginAuthenticateAsClient(Stream stream, AsyncCallback callback);
110         protected abstract Stream OnCompleteAuthenticateAsClient(IAsyncResult result);
111         protected abstract SecurityMessageProperty ValidateCreateSecurity();
112     }
113 }