[eglib] make g_mkdir_with_parents work for paths not ending in /
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Security.Tokens / SpnegoSecurityTokenProvider.cs
1 //
2 // SpnegoSecurityTokenProvider.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.Net;
29 using System.Security.Principal;
30 using System.IdentityModel.Selectors;
31 using System.IdentityModel.Tokens;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Description;
34 using System.ServiceModel.Security.Tokens;
35 using System.Xml;
36 using Mono.Security;
37
38 // mhm, why is this class not in S.SM.S.Tokens??
39 namespace System.ServiceModel.Security
40 {
41         // Anyways we won't support SSPI until it becomes open.
42         internal class SpnegoSecurityTokenProvider : CommunicationSecurityTokenProvider
43         {
44                 ClientCredentialsSecurityTokenManager manager;
45                 SecurityTokenRequirement requirement;
46                 SpnegoCommunicationObject comm;
47
48                 public SpnegoSecurityTokenProvider (ClientCredentialsSecurityTokenManager manager, SecurityTokenRequirement requirement)
49                 {
50                         this.manager = manager;
51                         comm = new SpnegoCommunicationObject (this);
52                 }
53
54                 public ClientCredentialsSecurityTokenManager Manager {
55                         get { return manager; }
56                 }
57
58                 public override ProviderCommunicationObject Communication {
59                         get { return comm; }
60                 }
61
62                 public override SecurityToken GetOnlineToken (TimeSpan timeout)
63                 {
64                         return comm.GetToken (timeout);
65                 }
66         }
67
68         class SpnegoCommunicationObject : ProviderCommunicationObject
69         {
70                 SpnegoSecurityTokenProvider owner;
71
72                 public SpnegoCommunicationObject (SpnegoSecurityTokenProvider owner)
73                 {
74                         this.owner = owner;
75                 }
76
77                 WSTrustSecurityTokenServiceProxy proxy;
78
79                 protected internal override TimeSpan DefaultCloseTimeout {
80                         get { throw new NotImplementedException (); }
81                 }
82
83                 protected internal override TimeSpan DefaultOpenTimeout {
84                         get { throw new NotImplementedException (); }
85                 }
86
87                 protected override void OnAbort ()
88                 {
89                         throw new NotImplementedException ();
90                 }
91
92                 protected override void OnOpen (TimeSpan timeout)
93                 {
94                         if (State == CommunicationState.Opened)
95                                 throw new InvalidOperationException ("Already opened.");
96
97                         EnsureProperties ();
98
99                         proxy = new WSTrustSecurityTokenServiceProxy (
100                                 IssuerBinding, IssuerAddress);
101                 }
102
103                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
104                 {
105                         throw new NotImplementedException ();
106                 }
107
108                 protected override void OnEndOpen (IAsyncResult result)
109                 {
110                         throw new NotImplementedException ();
111                 }
112
113                 protected override void OnClose (TimeSpan timeout)
114                 {
115                         if (proxy != null)
116                                 proxy.Close ();
117                 }
118
119                 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
120                 {
121                         throw new NotImplementedException ();
122                 }
123
124                 protected override void OnEndClose (IAsyncResult result)
125                 {
126                         throw new NotImplementedException ();
127                 }
128
129                 public SecurityToken GetToken (TimeSpan timeout)
130                 {
131                         bool gss = (TargetAddress.Identity == null);
132                         SspiClientSession sspi = new SspiClientSession ();
133
134                         WstRequestSecurityToken rst =
135                                 new WstRequestSecurityToken ();
136
137                         // send MessageType1
138                         rst.BinaryExchange = new WstBinaryExchange (Constants.WstBinaryExchangeValueGss);
139                         // When the TargetAddress does not contain the endpoint
140                         // identity, then .net seems to use Kerberos instead of
141                         // raw NTLM.
142                         if (gss)
143                                 rst.BinaryExchange.Value = sspi.ProcessSpnegoInitialContextTokenRequest ();
144                         else
145                                 rst.BinaryExchange.Value = sspi.ProcessMessageType1 ();
146
147                         Message request = Message.CreateMessage (IssuerBinding.MessageVersion, Constants.WstIssueAction, rst);
148                         request.Headers.MessageId = new UniqueId ();
149                         request.Headers.ReplyTo = new EndpointAddress (Constants.WsaAnonymousUri);
150                         request.Headers.To = TargetAddress.Uri;
151                         MessageBuffer buffer = request.CreateBufferedCopy (0x10000);
152 //                      tlsctx.StoreMessage (buffer.CreateMessage ().GetReaderAtBodyContents ());
153
154                         // receive MessageType2
155                         Message response = proxy.Issue (buffer.CreateMessage ());
156                         buffer = response.CreateBufferedCopy (0x10000);
157 //                      tlsctx.StoreMessage (buffer.CreateMessage ().GetReaderAtBodyContents ());
158
159                         WSTrustRequestSecurityTokenResponseReader reader =
160                                 new WSTrustRequestSecurityTokenResponseReader (Constants.WstSpnegoProofTokenType, buffer.CreateMessage ().GetReaderAtBodyContents (), SecurityTokenSerializer, null);
161                         reader.Read ();
162
163                         byte [] raw = reader.Value.BinaryExchange.Value;
164                         if (gss)
165                                 sspi.ProcessSpnegoInitialContextTokenResponse (raw);
166                         else
167                                 sspi.ProcessMessageType2 (raw);
168
169                         // send MessageType3
170                         WstRequestSecurityTokenResponse rstr =
171                                 new WstRequestSecurityTokenResponse (SecurityTokenSerializer);
172                         rstr.Context = reader.Value.Context;
173                         rstr.BinaryExchange = new WstBinaryExchange (Constants.WstBinaryExchangeValueGss);
174
175                         NetworkCredential cred = owner.Manager.ClientCredentials.Windows.ClientCredential;
176                         string user = string.IsNullOrEmpty (cred.UserName) ? Environment.UserName : cred.UserName;
177                         string pass = cred.Password ?? String.Empty;
178                         if (gss)
179                                 rstr.BinaryExchange.Value = sspi.ProcessSpnegoProcessContextToken (user, pass);
180                         else
181                                 rstr.BinaryExchange.Value = sspi.ProcessMessageType3 (user, pass);
182
183                         request = Message.CreateMessage (IssuerBinding.MessageVersion, Constants.WstIssueReplyAction, rstr);
184                         request.Headers.MessageId = new UniqueId ();
185                         request.Headers.ReplyTo = new EndpointAddress (Constants.WsaAnonymousUri);
186                         request.Headers.To = TargetAddress.Uri;
187
188                         buffer = request.CreateBufferedCopy (0x10000);
189 //                      tlsctx.StoreMessage (buffer.CreateMessage ().GetReaderAtBodyContents ());
190
191                         proxy = new WSTrustSecurityTokenServiceProxy (
192                                 IssuerBinding, IssuerAddress);
193                         response = proxy.IssueReply (buffer.CreateMessage ());
194                         // FIXME: use correct limitation
195                         buffer = response.CreateBufferedCopy (0x10000);
196                         // don't store this message for ckhash (it's not part
197                         // of exchange)
198 Console.WriteLine (buffer.CreateMessage ());
199
200                         throw new NotImplementedException ();
201                 }
202         }
203 }