1
/****************************************************************************
3
| Copyright (c) 2007 Novell, Inc.
6
| This program is free software; you can redistribute it and/or
7
| modify it under the terms of version 2 of the GNU General Public License as
8
| published by the Free Software Foundation.
10
| This program is distributed in the hope that it will be useful,
11
| but WITHOUT ANY WARRANTY; without even the implied warranty of
12
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
| GNU General Public License for more details.
15
| You should have received a copy of the GNU General Public License
16
| along with this program; if not, contact Novell, Inc.
18
| To contact Novell about this file by physical or electronic mail,
19
| you may find current contact information at www.novell.com
21
| Author: Mike Lasky <mlasky@novell.com>
22
|***************************************************************************/
28
using System.Security.Cryptography;
29
using System.Threading;
34
using Simias.Authentication;
35
using Simias.Client.Event;
37
//using Simias.Provision;
57
/// Host's user/member ID which is consistent
58
/// across all collections the host is
61
public string MemberID;
64
/// External facing address for clients
66
public string PublicAddress;
69
/// Internal facing address for server to
70
/// server communication.
72
public string PrivateAddress;
75
/// Public key for host to host authentication
77
public string PublicKey;
80
/// true = Master, false = Slave
85
/// HostInfo default constructor
91
internal HostInfo( HostNode node )
94
MemberID = node.UserID;
96
PublicAddress = node.PublicUrl;
97
PrivateAddress = node.PrivateUrl;
98
PublicKey = node.PublicKey.ToXmlString( false );
99
Master = node.IsMasterHost;
105
public class SlaveSetup
107
private static string tempHostFileName = ".host.xml";
108
private static string tempPPKFileName = ".hostppk.xml";
109
private static string tempDomainFileName = ".domain.xml";
110
private static string tempOwnerFileName = ".owner.xml";
112
private static void SaveXmlDoc( string storePath, string fileName, string sObject )
114
string fullPath = Path.Combine( storePath, fileName );
115
StreamWriter stream = new StreamWriter( File.Open( fullPath, FileMode.Create, FileAccess.Write, FileShare.None ) );
116
stream.Write( sObject );
120
private static string GetXmlDoc( string storePath, string fileName )
122
string fullPath = Path.Combine( storePath, fileName );
123
StreamReader stream = new StreamReader( File.Open( fullPath, FileMode.Open, FileAccess.Read, FileShare.None ) );
124
string objectXml = stream.ReadToEnd();
129
internal static Domain GetDomain( string storePath )
131
XmlDocument doc = new XmlDocument();
132
doc.LoadXml( GetXmlDoc( storePath, tempDomainFileName ) );
133
Domain domain = (Domain)Node.NodeFactory( Store.GetStore(), doc );
138
private static void SaveDomain( string storePath, string domain )
140
SaveXmlDoc( storePath, tempDomainFileName, domain );
143
internal static Member GetOwner( string storePath )
145
XmlDocument doc = new XmlDocument();
146
doc.LoadXml( GetXmlDoc( storePath, tempOwnerFileName ) );
147
Member owner = (Member)Node.NodeFactory( Store.GetStore(), doc );
152
private static void SaveOwner( string storePath, string owner )
154
SaveXmlDoc( storePath, tempOwnerFileName, owner );
157
internal static HostNode GetHost( string storePath )
159
XmlDocument doc = new XmlDocument();
160
doc.LoadXml( GetXmlDoc( storePath, tempHostFileName ) );
161
HostNode hnode = new HostNode( Node.NodeFactory( Store.GetStore(), doc ) );
165
private static void SaveHost( string storePath, string host )
167
SaveXmlDoc( storePath, tempHostFileName, host );
170
internal static RSACryptoServiceProvider GetKeys( string storePath )
172
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
173
string keys = GetXmlDoc( storePath, tempPPKFileName );
174
rsa.FromXmlString( keys );
180
public static RSACryptoServiceProvider CreateKeys( string storePath )
184
RSACryptoServiceProvider rsa = GetKeys( storePath );
189
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
196
public static void SaveInitObjects( string storePath, string domain, string owner, string host, RSACryptoServiceProvider rsa )
198
SaveDomain( storePath, domain );
199
SaveOwner( storePath, owner );
200
SaveHost( storePath, host );
201
SaveXmlDoc( storePath, tempPPKFileName, rsa.ToXmlString( true ) );
204
internal static void DeleteTempSetupFiles( string storePath )
206
File.Delete( Path.Combine( storePath, tempDomainFileName ) );
207
File.Delete( Path.Combine( storePath, tempDomainFileName ) );
208
File.Delete( Path.Combine( storePath, tempHostFileName ) );
209
File.Delete( Path.Combine( storePath, tempPPKFileName ) );
214
/// Summary description for HostDomainProvider.
216
public class HostProvider
218
private Domain hostDomain;
219
private HostNode host;
220
private Store store = Store.GetStore();
222
private static string ServerSection = "Server";
223
private static string ServerNameKey = "Name";
224
private static string PublicAddressKey = "PublicAddress";
225
private static string PrivateAddressKey = "PrivateAddress";
226
private static string MasterAddressKey = "MasterAddress";
228
/// The ID of the Host domain. used for Host to Host authentication.
230
private CollectionSyncClient syncClient;
231
private AutoResetEvent syncEvent = new AutoResetEvent(false);
232
private SimiasConnection connection;
235
/// Construct a Host domain.
237
/// <param name="domain">The enterprise domain.</param>
238
public HostProvider( Domain domain )
242
// Check if this is the master server.
243
bool master = ( hostDomain.Role == SyncRoles.Master ) ? true : false;
245
// Get the HostDomain
246
// If the HostNode does not exist create it.
247
lock( typeof( HostProvider ) )
249
// Check if the host node exists.
250
string hName = Store.Config.Get( ServerSection, ServerNameKey );
252
// Make sure a master host can run without any pre-configured settings
253
// so if the public address wasn't configured get a non-loopback local
254
// address and configure the public address with it.
255
string publicAddress = Store.Config.Get( ServerSection, PublicAddressKey );
256
if ( publicAddress == null || publicAddress == String.Empty )
258
// Get the first non-localhost address
259
string[] addresses = MyDns.GetHostAddresses();
260
foreach( string addr in addresses )
262
if ( IPAddress.IsLoopback( IPAddress.Parse( addr ) ) == false )
264
publicAddress = addr;
270
string privateAddress = Store.Config.Get( ServerSection, PrivateAddressKey );
271
if ( privateAddress == null || privateAddress == String.Empty )
273
if ( publicAddress != null )
275
privateAddress = publicAddress;
279
string masterAddress = Store.Config.Get( ServerSection, MasterAddressKey );
280
Member mNode = hostDomain.GetMemberByName( hName );
281
host = ( mNode == null ) ? null : new HostNode( mNode );
284
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
287
host = new HostNode( hName, System.Guid.NewGuid().ToString(), publicAddress, privateAddress, rsa );
288
host.Rights = Simias.Storage.Access.Rights.Admin;
289
host.IsMasterHost = true;
293
host = SlaveSetup.GetHost( Store.StorePath );
295
rsa = SlaveSetup.GetKeys( Store.StorePath );
297
Property p = new Property( PropertyTags.HostAddress, new Uri( masterAddress ) );
298
p.LocalProperty = true;
299
hostDomain.Properties.AddNodeProperty( p );
303
host.IsLocalHost = true;
304
hostDomain.Commit( new Node[] { hostDomain, host } );
306
// Now Associate this host with the local identity.
307
store.AddDomainIdentity( hostDomain.ID, host.UserID, rsa.ToXmlString(true), CredentialType.PPK );
308
SlaveSetup.DeleteTempSetupFiles( Store.StorePath );
312
// Make sure the address has not changed.
313
bool hostChanged = false;
314
if (host.PublicUrl != publicAddress)
316
host.PublicUrl = publicAddress;
319
if (host.PrivateUrl != privateAddress)
321
host.PrivateUrl = privateAddress;
325
if ( hostChanged == true )
327
hostDomain.Commit(host);
332
if ( master == true )
334
// Register the ProvisionUser Provider.
335
ProvisionService.RegisterProvider( new LoadBalanceProvisionUserProvider() );
336
//ProvisionService.RegisterProvider( new MasterHostProvisionProvider() );
340
// Now start the sync process for the domain.
341
Thread syncThread = new Thread( new ThreadStart( SyncDomain ) );
342
syncThread.IsBackground = true;
347
private void SyncDomain()
354
// Get a connection object to the server.
355
connection = new SimiasConnection( hostDomain.ID, host.UserID, SimiasConnection.AuthType.PPK, hostDomain );
357
// We need to get a one time password to use to authenticate.
358
connection.Authenticate();
363
Thread.Sleep( 10000 );
371
syncClient = new CollectionSyncClient( hostDomain.ID, new TimerCallback( TimerFired ) );
377
syncClient.SyncNow();
380
syncClient.Reschedule( true, 30 );
385
/// Called by The CollectionSyncClient when it is time to run another sync pass.
387
/// <param name="collectionClient">The client that is ready to sync.</param>
388
public void TimerFired( object collectionClient )
390
while(CollectionSyncClient.running)