1 // 2 // SecurityReplyChannel.cs 3 // 4 // Author: 5 // Atsushi Enomoto <atsushi@ximian.com> 6 // 7 // Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining 10 // a copy of this software and associated documentation files (the 11 // "Software"), to deal in the Software without restriction, including 12 // without limitation the rights to use, copy, modify, merge, publish, 13 // distribute, sublicense, and/or sell copies of the Software, and to 14 // permit persons to whom the Software is furnished to do so, subject to 15 // the following conditions: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 // 28 using System.Collections.Generic; 29 using System.Collections.ObjectModel; 30 using System.Net.Security; 31 using System.IdentityModel.Selectors; 32 using System.IdentityModel.Tokens; 33 using System.Security.Cryptography.X509Certificates; 34 using System.ServiceModel; 35 using System.ServiceModel.Channels; 36 using System.ServiceModel.Description; 37 using System.ServiceModel.Security; 38 using System.ServiceModel.Security.Tokens; 39 40 namespace System.ServiceModel.Channels.Security 41 { 42 internal class SecurityReplyChannel : InternalReplyChannelBase 43 { 44 IReplyChannel inner; 45 SecurityReplyChannel( SecurityChannelListener<IReplyChannel> source, IReplyChannel innerChannel)46 public SecurityReplyChannel ( 47 SecurityChannelListener<IReplyChannel> source, 48 IReplyChannel innerChannel) 49 : base (source) 50 { 51 this.inner = innerChannel; 52 } 53 54 public SecurityChannelListener<IReplyChannel> Source { 55 get { return (SecurityChannelListener<IReplyChannel>) Listener; } 56 } 57 58 // IReplyChannel 59 OnOpen(TimeSpan timeout)60 protected override void OnOpen (TimeSpan timeout) 61 { 62 inner.Open (timeout); 63 } 64 OnClose(TimeSpan timeout)65 protected override void OnClose (TimeSpan timeout) 66 { 67 inner.Close (timeout); 68 } 69 ReceiveRequest(TimeSpan timeout)70 public override RequestContext ReceiveRequest (TimeSpan timeout) 71 { 72 RequestContext ctx; 73 if (TryReceiveRequest (timeout, out ctx)) 74 return ctx; 75 throw new TimeoutException ("Failed to receive request context"); 76 } 77 TryReceiveRequest(TimeSpan timeout, out RequestContext context)78 public override bool TryReceiveRequest (TimeSpan timeout, out RequestContext context) 79 { 80 DateTime start = DateTime.UtcNow; 81 82 if (!inner.TryReceiveRequest (timeout, out context)) 83 return false; 84 if (context == null) 85 return true; 86 87 Message req, res; 88 req = context.RequestMessage; 89 switch (req.Headers.Action) { 90 case Constants.WstIssueAction: 91 case Constants.WstIssueReplyAction: 92 case Constants.WstRenewAction: 93 case Constants.WstCancelAction: 94 case Constants.WstValidateAction: 95 var support = Source.SecuritySupport; 96 var commAuth = support.TokenAuthenticator as CommunicationSecurityTokenAuthenticator; 97 if (commAuth != null) 98 res = commAuth.Communication.ProcessNegotiation (req, timeout - (DateTime.UtcNow - start)); 99 else 100 throw new MessageSecurityException ("This reply channel does not expect incoming WS-Trust requests"); 101 102 context.Reply (res, timeout - (DateTime.UtcNow - start)); 103 context.Close (timeout - (DateTime.UtcNow - start)); 104 // wait for another incoming message 105 return TryReceiveRequest (timeout - (DateTime.UtcNow - start), out context); 106 107 break; 108 } 109 110 context = new SecurityRequestContext (this, context); 111 return true; 112 } 113 114 [MonoTODO] WaitForRequest(TimeSpan timeout)115 public override bool WaitForRequest (TimeSpan timeout) 116 { 117 throw new NotImplementedException (); 118 } 119 120 // IChannel 121 GetProperty()122 public override T GetProperty<T> () 123 { 124 // FIXME: implement 125 return inner.GetProperty<T> (); 126 } 127 } 128 } 129