2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System.ServiceModel / System.ServiceModel.Security / ChannelProtectionRequirements.cs
blobf2802a088b4cbafa17e8c5eec2bfe456e8d02ab4
1 //
2 // ChannelProtectionRequirements.cs
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005-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.
28 using System;
29 using System.Net.Security;
30 using System.Collections.Generic;
31 using System.ServiceModel;
32 using System.ServiceModel.Description;
33 using System.Xml;
35 namespace System.ServiceModel.Security
37 // Represents sp:SignedParts and sp:EncryptedParts in
38 // sp:SupportingTokens/ws:Policy/.
39 public class ChannelProtectionRequirements
41 bool is_readonly;
42 ScopedMessagePartSpecification in_enc, in_sign, out_enc, out_sign;
44 public ChannelProtectionRequirements ()
46 in_enc = new ScopedMessagePartSpecification ();
47 out_enc = new ScopedMessagePartSpecification ();
48 in_sign = new ScopedMessagePartSpecification ();
49 out_sign = new ScopedMessagePartSpecification ();
52 public ChannelProtectionRequirements (
53 ChannelProtectionRequirements other)
55 if (other == null)
56 throw new ArgumentNullException ("other");
57 in_enc = new ScopedMessagePartSpecification (other.in_enc);
58 out_enc = new ScopedMessagePartSpecification (other.out_enc);
59 in_sign = new ScopedMessagePartSpecification (other.in_sign);
60 out_sign = new ScopedMessagePartSpecification (other.out_sign);
63 public bool IsReadOnly {
64 get { return is_readonly; }
67 public ScopedMessagePartSpecification IncomingEncryptionParts {
68 get { return in_enc; }
71 public ScopedMessagePartSpecification IncomingSignatureParts {
72 get { return in_sign; }
75 public ScopedMessagePartSpecification OutgoingEncryptionParts {
76 get { return out_enc; }
79 public ScopedMessagePartSpecification OutgoingSignatureParts {
80 get { return out_sign; }
83 public void Add (
84 ChannelProtectionRequirements protectionRequirements)
86 Add (protectionRequirements, false);
89 public void Add (
90 ChannelProtectionRequirements protectionRequirements,
91 bool channelScopeOnly)
93 if (is_readonly)
94 throw new InvalidOperationException ("This ChannelProtectionRequirements is read-only.");
96 AddScopedParts (
97 protectionRequirements.IncomingEncryptionParts,
98 IncomingEncryptionParts,
99 channelScopeOnly);
100 AddScopedParts (
101 protectionRequirements.IncomingSignatureParts,
102 IncomingSignatureParts,
103 channelScopeOnly);
104 AddScopedParts (
105 protectionRequirements.OutgoingEncryptionParts,
106 OutgoingEncryptionParts,
107 channelScopeOnly);
108 AddScopedParts (
109 protectionRequirements.OutgoingSignatureParts,
110 OutgoingSignatureParts,
111 channelScopeOnly);
114 void AddScopedParts (ScopedMessagePartSpecification src, ScopedMessagePartSpecification dst, bool channelOnly)
116 dst.AddParts (src.ChannelParts);
117 if (channelOnly)
118 return;
120 foreach (string a in src.Actions) {
121 MessagePartSpecification m;
122 src.TryGetParts (a, out m);
123 src.AddParts (m);
127 public ChannelProtectionRequirements CreateInverse ()
129 ChannelProtectionRequirements r =
130 new ChannelProtectionRequirements ();
131 AddScopedParts (in_enc, r.out_enc, false);
132 AddScopedParts (in_sign, r.out_sign, false);
133 AddScopedParts (out_enc, r.in_enc, false);
134 AddScopedParts (out_sign, r.in_sign, false);
135 return r;
138 public void MakeReadOnly ()
140 is_readonly = true;
141 in_enc.MakeReadOnly ();
142 in_sign.MakeReadOnly ();
143 out_enc.MakeReadOnly ();
144 out_sign.MakeReadOnly ();
147 internal static ChannelProtectionRequirements CreateFromContract (ContractDescription cd)
149 ChannelProtectionRequirements cp =
150 new ChannelProtectionRequirements ();
151 List<XmlQualifiedName> enc = new List<XmlQualifiedName> ();
152 List<XmlQualifiedName> sig = new List<XmlQualifiedName> ();
153 if (cd.HasProtectionLevel) {
154 switch (cd.ProtectionLevel) {
155 case ProtectionLevel.EncryptAndSign:
156 cp.IncomingEncryptionParts.ChannelParts.IsBodyIncluded = true;
157 cp.OutgoingEncryptionParts.ChannelParts.IsBodyIncluded = true;
158 goto case ProtectionLevel.Sign;
159 case ProtectionLevel.Sign:
160 cp.IncomingSignatureParts.ChannelParts.IsBodyIncluded = true;
161 cp.OutgoingSignatureParts.ChannelParts.IsBodyIncluded = true;
162 break;
165 foreach (OperationDescription od in cd.Operations) {
166 foreach (MessageDescription md in od.Messages) {
167 enc.Clear ();
168 sig.Clear ();
169 ProtectionLevel mplv =
170 md.HasProtectionLevel ? md.ProtectionLevel :
171 od.HasProtectionLevel ? od.ProtectionLevel :
172 ProtectionLevel.EncryptAndSign; // default
173 foreach (MessageHeaderDescription hd in md.Headers)
174 AddPartProtectionRequirements (enc, sig, hd, cp);
176 ScopedMessagePartSpecification spec;
177 bool includeBodyEnc = mplv == ProtectionLevel.EncryptAndSign;
178 bool includeBodySig = mplv != ProtectionLevel.None;
180 // enc
181 spec = md.Direction == MessageDirection.Input ?
182 cp.IncomingEncryptionParts :
183 cp.OutgoingEncryptionParts;
184 spec.AddParts (new MessagePartSpecification (includeBodyEnc, enc.ToArray ()), md.Action);
185 // sig
186 spec = md.Direction == MessageDirection.Input ?
187 cp.IncomingSignatureParts :
188 cp.OutgoingSignatureParts;
189 spec.AddParts (new MessagePartSpecification (includeBodySig, sig.ToArray ()), md.Action);
192 return cp;
195 static void AddPartProtectionRequirements (List<XmlQualifiedName> enc,
196 List<XmlQualifiedName> sig,
197 MessageHeaderDescription pd,
198 ChannelProtectionRequirements cp)
200 if (!pd.HasProtectionLevel)
201 return; // no specific part indication
202 switch (pd.ProtectionLevel) {
203 case ProtectionLevel.EncryptAndSign:
204 enc.Add (new XmlQualifiedName (pd.Name, pd.Namespace));
205 goto case ProtectionLevel.Sign;
206 case ProtectionLevel.Sign:
207 sig.Add (new XmlQualifiedName (pd.Name, pd.Namespace));
208 break;