moving missing WCF assembly (mono-only one).
[mono.git] / mcs / class / Mono.ServiceModel.IdentitySelectors / Mono.ServiceModel.IdentitySelectors / CardSelectorClient.cs
1 //
2 // CardSelectorClient.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2007 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;
29 using System.Collections.Generic;
30 using System.Collections.ObjectModel;
31 using System.IO;
32 using System.IdentityModel.Claims;
33 using System.IdentityModel.Policy;
34 using System.IdentityModel.Selectors;
35 using System.IdentityModel.Tokens;
36 using System.Security.Cryptography.X509Certificates;
37 using System.ServiceModel;
38 using System.ServiceModel.Security;
39 using System.ServiceModel.Security.Tokens;
40 using System.Xml;
41
42 namespace Mono.ServiceModel.IdentitySelectors
43 {
44         public abstract class CardSelectorClient
45         {
46                 public abstract void Manage ();
47
48                 #region Import
49
50                 // This must be implemented unless Import() is overriden.
51                 public virtual string ReceivePassword ()
52                 {
53                         throw new NotImplementedException ("Import is not implemented by this identity selector client");
54                 }
55
56                 public virtual void Import (string filename)
57                 {
58                         string password = ReceivePassword ();
59                         if (password == null)
60                                 return;
61                         IdentityCard card = ProcessImport (filename, password);
62                         IdentityStore.GetDefaultStore ().StoreCard (card, password);
63                 }
64
65                 protected IdentityCard ProcessImport (string filename, string password)
66                 {
67                         string xml = new IdentityCardEncryption ().Decrypt (
68                                 new StreamReader (filename).ReadToEnd (), password);
69                         IdentityCard card = new IdentityCard ();
70                         card.Load (XmlReader.Create (new StringReader (xml)));
71                         return card;
72                 }
73
74                 #endregion
75
76                 // This is virtual since it might not be required when
77                 // GetToken() is overriden.
78                 public virtual IdentityCard SelectCardToSend (CardSelectionContext context)
79                 {
80                         throw new NotSupportedException ();
81                 }
82
83                 #region Default self-issued card processor
84                 // They are used to indicate a service URL when there is no
85                 // overriden behavior of RequestSelfIssuedToken().
86
87                 string self_identity_issuer = Environment.GetEnvironmentVariable ("MONO_IDENTITY_SERVICE_URL") ?? "localhost:7450";
88                 string self_identity_issuer_cert = Environment.GetEnvironmentVariable ("MONO_IDENTITY_SERVICE_CERTIFICATE");
89
90                 public virtual string SelfIdentityIssuerUrl {
91                         get { return self_identity_issuer; }
92                 }
93
94                 public virtual string SelfIdentityIssuerCertificate {
95                         get { return self_identity_issuer_cert; }
96                 }
97                 #endregion
98
99                 public virtual GenericXmlSecurityToken GetToken (
100                         CardSpacePolicyElement [] policyChain,
101                         SecurityTokenSerializer serializer)
102                 {
103                         // FIXME: sort out what is supposed to be done here.
104                         foreach (CardSpacePolicyElement policy in policyChain)
105                                 return GetToken (policy.Target, policy.Issuer,
106                                           policy.Parameters,
107                                           policy.PolicyNoticeLink,
108                                           policy.PolicyNoticeVersion);
109                         throw new Exception ("INTERNAL ERROR: no policy to process");
110                 }
111
112                 GenericXmlSecurityToken GetToken (
113                         XmlElement target, XmlElement issuer,
114                         Collection<XmlElement> parameters,
115                         Uri policyNoticeLink, int policyNoticeVersion)
116                 {
117                         Collection<ClaimTypeRequirement> reqs = new Collection<ClaimTypeRequirement> ();
118                         Collection<XmlElement> alist = new Collection<XmlElement> ();
119                         foreach (XmlElement el in parameters) {
120                                 if (el.LocalName == "Claims" && el.NamespaceURI == Constants.WstNamespace)
121                                         foreach (XmlElement c in el.ChildNodes)
122                                                 reqs.Add (new ClaimTypeRequirement (c.GetAttribute ("Uri"), c.GetAttribute ("Optional") == "true"));
123                                 else
124                                         alist.Add (el);
125                         }
126
127                         CardSelectionContext ctx = new CardSelectionContext (
128                                 EndpointAddress.ReadFrom (XmlDictionaryReader.CreateDictionaryReader (new XmlNodeReader (target))),
129                                 EndpointAddress.ReadFrom (XmlDictionaryReader.CreateDictionaryReader (new XmlNodeReader (issuer))),
130                                 reqs,
131                                 alist,
132                                 policyNoticeLink,
133                                 policyNoticeVersion);
134
135                         IdentityCard card = SelectCardToSend (ctx);
136
137                         if (card.Issuer != null)
138                                 // process WS-Trust RST
139                                 return RequestTrustedToken (ctx, card);
140                         else
141                                 return RequestSelfIssuedToken (ctx, card);
142                 }
143
144                 public virtual GenericXmlSecurityToken RequestTrustedToken (CardSelectionContext ctx, IdentityCard card)
145                 {
146                         X509Certificate2 cert = new X509Certificate2 (card.Certificate);
147                         EndpointAddress issuer = new EndpointAddress (card.Issuer, new X509CertificateEndpointIdentity (cert));
148                         return RequestToken (issuer, ctx);
149                 }
150
151                 public virtual GenericXmlSecurityToken RequestSelfIssuedToken (CardSelectionContext ctx, IdentityCard card)
152                 {
153                         Uri issuerUri = card.Issuer ?? new Uri (SelfIdentityIssuerUrl);
154                         X509Certificate2 cert = new X509Certificate2 (SelfIdentityIssuerCertificate);
155                         EndpointAddress issuer = new EndpointAddress (issuerUri, new X509CertificateEndpointIdentity (cert));
156                         return RequestToken (issuer, ctx);
157                 }
158
159                 // This must be implemented unless other depending methods
160                 // are overriden.
161                 public virtual GenericXmlSecurityToken RequestToken (EndpointAddress issuer, CardSelectionContext ctx)
162                 {
163                         return null;
164                 }
165
166                 /* This will be used if we have to implement unmanaged foo.
167
168                 public string GetToken (
169                         string targetXml,
170                         string issuerXml,
171                         string claimTypeRequirementsXml,
172                         string policyNoticeLink,
173                         int policyNoticeVersion,
174                         bool isManagedIssuer)
175                 {
176                         EndpointAddress target = EndpointAddress.ReadFrom (
177                                 XmlDictionaryReader.CreateDictionaryReader (
178                                         XmlReader.Create (new StringReader (targetXml))));
179                         EndpointAddress issuer = isManagedIssuer ?EndpointAddress.ReadFrom (
180                                 XmlDictionaryReader.CreateDictionaryReader (
181                                         XmlReader.Create (new StringReader (issuerXml)))) : null;
182                         XmlReaderSettings s = new XmlReaderSettings ();
183                         s.ConformanceLevel = ConformanceLevel.Fragment;
184                         Collection<ClaimTypeRequirement> reqs = new Collection<ClaimTypeRequirement> ();
185                         Collection<XmlElement> parameters = new Collection<XmlElement> ();
186                         XmlDictionaryReader dr = XmlDictionaryReader.CreateDictionaryReader (
187                                 XmlReader.Create (new StringReader (claimTypeRequirementsXml)));
188                         XmlDocument doc = new XmlDocument ();
189                         for (dr.MoveToContent (); !dr.EOF; dr.MoveToContent ()) {
190                                 XmlElement el = doc.ReadNode (dr) as XmlElement;
191                                 if (el.LocalName == "Claims" && el.NamespaceURI == Constants.WstNamespace)
192                                         foreach (XmlElement c in el.ChildNodes)
193                                                 reqs.Add (new ClaimTypeRequirement (c.GetAttribute ("Uri"), c.GetAttribute ("Optional") == "true"));
194                                 else
195                                         parameters.Add (el);
196                         }
197
198                         GenericXmlSecurityToken token = GetToken (target, issuer, reqs, parameters, new Uri (policyNoticeLink), policyNoticeVersion);
199                         StringWriter sw = new StringWriter ();
200                         using (XmlWriter xw = XmlWriter.Create (sw)) {
201                                 WSSecurityTokenSerializer.DefaultInstance.WriteToken (xw, token);
202                         }
203                         return sw.ToString ();
204                 }
205                 */
206         }
207 }