File: TlsnegoTokenAuthenticator.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 (244 lines) | stat: -rw-r--r-- 10,024 bytes parent folder | download
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

namespace System.ServiceModel.Security
{
    using System;
    using System.Collections.ObjectModel;
    using System.IdentityModel.Policy;
    using System.IdentityModel.Selectors;
    using System.IdentityModel.Tokens;
    using System.Runtime;
    using System.Security.Cryptography.X509Certificates;
    using System.Security.Principal;
    using System.ServiceModel;
    using System.Xml;
    using SchProtocols = System.IdentityModel.SchProtocols;

    sealed class TlsnegoTokenAuthenticator : SspiNegotiationTokenAuthenticator
    {
        SecurityTokenAuthenticator clientTokenAuthenticator;
        SecurityTokenProvider serverTokenProvider;
        X509SecurityToken serverToken;
        bool mapCertificateToWindowsAccount;

        public TlsnegoTokenAuthenticator()
            : base()
        {
            // empty
        }

        public SecurityTokenAuthenticator ClientTokenAuthenticator
        {
            get
            {
                return this.clientTokenAuthenticator;
            }
            set
            {
                this.CommunicationObject.ThrowIfDisposedOrImmutable();
                this.clientTokenAuthenticator = value;
            }
        }

        public SecurityTokenProvider ServerTokenProvider
        {
            get
            {
                return this.serverTokenProvider;
            }
            set
            {
                this.CommunicationObject.ThrowIfDisposedOrImmutable();
                this.serverTokenProvider = value;
            }
        }

        public bool MapCertificateToWindowsAccount
        {
            get
            {
                return this.mapCertificateToWindowsAccount;
            }
            set
            {
                this.CommunicationObject.ThrowIfDisposedOrImmutable();
                this.mapCertificateToWindowsAccount = value;
            }
        }

