1 // 2 // SecurityRequestChannel.cs 3 // 4 // Author: 5 // Atsushi Enomoto <atsushi@ximian.com> 6 // 7 // Copyright (C) 2006 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 29 using System; 30 using System.Collections.Generic; 31 using System.Collections.ObjectModel; 32 using System.IdentityModel.Selectors; 33 using System.IdentityModel.Tokens; 34 using System.Runtime.Serialization; 35 using System.Security.Cryptography; 36 using System.Security.Cryptography.X509Certificates; 37 using System.Security.Cryptography.Xml; 38 using System.ServiceModel; 39 using System.ServiceModel.Channels; 40 using System.ServiceModel.Description; 41 using System.ServiceModel.Security; 42 using System.ServiceModel.Security.Tokens; 43 using System.Xml; 44 using System.Xml.XPath; 45 46 using ReqType = System.ServiceModel.Security.Tokens.ServiceModelSecurityTokenRequirement; 47 48 namespace System.ServiceModel.Channels.Security 49 { 50 class SecurityDuplexSession : DuplexSessionBase 51 { 52 SecurityDuplexSessionChannel channel; 53 SecurityDuplexSession(SecurityDuplexSessionChannel channel)54 public SecurityDuplexSession (SecurityDuplexSessionChannel channel) 55 { 56 this.channel = channel; 57 } 58 59 public override TimeSpan DefaultCloseTimeout { 60 get { return channel.DefaultCloseTimeout; } 61 } 62 Close(TimeSpan timeout)63 public override void Close (TimeSpan timeout) 64 { 65 // valid only if the inner channel is ISessionChannel 66 var d = channel.Channel as IDuplexSessionChannel; 67 if (d != null) 68 d.Session.CloseOutputSession (timeout); 69 } 70 } 71 72 class SecurityDuplexSessionChannel : DuplexChannelBase, IDuplexSessionChannel 73 { 74 IChannel channel; 75 InitiatorMessageSecurityBindingSupport security_initiator; 76 RecipientMessageSecurityBindingSupport security_recipient; 77 SecurityDuplexSession session; 78 SecurityDuplexSessionChannel(ChannelFactoryBase factory, IChannel innerChannel, EndpointAddress remoteAddress, Uri via, InitiatorMessageSecurityBindingSupport security)79 public SecurityDuplexSessionChannel (ChannelFactoryBase factory, IChannel innerChannel, EndpointAddress remoteAddress, Uri via, InitiatorMessageSecurityBindingSupport security) 80 : base (factory, remoteAddress, via) 81 { 82 this.channel = innerChannel; 83 session = new SecurityDuplexSession (this); 84 InitializeSecurityFunctionality (security); 85 } 86 SecurityDuplexSessionChannel(ChannelListenerBase listener, IChannel innerChannel, RecipientMessageSecurityBindingSupport security)87 public SecurityDuplexSessionChannel (ChannelListenerBase listener, IChannel innerChannel, RecipientMessageSecurityBindingSupport security) 88 : base (listener) 89 { 90 this.channel = innerChannel; 91 session = new SecurityDuplexSession (this); 92 InitializeSecurityFunctionality (security); 93 } 94 95 public IChannel Channel { 96 get { return channel; } 97 } 98 99 public IDuplexSession Session { 100 get { return session; } 101 } 102 InitializeSecurityFunctionality(InitiatorMessageSecurityBindingSupport security)103 void InitializeSecurityFunctionality (InitiatorMessageSecurityBindingSupport security) 104 { 105 security_initiator = security; 106 } 107 InitializeSecurityFunctionality(RecipientMessageSecurityBindingSupport security)108 void InitializeSecurityFunctionality (RecipientMessageSecurityBindingSupport security) 109 { 110 security_recipient = security; 111 } 112 OnOpen(TimeSpan timeout)113 protected override void OnOpen (TimeSpan timeout) 114 { 115 channel.Open (timeout); 116 if (security_initiator != null) 117 security_initiator.Prepare ((ChannelFactoryBase) Manager, RemoteAddress); 118 else 119 security_recipient.Prepare ((ChannelListenerBase) Manager, LocalAddress.Uri); 120 } 121 OnClose(TimeSpan timeout)122 protected override void OnClose (TimeSpan timeout) 123 { 124 if (security_initiator != null) 125 security_initiator.Release (); 126 else 127 security_recipient.Release (); 128 channel.Close (timeout); 129 } 130 OnAbort()131 protected override void OnAbort () 132 { 133 if (security_initiator != null) 134 security_initiator.Release (); 135 else 136 security_recipient.Release (); 137 channel.Abort (); 138 } 139 TryReceive(TimeSpan timeout, out Message message)140 public override bool TryReceive (TimeSpan timeout, out Message message) 141 { 142 ThrowIfDisposedOrNotOpen (); 143 var input = (IInputChannel) channel; 144 if (!input.TryReceive (timeout, out message)) 145 return false; 146 message = DecryptMessage (message); 147 return true; 148 } 149 WaitForMessage(TimeSpan timeout)150 public override bool WaitForMessage (TimeSpan timeout) 151 { 152 var input = (IInputChannel) channel; 153 return input.WaitForMessage (timeout); 154 } 155 Send(Message message)156 public override void Send (Message message) 157 { 158 Send (message, DefaultSendTimeout); 159 } 160 Send(Message message, TimeSpan timeout)161 public override void Send (Message message, TimeSpan timeout) 162 { 163 Message secure = SecureMessage (message); 164 var output = (IOutputChannel) channel; 165 output.Send (secure, timeout); 166 } 167 SecureMessage(Message msg)168 Message SecureMessage (Message msg) 169 { 170 if (security_initiator != null) 171 return new InitiatorMessageSecurityGenerator (msg, security_initiator, RemoteAddress).SecureMessage (); 172 else 173 return new RecipientMessageSecurityGenerator (msg, null, security_recipient).SecureMessage (); // FIXME: supply SecurityMessageProperty (if any) 174 } 175 DecryptMessage(Message msg)176 Message DecryptMessage (Message msg) 177 { 178 if (security_initiator != null) 179 return new InitiatorSecureMessageDecryptor (msg, null, security_initiator).DecryptMessage (); // FIXME: supply SecurityMessageProperty (if any) 180 else 181 return new RecipientSecureMessageDecryptor (msg, security_recipient).DecryptMessage (); 182 } 183 } 184 } 185 186