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