        X509SecurityToken ValidateX509Token(SecurityToken token)
        {
            X509SecurityToken result = token as X509SecurityToken;
            if (result == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.TokenProviderReturnedBadToken, token == null ? "<null>" : token.GetType().ToString())));
            }
            SecurityUtils.EnsureCertificateCanDoKeyExchange(result.Certificate);
            return result;
        }

        // overrides
        public override XmlDictionaryString NegotiationValueType
        {
            get 
            {
                if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
                {
                    return XD.TrustApr2004Dictionary.TlsnegoValueTypeUri;
                }
                else if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrust13)
                {
                    return DXD.TrustDec2005Dictionary.TlsnegoValueTypeUri;
                }
                // Not supported
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException());
            }
        }

        public override void OnOpen(TimeSpan timeout)
        {
            if (this.serverTokenProvider == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoServerX509TokenProvider)));
            }
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            SecurityUtils.OpenTokenProviderIfRequired(this.serverTokenProvider, timeoutHelper.RemainingTime());
            if (this.clientTokenAuthenticator != null)
            {
                SecurityUtils.OpenTokenAuthenticatorIfRequired(this.clientTokenAuthenticator, timeoutHelper.RemainingTime());
            }
            SecurityToken token = this.serverTokenProvider.GetToken(timeoutHelper.RemainingTime());
            this.serverToken = ValidateX509Token(token);
            base.OnOpen(timeoutHelper.RemainingTime());
        }

        public override void OnClose(TimeSpan timeout)
        {
            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
            if (this.serverTokenProvider != null)
            {
                SecurityUtils.CloseTokenProviderIfRequired(this.serverTokenProvider, timeoutHelper.RemainingTime());
                this.serverTokenProvider = null;
            }
            if (this.clientTokenAuthenticator != null)
            {
                SecurityUtils.CloseTokenAuthenticatorIfRequired(this.clientTokenAuthenticator, timeoutHelper.RemainingTime());
                this.clientTokenAuthenticator = null;
            }
            if (this.serverToken != null)
            {
                this.serverToken = null;
            }
            base.OnClose(timeoutHelper.RemainingTime());
        }

        public override void OnAbort()
        {
            if (this.serverTokenProvider != null)
            {
                SecurityUtils.AbortTokenProviderIfRequired(this.serverTokenProvider);
                this.serverTokenProvider = null;
            }
            if (this.clientTokenAuthenticator != null)
            {
                SecurityUtils.AbortTokenAuthenticatorIfRequired(this.clientTokenAuthenticator);
                this.clientTokenAuthenticator = null;
            }
            if (this.serverToken != null)
            {
                this.serverToken = null;
            }
            base.OnAbort();
        }

        protected override void ValidateIncomingBinaryNegotiation(BinaryNegotiation incomingNego)
        {
            // Accept both strings for WSTrustFeb2005
            if (incomingNego != null &&
                incomingNego.ValueTypeUri != this.NegotiationValueType.Value &&
                this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005)
            {
                incomingNego.Validate(DXD.TrustDec2005Dictionary.TlsnegoValueTypeUri);
            }
            else
            {
                base.ValidateIncomingBinaryNegotiation(incomingNego);
            }
        }

        protected override SspiNegotiationTokenAuthenticatorState CreateSspiState(byte[] incomingBlob, string incomingValueTypeUri)
        {
            TlsSspiNegotiation tlsNegotiation = new TlsSspiNegotiation(SchProtocols.TlsServer | SchProtocols.Ssl3Server,
                this.serverToken.Certificate, this.ClientTokenAuthenticator != null);
            // Echo only for TrustFeb2005 and ValueType mismatch
            if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005 && 
                this.NegotiationValueType.Value != incomingValueTypeUri)
            {
                tlsNegotiation.IncomingValueTypeUri = incomingValueTypeUri;
            }
            return new SspiNegotiationTokenAuthenticatorState(tlsNegotiation);
        }

        protected override BinaryNegotiation GetOutgoingBinaryNegotiation(ISspiNegotiation sspiNegotiation, byte[] outgoingBlob)
        {
            TlsSspiNegotiation tlsNegotiation = sspiNegotiation as TlsSspiNegotiation;
            // Echo only for TrustFeb2005 and ValueType mismatch
            if (this.StandardsManager.MessageSecurityVersion.TrustVersion == TrustVersion.WSTrustFeb2005 &&
                tlsNegotiation != null &&
                tlsNegotiation.IncomingValueTypeUri != null)
            {
                return new BinaryNegotiation(tlsNegotiation.IncomingValueTypeUri, outgoingBlob);
            }
            else
            {
                return base.GetOutgoingBinaryNegotiation(sspiNegotiation, outgoingBlob);
            }
        }

        protected override ReadOnlyCollection<IAuthorizationPolicy> ValidateSspiNegotiation(ISspiNegotiation sspiNegotiation)
        {
            TlsSspiNegotiation tlsNegotiation = (TlsSspiNegotiation)sspiNegotiation;
            if (tlsNegotiation.IsValidContext == false)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation)));
            }

            if (this.ClientTokenAuthenticator == null)
            {
                return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
            }

            X509Certificate2 clientCertificate = tlsNegotiation.RemoteCertificate;
            if (clientCertificate == null)
            {
                // isAnonymous is false. So, fail the negotiation
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new SecurityTokenValidationException(SR.GetString(SR.ClientCertificateNotProvided)));
            }

            ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies;
            if (this.ClientTokenAuthenticator != null)
            {
                X509SecurityToken clientToken;
                WindowsIdentity preMappedIdentity;
                if (!this.MapCertificateToWindowsAccount || !tlsNegotiation.TryGetContextIdentity(out preMappedIdentity))
                {
                    clientToken = new X509SecurityToken(clientCertificate);
                }
                else
                {
                    clientToken = new X509WindowsSecurityToken(clientCertificate, preMappedIdentity, preMappedIdentity.AuthenticationType, true);
                    preMappedIdentity.Dispose();
                }
                authorizationPolicies = this.ClientTokenAuthenticator.ValidateToken(clientToken);
                clientToken.Dispose();
            }
            else
            {
                authorizationPolicies = EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
            }
            return authorizationPolicies;
        }
    }
}