| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections.Generic; |
| | | 6 | | using System.Collections.ObjectModel; |
| | | 7 | | using System.Globalization; |
| | | 8 | | using System.Security.Authentication.ExtendedProtection; |
| | | 9 | | using System.Threading.Tasks; |
| | | 10 | | using CoreWCF.Channels; |
| | | 11 | | using CoreWCF.Description; |
| | | 12 | | using CoreWCF.Dispatcher; |
| | | 13 | | using CoreWCF.IdentityModel.Selectors; |
| | | 14 | | using CoreWCF.IdentityModel.Tokens; |
| | | 15 | | using CoreWCF.Runtime; |
| | | 16 | | using CoreWCF.Security.Tokens; |
| | | 17 | | |
| | | 18 | | namespace CoreWCF.Security |
| | | 19 | | { |
| | | 20 | | /* |
| | | 21 | | * See |
| | | 22 | | * http://xws/gxa/main/specs/security/security_profiles/SecurityProfiles.doc |
| | | 23 | | * for details on security protocols |
| | | 24 | | |
| | | 25 | | * Concrete implementations are required to me thread safe after |
| | | 26 | | * Open() is called; |
| | | 27 | | |
| | | 28 | | * instances of concrete protocol factories are scoped to a |
| | | 29 | | * channel/listener factory; |
| | | 30 | | |
| | | 31 | | * Each channel/listener factory must have a |
| | | 32 | | * SecurityProtocolFactory set on it before open/first use; the |
| | | 33 | | * factory instance cannot be changed once the factory is opened |
| | | 34 | | * or listening; |
| | | 35 | | |
| | | 36 | | * security protocol instances are scoped to a channel and will be |
| | | 37 | | * created by the Create calls on protocol factories; |
| | | 38 | | |
| | | 39 | | * security protocol instances are required to be thread-safe. |
| | | 40 | | |
| | | 41 | | * for typical subclasses, factory wide state and immutable |
| | | 42 | | * settings are expected to be on the ProtocolFactory itself while |
| | | 43 | | * channel-wide state is maintained internally in each security |
| | | 44 | | * protocol instance; |
| | | 45 | | |
| | | 46 | | * the security protocol instance set on a channel cannot be |
| | | 47 | | * changed; however, the protocol instance may change internal |
| | | 48 | | * state; this covers RM's SCT renego case; by keeping state |
| | | 49 | | * change internal to protocol instances, we get better |
| | | 50 | | * coordination with concurrent message security on channels; |
| | | 51 | | |
| | | 52 | | * the primary pivot in creating a security protocol instance is |
| | | 53 | | * initiator (client) vs. responder (server), NOT sender vs |
| | | 54 | | * receiver |
| | | 55 | | |
| | | 56 | | * Create calls for input and reply channels will contain the |
| | | 57 | | * listener-wide state (if any) created by the corresponding call |
| | | 58 | | * on the factory; |
| | | 59 | | |
| | | 60 | | */ |
| | | 61 | | |
| | | 62 | | // Whether we need to add support for targetting different SOAP roles is tracked by 19144 |
| | | 63 | | public abstract class SecurityProtocolFactory : ISecurityCommunicationObject |
| | | 64 | | { |
| | | 65 | | internal const bool defaultAddTimestamp = true; |
| | | 66 | | internal const bool defaultDeriveKeys = true; |
| | | 67 | | internal const bool defaultDetectReplays = true; |
| | | 68 | | internal const string defaultMaxClockSkewString = "00:05:00"; |
| | | 69 | | internal const string defaultReplayWindowString = "00:05:00"; |
| | 4 | 70 | | internal static readonly TimeSpan defaultMaxClockSkew = TimeSpan.Parse(defaultMaxClockSkewString, CultureInfo.In |
| | 4 | 71 | | internal static readonly TimeSpan defaultReplayWindow = TimeSpan.Parse(defaultReplayWindowString, CultureInfo.In |
| | | 72 | | internal const int defaultMaxCachedNonces = 900000; |
| | | 73 | | internal const string defaultTimestampValidityDurationString = "00:05:00"; |
| | 4 | 74 | | internal static readonly TimeSpan defaultTimestampValidityDuration = TimeSpan.Parse(defaultTimestampValidityDura |
| | | 75 | | internal const SecurityHeaderLayout defaultSecurityHeaderLayout = SecurityHeaderLayout.Strict; |
| | | 76 | | private static ReadOnlyCollection<SupportingTokenAuthenticatorSpecification> s_emptyTokenAuthenticators; |
| | 55 | 77 | | private bool _addTimestamp = defaultAddTimestamp; |
| | 55 | 78 | | private bool _detectReplays = defaultDetectReplays; |
| | 55 | 79 | | private SecurityAlgorithmSuite _incomingAlgorithmSuite = SecurityAlgorithmSuite.Default; |
| | | 80 | | private Dictionary<string, MergedSupportingTokenAuthenticatorSpecification> _mergedSupportingTokenAuthenticators |
| | 55 | 81 | | private int _maxCachedNonces = defaultMaxCachedNonces; |
| | 55 | 82 | | private TimeSpan _maxClockSkew = defaultMaxClockSkew; |
| | | 83 | | private NonceCache _nonceCache = null; |
| | 55 | 84 | | private SecurityAlgorithmSuite _outgoingAlgorithmSuite = SecurityAlgorithmSuite.Default; |
| | 55 | 85 | | private TimeSpan _replayWindow = defaultReplayWindow; |
| | 55 | 86 | | private SecurityStandardsManager _standardsManager = SecurityStandardsManager.DefaultInstance; |
| | | 87 | | private SecurityTokenManager _securityTokenManager; |
| | | 88 | | private SecurityBindingElement _securityBindingElement; |
| | | 89 | | private string _requestReplyErrorPropertyName; |
| | 55 | 90 | | private TimeSpan _timestampValidityDuration = defaultTimestampValidityDuration; |
| | | 91 | | |
| | | 92 | | // AuditLogLocation auditLogLocation; |
| | | 93 | | private readonly bool _suppressAuditFailure; |
| | | 94 | | private SecurityHeaderLayout _securityHeaderLayout; |
| | | 95 | | private bool _expectChannelBasicTokens; |
| | | 96 | | private bool _expectChannelSignedTokens; |
| | | 97 | | private bool _expectChannelEndorsingTokens; |
| | | 98 | | private Uri _listenUri; |
| | | 99 | | private Uri _privacyNoticeUri; |
| | | 100 | | private int _privacyNoticeVersion; |
| | | 101 | | private IMessageFilterTable<EndpointAddress> _endpointFilterTable; |
| | | 102 | | private BufferManager _streamBufferManager = null; |
| | | 103 | | |
| | 55 | 104 | | protected SecurityProtocolFactory() |
| | | 105 | | { |
| | 55 | 106 | | ChannelSupportingTokenAuthenticatorSpecification = new Collection<SupportingTokenAuthenticatorSpecification> |
| | 55 | 107 | | ScopedSupportingTokenAuthenticatorSpecification = new Dictionary<string, ICollection<SupportingTokenAuthenti |
| | 55 | 108 | | CommunicationObject = new WrapperSecurityCommunicationObject(this); |
| | 55 | 109 | | } |
| | | 110 | | |
| | 0 | 111 | | internal SecurityProtocolFactory(SecurityProtocolFactory factory) : this() |
| | | 112 | | { |
| | 0 | 113 | | if (factory == null) |
| | | 114 | | { |
| | 0 | 115 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(factory)); |
| | | 116 | | } |
| | | 117 | | |
| | 0 | 118 | | ActAsInitiator = factory.ActAsInitiator; |
| | 0 | 119 | | _addTimestamp = factory._addTimestamp; |
| | 0 | 120 | | _detectReplays = factory._detectReplays; |
| | 0 | 121 | | _incomingAlgorithmSuite = factory._incomingAlgorithmSuite; |
| | 0 | 122 | | _maxCachedNonces = factory._maxCachedNonces; |
| | 0 | 123 | | _maxClockSkew = factory._maxClockSkew; |
| | 0 | 124 | | _outgoingAlgorithmSuite = factory._outgoingAlgorithmSuite; |
| | 0 | 125 | | _replayWindow = factory._replayWindow; |
| | 0 | 126 | | ChannelSupportingTokenAuthenticatorSpecification = new Collection<SupportingTokenAuthenticatorSpecification> |
| | 0 | 127 | | ScopedSupportingTokenAuthenticatorSpecification = new Dictionary<string, ICollection<SupportingTokenAuthenti |
| | 0 | 128 | | _standardsManager = factory._standardsManager; |
| | 0 | 129 | | _timestampValidityDuration = factory._timestampValidityDuration; |
| | | 130 | | // this.auditLogLocation = factory.auditLogLocation; |
| | 0 | 131 | | _suppressAuditFailure = factory._suppressAuditFailure; |
| | | 132 | | // this.serviceAuthorizationAuditLevel = factory.serviceAuthorizationAuditLevel; |
| | | 133 | | // this.messageAuthenticationAuditLevel = factory.messageAuthenticationAuditLevel; |
| | 0 | 134 | | if (factory._securityBindingElement != null) |
| | | 135 | | { |
| | 0 | 136 | | _securityBindingElement = (SecurityBindingElement)factory._securityBindingElement.Clone(); |
| | | 137 | | } |
| | 0 | 138 | | _securityTokenManager = factory._securityTokenManager; |
| | 0 | 139 | | _privacyNoticeUri = factory._privacyNoticeUri; |
| | 0 | 140 | | _privacyNoticeVersion = factory._privacyNoticeVersion; |
| | 0 | 141 | | _endpointFilterTable = factory._endpointFilterTable; |
| | 0 | 142 | | ExtendedProtectionPolicy = factory.ExtendedProtectionPolicy; |
| | 0 | 143 | | _nonceCache = factory._nonceCache; |
| | 0 | 144 | | } |
| | | 145 | | |
| | 958 | 146 | | internal WrapperSecurityCommunicationObject CommunicationObject { get; } |
| | | 147 | | |
| | | 148 | | // The ActAsInitiator value is set automatically on Open and |
| | | 149 | | // remains unchanged thereafter. ActAsInitiator is true for |
| | | 150 | | // the initiator of the message exchange, such as the sender |
| | | 151 | | // of a datagram, sender of a request and sender of either leg |
| | | 152 | | // of a duplex exchange. |
| | 526 | 153 | | public bool ActAsInitiator { get; } |
| | | 154 | | |
| | | 155 | | public BufferManager StreamBufferManager |
| | | 156 | | { |
| | | 157 | | get |
| | | 158 | | { |
| | 63 | 159 | | if (_streamBufferManager == null) |
| | | 160 | | { |
| | 27 | 161 | | _streamBufferManager = BufferManager.CreateBufferManager(0, int.MaxValue); |
| | | 162 | | } |
| | | 163 | | |
| | 63 | 164 | | return _streamBufferManager; |
| | | 165 | | } |
| | | 166 | | set |
| | | 167 | | { |
| | 0 | 168 | | _streamBufferManager = value; |
| | 0 | 169 | | } |
| | | 170 | | } |
| | | 171 | | |
| | 204 | 172 | | public ExtendedProtectionPolicy ExtendedProtectionPolicy { get; set; } |
| | | 173 | | |
| | 0 | 174 | | internal bool IsDuplexReply { get; set; } |
| | | 175 | | |
| | | 176 | | public bool AddTimestamp |
| | | 177 | | { |
| | | 178 | | get |
| | | 179 | | { |
| | 126 | 180 | | return _addTimestamp; |
| | | 181 | | } |
| | | 182 | | set |
| | | 183 | | { |
| | 77 | 184 | | ThrowIfImmutable(); |
| | 77 | 185 | | _addTimestamp = value; |
| | 77 | 186 | | } |
| | | 187 | | } |
| | | 188 | | |
| | | 189 | | //public AuditLogLocation AuditLogLocation |
| | | 190 | | //{ |
| | | 191 | | // get |
| | | 192 | | // { |
| | | 193 | | // return this.auditLogLocation; |
| | | 194 | | // } |
| | | 195 | | // set |
| | | 196 | | // { |
| | | 197 | | // ThrowIfImmutable(); |
| | | 198 | | // AuditLogLocationHelper.Validate(value); |
| | | 199 | | // this.auditLogLocation = value; |
| | | 200 | | // } |
| | | 201 | | //} |
| | | 202 | | |
| | | 203 | | //public bool SuppressAuditFailure |
| | | 204 | | //{ |
| | | 205 | | // get |
| | | 206 | | // { |
| | | 207 | | // return this.suppressAuditFailure; |
| | | 208 | | // } |
| | | 209 | | // set |
| | | 210 | | // { |
| | | 211 | | // ThrowIfImmutable(); |
| | | 212 | | // this.suppressAuditFailure = value; |
| | | 213 | | // } |
| | | 214 | | //} |
| | | 215 | | |
| | | 216 | | //public AuditLevel ServiceAuthorizationAuditLevel |
| | | 217 | | //{ |
| | | 218 | | // get |
| | | 219 | | // { |
| | | 220 | | // return this.serviceAuthorizationAuditLevel; |
| | | 221 | | // } |
| | | 222 | | // set |
| | | 223 | | // { |
| | | 224 | | // ThrowIfImmutable(); |
| | | 225 | | // AuditLevelHelper.Validate(value); |
| | | 226 | | // this.serviceAuthorizationAuditLevel = value; |
| | | 227 | | // } |
| | | 228 | | //} |
| | | 229 | | |
| | | 230 | | //public AuditLevel MessageAuthenticationAuditLevel |
| | | 231 | | //{ |
| | | 232 | | // get |
| | | 233 | | // { |
| | | 234 | | // return this.messageAuthenticationAuditLevel; |
| | | 235 | | // } |
| | | 236 | | // set |
| | | 237 | | // { |
| | | 238 | | // ThrowIfImmutable(); |
| | | 239 | | // AuditLevelHelper.Validate(value); |
| | | 240 | | // this.messageAuthenticationAuditLevel = value; |
| | | 241 | | // } |
| | | 242 | | //} |
| | | 243 | | |
| | | 244 | | public bool DetectReplays |
| | | 245 | | { |
| | | 246 | | get |
| | | 247 | | { |
| | 149 | 248 | | return _detectReplays; |
| | | 249 | | } |
| | | 250 | | set |
| | | 251 | | { |
| | 88 | 252 | | ThrowIfImmutable(); |
| | 88 | 253 | | _detectReplays = value; |
| | 88 | 254 | | } |
| | | 255 | | } |
| | | 256 | | |
| | | 257 | | public Uri PrivacyNoticeUri |
| | | 258 | | { |
| | | 259 | | get |
| | | 260 | | { |
| | 0 | 261 | | return _privacyNoticeUri; |
| | | 262 | | } |
| | | 263 | | set |
| | | 264 | | { |
| | 0 | 265 | | ThrowIfImmutable(); |
| | 0 | 266 | | _privacyNoticeUri = value; |
| | 0 | 267 | | } |
| | | 268 | | } |
| | | 269 | | |
| | | 270 | | public int PrivacyNoticeVersion |
| | | 271 | | { |
| | | 272 | | get |
| | | 273 | | { |
| | 0 | 274 | | return _privacyNoticeVersion; |
| | | 275 | | } |
| | | 276 | | set |
| | | 277 | | { |
| | 0 | 278 | | ThrowIfImmutable(); |
| | 0 | 279 | | _privacyNoticeVersion = value; |
| | 0 | 280 | | } |
| | | 281 | | } |
| | | 282 | | |
| | | 283 | | internal IMessageFilterTable<EndpointAddress> EndpointFilterTable |
| | | 284 | | { |
| | | 285 | | get |
| | | 286 | | { |
| | 22 | 287 | | return _endpointFilterTable; |
| | | 288 | | } |
| | | 289 | | set |
| | | 290 | | { |
| | 0 | 291 | | ThrowIfImmutable(); |
| | 0 | 292 | | _endpointFilterTable = value; |
| | 0 | 293 | | } |
| | | 294 | | } |
| | | 295 | | |
| | | 296 | | private static ReadOnlyCollection<SupportingTokenAuthenticatorSpecification> EmptyTokenAuthenticators |
| | | 297 | | { |
| | | 298 | | get |
| | | 299 | | { |
| | 116 | 300 | | if (s_emptyTokenAuthenticators == null) |
| | | 301 | | { |
| | 3 | 302 | | s_emptyTokenAuthenticators = Array.AsReadOnly(Array.Empty<SupportingTokenAuthenticatorSpecification> |
| | | 303 | | } |
| | 116 | 304 | | return s_emptyTokenAuthenticators; |
| | | 305 | | } |
| | | 306 | | } |
| | | 307 | | |
| | 0 | 308 | | internal NonValidatingSecurityTokenAuthenticator<DerivedKeySecurityToken> DerivedKeyTokenAuthenticator { get; } |
| | | 309 | | |
| | 55 | 310 | | internal bool ExpectIncomingMessages { get; private set; } |
| | | 311 | | |
| | 55 | 312 | | internal bool ExpectOutgoingMessages { get; private set; } |
| | | 313 | | |
| | 74 | 314 | | internal bool ExpectKeyDerivation { get; set; } |
| | | 315 | | |
| | 55 | 316 | | internal bool ExpectSupportingTokens { get; set; } |
| | | 317 | | |
| | | 318 | | public SecurityAlgorithmSuite IncomingAlgorithmSuite |
| | | 319 | | { |
| | | 320 | | get |
| | | 321 | | { |
| | 171 | 322 | | return _incomingAlgorithmSuite; |
| | | 323 | | } |
| | | 324 | | set |
| | | 325 | | { |
| | 55 | 326 | | ThrowIfImmutable(); |
| | 55 | 327 | | _incomingAlgorithmSuite = value ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Argumen |
| | 55 | 328 | | } |
| | | 329 | | } |
| | | 330 | | |
| | | 331 | | public int MaxCachedNonces |
| | | 332 | | { |
| | | 333 | | get |
| | | 334 | | { |
| | 0 | 335 | | return _maxCachedNonces; |
| | | 336 | | } |
| | | 337 | | set |
| | | 338 | | { |
| | 55 | 339 | | ThrowIfImmutable(); |
| | 55 | 340 | | if (value <= 0) |
| | | 341 | | { |
| | 0 | 342 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 343 | | } |
| | 55 | 344 | | _maxCachedNonces = value; |
| | 55 | 345 | | } |
| | | 346 | | } |
| | | 347 | | |
| | | 348 | | public TimeSpan MaxClockSkew |
| | | 349 | | { |
| | | 350 | | get |
| | | 351 | | { |
| | 94 | 352 | | return _maxClockSkew; |
| | | 353 | | } |
| | | 354 | | set |
| | | 355 | | { |
| | 55 | 356 | | ThrowIfImmutable(); |
| | 55 | 357 | | if (value < TimeSpan.Zero) |
| | | 358 | | { |
| | 0 | 359 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 360 | | } |
| | 55 | 361 | | _maxClockSkew = value; |
| | 55 | 362 | | } |
| | | 363 | | } |
| | | 364 | | |
| | | 365 | | public NonceCache NonceCache |
| | | 366 | | { |
| | | 367 | | get |
| | | 368 | | { |
| | 94 | 369 | | return _nonceCache; |
| | | 370 | | } |
| | | 371 | | set |
| | | 372 | | { |
| | 0 | 373 | | ThrowIfImmutable(); |
| | 0 | 374 | | _nonceCache = value; |
| | 0 | 375 | | } |
| | | 376 | | } |
| | | 377 | | |
| | | 378 | | public SecurityAlgorithmSuite OutgoingAlgorithmSuite |
| | | 379 | | { |
| | | 380 | | get |
| | | 381 | | { |
| | 63 | 382 | | return _outgoingAlgorithmSuite; |
| | | 383 | | } |
| | | 384 | | set |
| | | 385 | | { |
| | 55 | 386 | | ThrowIfImmutable(); |
| | 55 | 387 | | _outgoingAlgorithmSuite = value ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Argumen |
| | 55 | 388 | | } |
| | | 389 | | } |
| | | 390 | | |
| | | 391 | | public TimeSpan ReplayWindow |
| | | 392 | | { |
| | | 393 | | get |
| | | 394 | | { |
| | 94 | 395 | | return _replayWindow; |
| | | 396 | | } |
| | | 397 | | set |
| | | 398 | | { |
| | 55 | 399 | | ThrowIfImmutable(); |
| | 55 | 400 | | if (value <= TimeSpan.Zero) |
| | | 401 | | { |
| | 0 | 402 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 403 | | } |
| | 55 | 404 | | _replayWindow = value; |
| | 55 | 405 | | } |
| | | 406 | | } |
| | | 407 | | |
| | 641 | 408 | | public ICollection<SupportingTokenAuthenticatorSpecification> ChannelSupportingTokenAuthenticatorSpecification { |
| | | 409 | | |
| | 121 | 410 | | public Dictionary<string, ICollection<SupportingTokenAuthenticatorSpecification>> ScopedSupportingTokenAuthentic |
| | | 411 | | |
| | | 412 | | public SecurityBindingElement SecurityBindingElement |
| | | 413 | | { |
| | 385 | 414 | | get { return _securityBindingElement; } |
| | | 415 | | set |
| | | 416 | | { |
| | 55 | 417 | | ThrowIfImmutable(); |
| | 55 | 418 | | if (value != null) |
| | | 419 | | { |
| | 55 | 420 | | value = (SecurityBindingElement)value.Clone(); |
| | | 421 | | } |
| | 55 | 422 | | _securityBindingElement = value; |
| | 55 | 423 | | } |
| | | 424 | | } |
| | | 425 | | |
| | | 426 | | internal SecurityTokenManager SecurityTokenManager |
| | | 427 | | { |
| | 209 | 428 | | get { return _securityTokenManager; } |
| | | 429 | | set |
| | | 430 | | { |
| | 77 | 431 | | ThrowIfImmutable(); |
| | 77 | 432 | | _securityTokenManager = value; |
| | 77 | 433 | | } |
| | | 434 | | } |
| | | 435 | | |
| | 0 | 436 | | public virtual bool SupportsDuplex => false; |
| | | 437 | | |
| | | 438 | | public SecurityHeaderLayout SecurityHeaderLayout |
| | | 439 | | { |
| | | 440 | | get |
| | | 441 | | { |
| | 147 | 442 | | return _securityHeaderLayout; |
| | | 443 | | } |
| | | 444 | | set |
| | | 445 | | { |
| | 55 | 446 | | ThrowIfImmutable(); |
| | 55 | 447 | | _securityHeaderLayout = value; |
| | 55 | 448 | | } |
| | | 449 | | } |
| | | 450 | | |
| | 0 | 451 | | public virtual bool SupportsReplayDetection => true; |
| | | 452 | | |
| | 55 | 453 | | public virtual bool SupportsRequestReply => true; |
| | | 454 | | |
| | | 455 | | internal SecurityStandardsManager StandardsManager |
| | | 456 | | { |
| | | 457 | | get |
| | | 458 | | { |
| | 296 | 459 | | return _standardsManager; |
| | | 460 | | } |
| | | 461 | | set |
| | | 462 | | { |
| | 55 | 463 | | ThrowIfImmutable(); |
| | 55 | 464 | | _standardsManager = value ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullE |
| | 55 | 465 | | } |
| | | 466 | | } |
| | | 467 | | |
| | | 468 | | public TimeSpan TimestampValidityDuration |
| | | 469 | | { |
| | | 470 | | get |
| | | 471 | | { |
| | 63 | 472 | | return _timestampValidityDuration; |
| | | 473 | | } |
| | | 474 | | set |
| | | 475 | | { |
| | 55 | 476 | | ThrowIfImmutable(); |
| | 55 | 477 | | if (value <= TimeSpan.Zero) |
| | | 478 | | { |
| | 0 | 479 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(val |
| | | 480 | | } |
| | 55 | 481 | | _timestampValidityDuration = value; |
| | 55 | 482 | | } |
| | | 483 | | } |
| | | 484 | | |
| | | 485 | | public Uri ListenUri |
| | | 486 | | { |
| | 22 | 487 | | get { return _listenUri; } |
| | | 488 | | set |
| | | 489 | | { |
| | 55 | 490 | | ThrowIfImmutable(); |
| | 55 | 491 | | _listenUri = value; |
| | 55 | 492 | | } |
| | | 493 | | } |
| | | 494 | | |
| | 132 | 495 | | internal MessageSecurityVersion MessageSecurityVersion { get; private set; } |
| | | 496 | | |
| | 110 | 497 | | public TimeSpan DefaultOpenTimeout => ServiceDefaults.OpenTimeout; |
| | | 498 | | |
| | 0 | 499 | | public TimeSpan DefaultCloseTimeout => ServiceDefaults.CloseTimeout; |
| | | 500 | | |
| | | 501 | | public virtual void OnAbort() |
| | | 502 | | { |
| | 0 | 503 | | if (!ActAsInitiator) |
| | | 504 | | { |
| | 0 | 505 | | foreach (SupportingTokenAuthenticatorSpecification spec in ChannelSupportingTokenAuthenticatorSpecificat |
| | | 506 | | { |
| | 0 | 507 | | SecurityUtils.AbortTokenAuthenticatorIfRequired(spec.TokenAuthenticator); |
| | | 508 | | } |
| | 0 | 509 | | foreach (string action in ScopedSupportingTokenAuthenticatorSpecification.Keys) |
| | | 510 | | { |
| | 0 | 511 | | ICollection<SupportingTokenAuthenticatorSpecification> supportingAuthenticators = ScopedSupportingTo |
| | 0 | 512 | | foreach (SupportingTokenAuthenticatorSpecification spec in supportingAuthenticators) |
| | | 513 | | { |
| | 0 | 514 | | SecurityUtils.AbortTokenAuthenticatorIfRequired(spec.TokenAuthenticator); |
| | | 515 | | } |
| | | 516 | | } |
| | | 517 | | } |
| | 0 | 518 | | } |
| | | 519 | | |
| | | 520 | | public virtual void OnClose(TimeSpan timeout) |
| | | 521 | | { |
| | 0 | 522 | | TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); |
| | 0 | 523 | | if (!ActAsInitiator) |
| | | 524 | | { |
| | 0 | 525 | | foreach (SupportingTokenAuthenticatorSpecification spec in ChannelSupportingTokenAuthenticatorSpecificat |
| | | 526 | | { |
| | 0 | 527 | | SecurityUtils.CloseTokenAuthenticatorIfRequiredAsync(spec.TokenAuthenticator, timeoutHelper.GetCance |
| | | 528 | | } |
| | 0 | 529 | | foreach (string action in ScopedSupportingTokenAuthenticatorSpecification.Keys) |
| | | 530 | | { |
| | 0 | 531 | | ICollection<SupportingTokenAuthenticatorSpecification> supportingAuthenticators = ScopedSupportingTo |
| | 0 | 532 | | foreach (SupportingTokenAuthenticatorSpecification spec in supportingAuthenticators) |
| | | 533 | | { |
| | 0 | 534 | | SecurityUtils.CloseTokenAuthenticatorIfRequiredAsync(spec.TokenAuthenticator, timeoutHelper.GetC |
| | | 535 | | } |
| | | 536 | | } |
| | | 537 | | } |
| | 0 | 538 | | } |
| | | 539 | | |
| | | 540 | | public virtual object CreateListenerSecurityState() |
| | | 541 | | { |
| | 0 | 542 | | return null; |
| | | 543 | | } |
| | | 544 | | |
| | | 545 | | internal SecurityProtocol CreateSecurityProtocol(EndpointAddress target, Uri via, bool isReturnLegSecurityRequir |
| | | 546 | | { |
| | 34 | 547 | | ThrowIfNotOpen(); |
| | 34 | 548 | | SecurityProtocol securityProtocol = OnCreateSecurityProtocol(target, via, timeout); |
| | 34 | 549 | | if (securityProtocol == null) |
| | | 550 | | { |
| | 0 | 551 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.ProtocolFactor |
| | | 552 | | } |
| | 34 | 553 | | return securityProtocol; |
| | | 554 | | } |
| | | 555 | | |
| | | 556 | | public virtual EndpointIdentity GetIdentityOfSelf() |
| | | 557 | | { |
| | 0 | 558 | | return null; |
| | | 559 | | } |
| | | 560 | | |
| | | 561 | | public virtual T GetProperty<T>() |
| | | 562 | | { |
| | 0 | 563 | | if (typeof(T) == typeof(Collection<ISecurityContextSecurityTokenCache>)) |
| | | 564 | | { |
| | 0 | 565 | | ThrowIfNotOpen(); |
| | 0 | 566 | | Collection<ISecurityContextSecurityTokenCache> result = new Collection<ISecurityContextSecurityTokenCach |
| | 0 | 567 | | if (ChannelSupportingTokenAuthenticatorSpecification != null) |
| | | 568 | | { |
| | 0 | 569 | | foreach (SupportingTokenAuthenticatorSpecification spec in ChannelSupportingTokenAuthenticatorSpecif |
| | | 570 | | { |
| | 0 | 571 | | if (spec.TokenAuthenticator is ISecurityContextSecurityTokenCacheProvider cacheProvider) |
| | | 572 | | { |
| | 0 | 573 | | result.Add(cacheProvider.TokenCache); |
| | | 574 | | } |
| | | 575 | | } |
| | | 576 | | } |
| | 0 | 577 | | return (T)(object)(result); |
| | | 578 | | } |
| | | 579 | | else |
| | | 580 | | { |
| | 0 | 581 | | return default; |
| | | 582 | | } |
| | | 583 | | } |
| | | 584 | | internal abstract SecurityProtocol OnCreateSecurityProtocol(EndpointAddress target, Uri via, TimeSpan timeout); |
| | | 585 | | |
| | | 586 | | private void VerifyTypeUniqueness(ICollection<SupportingTokenAuthenticatorSpecification> supportingTokenAuthenti |
| | | 587 | | { |
| | | 588 | | // its ok to go brute force here since we are dealing with a small number of authenticators |
| | 308 | 589 | | foreach (SupportingTokenAuthenticatorSpecification spec in supportingTokenAuthenticators) |
| | | 590 | | { |
| | 77 | 591 | | Type authenticatorType = spec.TokenAuthenticator.GetType(); |
| | 77 | 592 | | int numSkipped = 0; |
| | 396 | 593 | | foreach (SupportingTokenAuthenticatorSpecification spec2 in supportingTokenAuthenticators) |
| | | 594 | | { |
| | 121 | 595 | | Type spec2AuthenticatorType = spec2.TokenAuthenticator.GetType(); |
| | 121 | 596 | | if (ReferenceEquals(spec, spec2)) |
| | | 597 | | { |
| | 77 | 598 | | if (numSkipped > 0) |
| | | 599 | | { |
| | 0 | 600 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR |
| | | 601 | | } |
| | 77 | 602 | | ++numSkipped; |
| | 77 | 603 | | continue; |
| | | 604 | | } |
| | 44 | 605 | | else if (authenticatorType.IsAssignableFrom(spec2AuthenticatorType) || spec2AuthenticatorType.IsAssi |
| | | 606 | | { |
| | 0 | 607 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.Mul |
| | | 608 | | } |
| | | 609 | | } |
| | | 610 | | } |
| | 77 | 611 | | } |
| | | 612 | | |
| | | 613 | | internal IList<SupportingTokenAuthenticatorSpecification> GetSupportingTokenAuthenticators(string action, out bo |
| | | 614 | | { |
| | 94 | 615 | | if (_mergedSupportingTokenAuthenticatorsMap != null && _mergedSupportingTokenAuthenticatorsMap.Count > 0) |
| | | 616 | | { |
| | 13 | 617 | | if (action != null && _mergedSupportingTokenAuthenticatorsMap.ContainsKey(action)) |
| | | 618 | | { |
| | 0 | 619 | | MergedSupportingTokenAuthenticatorSpecification mergedSpec = _mergedSupportingTokenAuthenticatorsMap |
| | 0 | 620 | | expectSignedTokens = mergedSpec.ExpectSignedTokens; |
| | 0 | 621 | | expectBasicTokens = mergedSpec.ExpectBasicTokens; |
| | 0 | 622 | | expectEndorsingTokens = mergedSpec.ExpectEndorsingTokens; |
| | 0 | 623 | | return mergedSpec.SupportingTokenAuthenticators; |
| | | 624 | | } |
| | 13 | 625 | | else if (_mergedSupportingTokenAuthenticatorsMap.ContainsKey(MessageHeaders.WildcardAction)) |
| | | 626 | | { |
| | 0 | 627 | | MergedSupportingTokenAuthenticatorSpecification mergedSpec = _mergedSupportingTokenAuthenticatorsMap |
| | 0 | 628 | | expectSignedTokens = mergedSpec.ExpectSignedTokens; |
| | 0 | 629 | | expectBasicTokens = mergedSpec.ExpectBasicTokens; |
| | 0 | 630 | | expectEndorsingTokens = mergedSpec.ExpectEndorsingTokens; |
| | 0 | 631 | | return mergedSpec.SupportingTokenAuthenticators; |
| | | 632 | | } |
| | | 633 | | } |
| | 94 | 634 | | expectSignedTokens = _expectChannelSignedTokens; |
| | 94 | 635 | | expectBasicTokens = _expectChannelBasicTokens; |
| | 94 | 636 | | expectEndorsingTokens = _expectChannelEndorsingTokens; |
| | | 637 | | // in case the channelSupportingTokenAuthenticators is empty return null so that its Count does not get acce |
| | 94 | 638 | | return (ReferenceEquals(ChannelSupportingTokenAuthenticatorSpecification, EmptyTokenAuthenticators)) ? null |
| | | 639 | | } |
| | | 640 | | |
| | | 641 | | private void MergeSupportingTokenAuthenticators(TimeSpan timeout) |
| | | 642 | | { |
| | 55 | 643 | | if (ScopedSupportingTokenAuthenticatorSpecification.Count == 0) |
| | | 644 | | { |
| | 33 | 645 | | _mergedSupportingTokenAuthenticatorsMap = null; |
| | | 646 | | } |
| | | 647 | | else |
| | | 648 | | { |
| | 22 | 649 | | TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); |
| | 22 | 650 | | ExpectSupportingTokens = true; |
| | 22 | 651 | | _mergedSupportingTokenAuthenticatorsMap = new Dictionary<string, MergedSupportingTokenAuthenticatorSpeci |
| | 88 | 652 | | foreach (string action in ScopedSupportingTokenAuthenticatorSpecification.Keys) |
| | | 653 | | { |
| | 22 | 654 | | ICollection<SupportingTokenAuthenticatorSpecification> scopedAuthenticators = ScopedSupportingTokenA |
| | 22 | 655 | | if (scopedAuthenticators == null || scopedAuthenticators.Count == 0) |
| | | 656 | | { |
| | | 657 | | continue; |
| | | 658 | | } |
| | 22 | 659 | | Collection<SupportingTokenAuthenticatorSpecification> mergedAuthenticators = new Collection<Supporti |
| | 22 | 660 | | bool expectSignedTokens = _expectChannelSignedTokens; |
| | 22 | 661 | | bool expectBasicTokens = _expectChannelBasicTokens; |
| | 22 | 662 | | bool expectEndorsingTokens = _expectChannelEndorsingTokens; |
| | 88 | 663 | | foreach (SupportingTokenAuthenticatorSpecification spec in ChannelSupportingTokenAuthenticatorSpecif |
| | | 664 | | { |
| | 22 | 665 | | mergedAuthenticators.Add(spec); |
| | | 666 | | } |
| | 88 | 667 | | foreach (SupportingTokenAuthenticatorSpecification spec in scopedAuthenticators) |
| | | 668 | | { |
| | 22 | 669 | | SecurityUtils.OpenTokenAuthenticatorIfRequiredAsync(spec.TokenAuthenticator, timeoutHelper.GetCa |
| | | 670 | | |
| | 22 | 671 | | mergedAuthenticators.Add(spec); |
| | 22 | 672 | | if (spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endorsing || |
| | 22 | 673 | | spec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.SignedEndorsing) |
| | | 674 | | { |
| | 22 | 675 | | if (spec.TokenParameters.RequireDerivedKeys && !spec.TokenParameters.HasAsymmetricKey) |
| | | 676 | | { |
| | 0 | 677 | | ExpectKeyDerivation = true; |
| | | 678 | | } |
| | | 679 | | } |
| | 22 | 680 | | SecurityTokenAttachmentMode mode = spec.SecurityTokenAttachmentMode; |
| | 22 | 681 | | if (mode == SecurityTokenAttachmentMode.SignedEncrypted |
| | 22 | 682 | | || mode == SecurityTokenAttachmentMode.Signed |
| | 22 | 683 | | || mode == SecurityTokenAttachmentMode.SignedEndorsing) |
| | | 684 | | { |
| | 0 | 685 | | expectSignedTokens = true; |
| | 0 | 686 | | if (mode == SecurityTokenAttachmentMode.SignedEncrypted) |
| | | 687 | | { |
| | 0 | 688 | | expectBasicTokens = true; |
| | | 689 | | } |
| | | 690 | | } |
| | 22 | 691 | | if (mode == SecurityTokenAttachmentMode.Endorsing || mode == SecurityTokenAttachmentMode.SignedE |
| | | 692 | | { |
| | 22 | 693 | | expectEndorsingTokens = true; |
| | | 694 | | } |
| | | 695 | | } |
| | 22 | 696 | | VerifyTypeUniqueness(mergedAuthenticators); |
| | 22 | 697 | | MergedSupportingTokenAuthenticatorSpecification mergedSpec = new MergedSupportingTokenAuthenticatorS |
| | 22 | 698 | | { |
| | 22 | 699 | | SupportingTokenAuthenticators = mergedAuthenticators, |
| | 22 | 700 | | ExpectBasicTokens = expectBasicTokens, |
| | 22 | 701 | | ExpectEndorsingTokens = expectEndorsingTokens, |
| | 22 | 702 | | ExpectSignedTokens = expectSignedTokens |
| | 22 | 703 | | }; |
| | 22 | 704 | | _mergedSupportingTokenAuthenticatorsMap.Add(action, mergedSpec); |
| | | 705 | | } |
| | | 706 | | } |
| | 22 | 707 | | } |
| | | 708 | | |
| | | 709 | | protected RecipientServiceModelSecurityTokenRequirement CreateRecipientSecurityTokenRequirement() |
| | | 710 | | { |
| | 55 | 711 | | RecipientServiceModelSecurityTokenRequirement requirement = new RecipientServiceModelSecurityTokenRequiremen |
| | 55 | 712 | | { |
| | 55 | 713 | | SecurityBindingElement = _securityBindingElement, |
| | 55 | 714 | | SecurityAlgorithmSuite = IncomingAlgorithmSuite, |
| | 55 | 715 | | ListenUri = _listenUri, |
| | 55 | 716 | | MessageSecurityVersion = MessageSecurityVersion.SecurityTokenVersion |
| | 55 | 717 | | }; |
| | | 718 | | // requirement.AuditLogLocation = this.auditLogLocation; |
| | | 719 | | // requirement.SuppressAuditFailure = this.suppressAuditFailure; |
| | | 720 | | // requirement.MessageAuthenticationAuditLevel = this.messageAuthenticationAuditLevel; |
| | 55 | 721 | | requirement.Properties[ServiceModelSecurityTokenRequirement.ExtendedProtectionPolicy] = ExtendedProtectionPo |
| | 55 | 722 | | if (_endpointFilterTable != null) |
| | | 723 | | { |
| | 0 | 724 | | requirement.Properties.Add(ServiceModelSecurityTokenRequirement.EndpointFilterTableProperty, _endpointFi |
| | | 725 | | } |
| | 55 | 726 | | return requirement; |
| | | 727 | | } |
| | | 728 | | |
| | | 729 | | private RecipientServiceModelSecurityTokenRequirement CreateRecipientSecurityTokenRequirement(SecurityTokenParam |
| | | 730 | | { |
| | 55 | 731 | | RecipientServiceModelSecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement(); |
| | 55 | 732 | | parameters.InitializeSecurityTokenRequirement(requirement); |
| | 55 | 733 | | requirement.KeyUsage = SecurityKeyUsage.Signature; |
| | 55 | 734 | | requirement.Properties[ServiceModelSecurityTokenRequirement.MessageDirectionProperty] = MessageDirection.Inp |
| | 55 | 735 | | requirement.Properties[ServiceModelSecurityTokenRequirement.SupportingTokenAttachmentModeProperty] = attachm |
| | 55 | 736 | | requirement.Properties[ServiceModelSecurityTokenRequirement.ExtendedProtectionPolicy] = ExtendedProtectionPo |
| | 55 | 737 | | return requirement; |
| | | 738 | | } |
| | | 739 | | |
| | | 740 | | private void AddSupportingTokenAuthenticators(SupportingTokenParameters supportingTokenParameters, bool isOption |
| | | 741 | | { |
| | 332 | 742 | | for (int i = 0; i < supportingTokenParameters.Endorsing.Count; ++i) |
| | | 743 | | { |
| | 34 | 744 | | SecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement(supportingTokenParameters |
| | | 745 | | try |
| | | 746 | | { |
| | 34 | 747 | | CoreWCF.IdentityModel.Selectors.SecurityTokenAuthenticator authenticator = SecurityTokenManager.Crea |
| | 34 | 748 | | SupportingTokenAuthenticatorSpecification authenticatorSpec = new SupportingTokenAuthenticatorSpecif |
| | 34 | 749 | | authenticatorSpecList.Add(authenticatorSpec); |
| | 34 | 750 | | } |
| | 0 | 751 | | catch (Exception e) |
| | | 752 | | { |
| | 0 | 753 | | if (!isOptional || Fx.IsFatal(e)) |
| | | 754 | | { |
| | 0 | 755 | | throw; |
| | | 756 | | } |
| | 0 | 757 | | } |
| | | 758 | | } |
| | 264 | 759 | | for (int i = 0; i < supportingTokenParameters.SignedEndorsing.Count; ++i) |
| | | 760 | | { |
| | 0 | 761 | | SecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement(supportingTokenParameters |
| | | 762 | | try |
| | | 763 | | { |
| | 0 | 764 | | CoreWCF.IdentityModel.Selectors.SecurityTokenAuthenticator authenticator = SecurityTokenManager.Crea |
| | 0 | 765 | | SupportingTokenAuthenticatorSpecification authenticatorSpec = new SupportingTokenAuthenticatorSpecif |
| | 0 | 766 | | authenticatorSpecList.Add(authenticatorSpec); |
| | 0 | 767 | | } |
| | 0 | 768 | | catch (Exception e) |
| | | 769 | | { |
| | 0 | 770 | | if (!isOptional || Fx.IsFatal(e)) |
| | | 771 | | { |
| | 0 | 772 | | throw; |
| | | 773 | | } |
| | 0 | 774 | | } |
| | | 775 | | } |
| | 302 | 776 | | for (int i = 0; i < supportingTokenParameters.SignedEncrypted.Count; ++i) |
| | | 777 | | { |
| | 19 | 778 | | SecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement(supportingTokenParameters |
| | | 779 | | try |
| | | 780 | | { |
| | 19 | 781 | | CoreWCF.IdentityModel.Selectors.SecurityTokenAuthenticator authenticator = SecurityTokenManager.Crea |
| | 19 | 782 | | SupportingTokenAuthenticatorSpecification authenticatorSpec = new SupportingTokenAuthenticatorSpecif |
| | 19 | 783 | | authenticatorSpecList.Add(authenticatorSpec); |
| | 19 | 784 | | } |
| | 0 | 785 | | catch (Exception e) |
| | | 786 | | { |
| | 0 | 787 | | if (!isOptional || Fx.IsFatal(e)) |
| | | 788 | | { |
| | 0 | 789 | | throw; |
| | | 790 | | } |
| | 0 | 791 | | } |
| | | 792 | | } |
| | 268 | 793 | | for (int i = 0; i < supportingTokenParameters.Signed.Count; ++i) |
| | | 794 | | { |
| | 2 | 795 | | SecurityTokenRequirement requirement = CreateRecipientSecurityTokenRequirement(supportingTokenParameters |
| | | 796 | | try |
| | | 797 | | { |
| | 2 | 798 | | CoreWCF.IdentityModel.Selectors.SecurityTokenAuthenticator authenticator = SecurityTokenManager.Crea |
| | 2 | 799 | | SupportingTokenAuthenticatorSpecification authenticatorSpec = new SupportingTokenAuthenticatorSpecif |
| | 2 | 800 | | authenticatorSpecList.Add(authenticatorSpec); |
| | 2 | 801 | | } |
| | 0 | 802 | | catch (Exception e) |
| | | 803 | | { |
| | 0 | 804 | | if (!isOptional || Fx.IsFatal(e)) |
| | | 805 | | { |
| | 0 | 806 | | throw; |
| | | 807 | | } |
| | 0 | 808 | | } |
| | | 809 | | } |
| | 132 | 810 | | } |
| | | 811 | | |
| | | 812 | | public Task OpenAsync(TimeSpan timeout) |
| | | 813 | | { |
| | 55 | 814 | | return CommunicationObject.OpenAsync(); |
| | | 815 | | } |
| | | 816 | | |
| | | 817 | | public virtual Task OnOpenAsync(TimeSpan timeout) |
| | | 818 | | { |
| | 55 | 819 | | if (SecurityBindingElement == null) |
| | | 820 | | { |
| | 0 | 821 | | OnPropertySettingsError(nameof(SecurityBindingElement), true); |
| | | 822 | | } |
| | 55 | 823 | | if (SecurityTokenManager == null) |
| | | 824 | | { |
| | 0 | 825 | | OnPropertySettingsError(nameof(SecurityTokenManager), true); |
| | | 826 | | } |
| | 55 | 827 | | MessageSecurityVersion = _standardsManager.MessageSecurityVersion; |
| | 55 | 828 | | TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); |
| | 55 | 829 | | ExpectOutgoingMessages = ActAsInitiator || SupportsRequestReply; |
| | 55 | 830 | | ExpectIncomingMessages = !ActAsInitiator || SupportsRequestReply; |
| | 55 | 831 | | if (!ActAsInitiator) |
| | | 832 | | { |
| | 55 | 833 | | AddSupportingTokenAuthenticators(_securityBindingElement.EndpointSupportingTokenParameters, false, (ILis |
| | 55 | 834 | | AddSupportingTokenAuthenticators(_securityBindingElement.OptionalEndpointSupportingTokenParameters, true |
| | 154 | 835 | | foreach (string action in _securityBindingElement.OperationSupportingTokenParameters.Keys) |
| | | 836 | | { |
| | 22 | 837 | | Collection<SupportingTokenAuthenticatorSpecification> authenticatorSpecList = new Collection<Support |
| | 22 | 838 | | AddSupportingTokenAuthenticators(_securityBindingElement.OperationSupportingTokenParameters[action], |
| | 22 | 839 | | ScopedSupportingTokenAuthenticatorSpecification.Add(action, authenticatorSpecList); |
| | | 840 | | } |
| | 110 | 841 | | foreach (string action in _securityBindingElement.OptionalOperationSupportingTokenParameters.Keys) |
| | | 842 | | { |
| | | 843 | | Collection<SupportingTokenAuthenticatorSpecification> authenticatorSpecList; |
| | 0 | 844 | | if (ScopedSupportingTokenAuthenticatorSpecification.TryGetValue(action, out ICollection<SupportingTo |
| | | 845 | | { |
| | 0 | 846 | | authenticatorSpecList = ((Collection<SupportingTokenAuthenticatorSpecification>)existingList); |
| | | 847 | | } |
| | | 848 | | else |
| | | 849 | | { |
| | 0 | 850 | | authenticatorSpecList = new Collection<SupportingTokenAuthenticatorSpecification>(); |
| | 0 | 851 | | ScopedSupportingTokenAuthenticatorSpecification.Add(action, authenticatorSpecList); |
| | | 852 | | } |
| | 0 | 853 | | AddSupportingTokenAuthenticators(_securityBindingElement.OptionalOperationSupportingTokenParameters[ |
| | | 854 | | } |
| | | 855 | | // validate the token authenticator types and create a merged map if needed. |
| | 55 | 856 | | if (!ChannelSupportingTokenAuthenticatorSpecification.IsReadOnly) |
| | | 857 | | { |
| | 55 | 858 | | if (ChannelSupportingTokenAuthenticatorSpecification.Count == 0) |
| | | 859 | | { |
| | 22 | 860 | | ChannelSupportingTokenAuthenticatorSpecification = EmptyTokenAuthenticators; |
| | | 861 | | } |
| | | 862 | | else |
| | | 863 | | { |
| | 33 | 864 | | ExpectSupportingTokens = true; |
| | 132 | 865 | | foreach (SupportingTokenAuthenticatorSpecification tokenAuthenticatorSpec in ChannelSupportingTo |
| | | 866 | | { |
| | 33 | 867 | | SecurityUtils.OpenTokenAuthenticatorIfRequiredAsync(tokenAuthenticatorSpec.TokenAuthenticato |
| | 33 | 868 | | if (tokenAuthenticatorSpec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Endors |
| | 33 | 869 | | || tokenAuthenticatorSpec.SecurityTokenAttachmentMode == SecurityTokenAttachmentMode.Sig |
| | | 870 | | { |
| | 12 | 871 | | if (tokenAuthenticatorSpec.TokenParameters.RequireDerivedKeys && !tokenAuthenticatorSpec |
| | | 872 | | { |
| | 0 | 873 | | ExpectKeyDerivation = true; |
| | | 874 | | } |
| | | 875 | | } |
| | 33 | 876 | | SecurityTokenAttachmentMode mode = tokenAuthenticatorSpec.SecurityTokenAttachmentMode; |
| | 33 | 877 | | if (mode == SecurityTokenAttachmentMode.SignedEncrypted |
| | 33 | 878 | | || mode == SecurityTokenAttachmentMode.Signed |
| | 33 | 879 | | || mode == SecurityTokenAttachmentMode.SignedEndorsing) |
| | | 880 | | { |
| | 21 | 881 | | _expectChannelSignedTokens = true; |
| | 21 | 882 | | if (mode == SecurityTokenAttachmentMode.SignedEncrypted) |
| | | 883 | | { |
| | 19 | 884 | | _expectChannelBasicTokens = true; |
| | | 885 | | } |
| | | 886 | | } |
| | 33 | 887 | | if (mode == SecurityTokenAttachmentMode.Endorsing || mode == SecurityTokenAttachmentMode.Sig |
| | | 888 | | { |
| | 12 | 889 | | _expectChannelEndorsingTokens = true; |
| | | 890 | | } |
| | | 891 | | } |
| | 33 | 892 | | ChannelSupportingTokenAuthenticatorSpecification = |
| | 33 | 893 | | new ReadOnlyCollection<SupportingTokenAuthenticatorSpecification>((Collection<SupportingToke |
| | | 894 | | } |
| | | 895 | | } |
| | 55 | 896 | | VerifyTypeUniqueness(ChannelSupportingTokenAuthenticatorSpecification); |
| | 55 | 897 | | MergeSupportingTokenAuthenticators(timeoutHelper.RemainingTime()); |
| | | 898 | | } |
| | | 899 | | |
| | 55 | 900 | | if (DetectReplays) |
| | | 901 | | { |
| | 0 | 902 | | if (!SupportsReplayDetection) |
| | | 903 | | { |
| | 0 | 904 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(nameof(DetectReplays), SR.Format(SR.Sec |
| | | 905 | | } |
| | 0 | 906 | | if (MaxClockSkew == TimeSpan.MaxValue || ReplayWindow == TimeSpan.MaxValue) |
| | | 907 | | { |
| | 0 | 908 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.NoncesCac |
| | | 909 | | } |
| | | 910 | | |
| | | 911 | | // If DetectReplays is true and nonceCache is null then use the default InMemoryNonceCache. |
| | 0 | 912 | | if (_nonceCache == null) |
| | | 913 | | { |
| | | 914 | | //TODO below (InMemoryNonceCache) is coming along with WindowsAuth, so uncomment |
| | | 915 | | // The nonce needs to be cached for replayWindow + 2*clockSkew to eliminate replays |
| | | 916 | | // this.nonceCache = new InMemoryNonceCache(this.ReplayWindow + this.MaxClockSkew + this.MaxClockSke |
| | | 917 | | } |
| | | 918 | | } |
| | | 919 | | |
| | | 920 | | //this.derivedKeyTokenAuthenticator = new NonValidatingSecurityTokenAuthenticator<DerivedKeySecurityToken>() |
| | 55 | 921 | | return Task.CompletedTask; |
| | | 922 | | } |
| | | 923 | | |
| | | 924 | | public virtual Task OnCloseAsync(TimeSpan timeout) |
| | | 925 | | { |
| | 0 | 926 | | OnClose(timeout); |
| | 0 | 927 | | return Task.CompletedTask; |
| | | 928 | | } |
| | | 929 | | |
| | | 930 | | |
| | | 931 | | internal void Open(string propertyName, bool requiredForForwardDirection, SecurityTokenAuthenticator authenticat |
| | | 932 | | { |
| | 0 | 933 | | if (authenticator != null) |
| | | 934 | | { |
| | 0 | 935 | | TimeoutHelper helper = new TimeoutHelper(timeout); |
| | 0 | 936 | | SecurityUtils.OpenTokenAuthenticatorIfRequiredAsync(authenticator, helper.GetCancellationToken()); |
| | | 937 | | } |
| | | 938 | | else |
| | | 939 | | { |
| | 0 | 940 | | OnPropertySettingsError(propertyName, requiredForForwardDirection); |
| | | 941 | | } |
| | 0 | 942 | | } |
| | | 943 | | |
| | | 944 | | internal void Open(string propertyName, bool requiredForForwardDirection, SecurityTokenProvider provider, TimeSp |
| | | 945 | | { |
| | 0 | 946 | | if (provider != null) |
| | | 947 | | { |
| | 0 | 948 | | SecurityUtils.OpenTokenProviderIfRequiredAsync(provider, new TimeoutHelper(timeout).GetCancellationToken |
| | | 949 | | } |
| | | 950 | | else |
| | | 951 | | { |
| | 0 | 952 | | OnPropertySettingsError(propertyName, requiredForForwardDirection); |
| | | 953 | | } |
| | 0 | 954 | | } |
| | | 955 | | |
| | | 956 | | internal void OnPropertySettingsError(string propertyName, bool requiredForForwardDirection) |
| | | 957 | | { |
| | 0 | 958 | | if (requiredForForwardDirection) |
| | | 959 | | { |
| | 0 | 960 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException( |
| | 0 | 961 | | SR.Format(SR.PropertySettingErrorOnProtocolFactory, propertyName, this), |
| | 0 | 962 | | propertyName)); |
| | | 963 | | } |
| | 0 | 964 | | else if (_requestReplyErrorPropertyName == null) |
| | | 965 | | { |
| | 0 | 966 | | _requestReplyErrorPropertyName = propertyName; |
| | | 967 | | } |
| | 0 | 968 | | } |
| | | 969 | | |
| | | 970 | | internal void ThrowIfImmutable() |
| | | 971 | | { |
| | 836 | 972 | | CommunicationObject.ThrowIfDisposedOrImmutable(); |
| | 836 | 973 | | } |
| | | 974 | | |
| | | 975 | | private void ThrowIfNotOpen() |
| | | 976 | | { |
| | 34 | 977 | | CommunicationObject.ThrowIfNotOpened(); |
| | 34 | 978 | | } |
| | | 979 | | |
| | | 980 | | public void OnClosed() |
| | | 981 | | { |
| | 0 | 982 | | throw new NotImplementedException(); |
| | | 983 | | } |
| | | 984 | | |
| | | 985 | | public void OnClosing() |
| | | 986 | | { |
| | 0 | 987 | | throw new NotImplementedException(); |
| | | 988 | | } |
| | | 989 | | |
| | | 990 | | public void OnFaulted() |
| | | 991 | | { |
| | 0 | 992 | | throw new NotImplementedException(); |
| | | 993 | | } |
| | | 994 | | |
| | | 995 | | public void OnOpened() |
| | | 996 | | { |
| | 0 | 997 | | throw new NotImplementedException(); |
| | | 998 | | } |
| | | 999 | | |
| | | 1000 | | public void OnOpening() |
| | | 1001 | | { |
| | 0 | 1002 | | throw new NotImplementedException(); |
| | | 1003 | | } |
| | | 1004 | | } |
| | | 1005 | | |
| | | 1006 | | internal struct MergedSupportingTokenAuthenticatorSpecification |
| | | 1007 | | { |
| | | 1008 | | public Collection<SupportingTokenAuthenticatorSpecification> SupportingTokenAuthenticators; |
| | | 1009 | | public bool ExpectSignedTokens; |
| | | 1010 | | public bool ExpectEndorsingTokens; |
| | | 1011 | | public bool ExpectBasicTokens; |
| | | 1012 | | } |
| | | 1013 | | } |