2 // ChannelProtectionRequirements.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System
.Net
.Security
;
30 using System
.Collections
.Generic
;
31 using System
.ServiceModel
;
32 using System
.ServiceModel
.Description
;
35 namespace System
.ServiceModel
.Security
37 // Represents sp:SignedParts and sp:EncryptedParts in
38 // sp:SupportingTokens/ws:Policy/.
39 public class ChannelProtectionRequirements
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
)
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; }
84 ChannelProtectionRequirements protectionRequirements
)
86 Add (protectionRequirements
, false);
90 ChannelProtectionRequirements protectionRequirements
,
91 bool channelScopeOnly
)
94 throw new InvalidOperationException ("This ChannelProtectionRequirements is read-only.");
97 protectionRequirements
.IncomingEncryptionParts
,
98 IncomingEncryptionParts
,
101 protectionRequirements
.IncomingSignatureParts
,
102 IncomingSignatureParts
,
105 protectionRequirements
.OutgoingEncryptionParts
,
106 OutgoingEncryptionParts
,
109 protectionRequirements
.OutgoingSignatureParts
,
110 OutgoingSignatureParts
,
114 void AddScopedParts (ScopedMessagePartSpecification src
, ScopedMessagePartSpecification dst
, bool channelOnly
)
116 dst
.AddParts (src
.ChannelParts
);
120 foreach (string a
in src
.Actions
) {
121 MessagePartSpecification m
;
122 src
.TryGetParts (a
, out 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);
138 public void MakeReadOnly ()
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;
165 foreach (OperationDescription od
in cd
.Operations
) {
166 foreach (MessageDescription md
in od
.Messages
) {
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
;
181 spec
= md
.Direction
== MessageDirection
.Input
?
182 cp
.IncomingEncryptionParts
:
183 cp
.OutgoingEncryptionParts
;
184 spec
.AddParts (new MessagePartSpecification (includeBodyEnc
, enc
.ToArray ()), md
.Action
);
186 spec
= md
.Direction
== MessageDirection
.Input
?
187 cp
.IncomingSignatureParts
:
188 cp
.OutgoingSignatureParts
;
189 spec
.AddParts (new MessagePartSpecification (includeBodySig
, sig
.ToArray ()), md
.Action
);
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
));