File: ImpersonateOnSerializingReplyMessageProperty.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (146 lines) | stat: -rw-r--r-- 7,127 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//------------------------------------------------------------------------------------------------------
// <copyright file="ImpersonateOnSerializingReplyMessageProperty.cs" company="Microsoft Corporation"> 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//----------------------------------------------------------------------------------------------------

namespace System.ServiceModel.Security
{
    using System.Runtime;
    using System.Security;
    using System.Security.Principal;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.ServiceModel.Diagnostics;

    /// <summary>
    /// The helper class to enable impersonation while serializing the body of the reply message.
    /// </summary>
    public class ImpersonateOnSerializingReplyMessageProperty : IMessageProperty
    {
        const string PropertyName = "ImpersonateOnSerializingReplyMessageProperty";
        MessageRpc rpc;

        internal ImpersonateOnSerializingReplyMessageProperty(ref MessageRpc rpc)
        {
           this.rpc = rpc;
        }

        /// <summary>
        /// Gets the name of the message property.
        /// </summary>
        public static string Name
        {
            get { return PropertyName; }
        }

        /// <summary>
        /// Gets the ImpersonateOnSerializingReplyMessageProperty property from a message.
        /// </summary>
        /// <param name="message">The message to extract the property from.</param>
        /// <param name="property">An output paramter to hold the ImpersonateOnSerializingReplyMessageProperty property.</param>
        /// <returns>True if the ImpersonateOnSerializingReplyMessageProperty property was found.</returns>
        public static bool TryGet(Message message, out ImpersonateOnSerializingReplyMessageProperty property)
        {
            if (message == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("message");
            }

            return TryGet(message.Properties, out property);
        }

        /// <summary>
        /// Gets the ImpersonateOnSerializingReplyMessageProperty property from MessageProperties.
        /// </summary>
        /// <param name="properties">The MessagePropeties object.</param>
        /// <param name="property">An output paramter to hold the ImpersonateOnSerializingReplyMessageProperty property.</param>
        /// <returns>True if the ImpersonateOnSerializingReplyMessageProperty property was found.</returns>
        public static bool TryGet(MessageProperties properties, out ImpersonateOnSerializingReplyMessageProperty property)
        {
            if (properties == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("properties");
            }

            object value = null;
            if (properties.TryGetValue(PropertyName, out value))
            {
                property = value as ImpersonateOnSerializingReplyMessageProperty;
            }
            else
            {
                property = null;
            }

            return property != null;
        }
        
        /// <summary>
        /// Creates a copy of the message property.
        /// </summary>
        /// <returns>Returns a copy of the message property.</returns>
        public IMessageProperty CreateCopy()
        {
            ImpersonateOnSerializingReplyMessageProperty result = new ImpersonateOnSerializingReplyMessageProperty(ref this.rpc);
            return result;
        }
              
        /// <summary>
        /// Starts Impersonating with the caller's context if impersonation is enabled on the service and sets the appropriate principal on the thread as per the service configuration.
        /// </summary>
        /// <param name="impersonationContext">The impersonated context.</param>
        /// <param name="originalPrincipal">The original principal on the thread before invoking this method.</param>
        /// <param name="isThreadPrincipalSet">The value determines if the principal was set on the thread by the method.</param>
        /// <returns>Returns false if operation context was not available to impersonate.</returns>
        [Fx.Tag.SecurityNote(Critical = "Calls SecurityCritical method StartImpersonation.", Safe = "Manages the result of impersonation and properly Disposes it.")]
        [SecuritySafeCritical]
        public void StartImpersonation(out IDisposable impersonationContext, out IPrincipal originalPrincipal, out bool isThreadPrincipalSet)
        {
            impersonationContext = null;
            originalPrincipal = null;
            isThreadPrincipalSet = false;

            if (OperationContext.Current != null)
            {
                EndpointDispatcher endpointDispatcher = OperationContext.Current.EndpointDispatcher;
                if (endpointDispatcher != null)
                {
                    DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
                    ImmutableDispatchRuntime runtime = dispatchRuntime.GetRuntime();
                    if (runtime != null && runtime.SecurityImpersonation != null)
                    {
                        runtime.SecurityImpersonation.StartImpersonation(ref this.rpc, out impersonationContext, out originalPrincipal, out isThreadPrincipalSet);
                    }
                }
            }
        }

        /// <summary>
        /// Reverts impersonation and sets the original principal on the thread.
        /// </summary>
        /// <param name="impersonationContext">The impersonation context to revert.</param>
        /// <param name="originalPrincipal">The original principal to set on the thread.</param>
        /// <param name="isThreadPrincipalSet">The value determines if the thread principal was set during impersonation.</param>
        /// <returns>Returns false if operation context was not available to revert the impersonation.</returns>
        [Fx.Tag.SecurityNote(Critical = "Calls SecurityCritical method StartImpersonation.", Safe = "Manages the result of impersonation and properly Disposes it.")]
        [SecuritySafeCritical]
        public void StopImpersonation(IDisposable impersonationContext, IPrincipal originalPrincipal, bool isThreadPrincipalSet)
        {
            if (OperationContext.Current != null)
            {
                EndpointDispatcher endpointDispatcher = OperationContext.Current.EndpointDispatcher;
                if (endpointDispatcher != null)
                {
                    DispatchRuntime dispatchRuntime = endpointDispatcher.DispatchRuntime;
                    ImmutableDispatchRuntime runtime = dispatchRuntime.GetRuntime();
                    if (runtime != null && runtime.SecurityImpersonation != null)
                    {
                       runtime.SecurityImpersonation.StopImpersonation(ref this.rpc, impersonationContext, originalPrincipal, isThreadPrincipalSet);
                    }
                }
            }
        }
    }
}