You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
647 lines
20 KiB
647 lines
20 KiB
using System;
|
|
using System.Net;
|
|
using System.Collections;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Security.Principal;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Xml;
|
|
using System.Xml.Schema;
|
|
using System.Xml.Serialization;
|
|
using System.Web.Services;
|
|
using System.Web.Services.Description;
|
|
using System.Web.Services.Protocols;
|
|
|
|
using UDDI;
|
|
using UDDI.Replication;
|
|
using UDDI.Diagnostics;
|
|
|
|
namespace UDDI.Tools
|
|
{
|
|
public class ReplicationConfigurationUtility
|
|
{
|
|
private static string executable = System.AppDomain.CurrentDomain.FriendlyName;
|
|
private static string filename = null;
|
|
private static string operatorKey = null;
|
|
private static string rcfFile = null;
|
|
|
|
private static bool overwrite = false;
|
|
|
|
private enum ModeType
|
|
{
|
|
None = 0,
|
|
ImportOperatorCertificate = 1,
|
|
ExportOperatorCertificate = 2,
|
|
ImportRCF = 3
|
|
}
|
|
|
|
private static ModeType mode = ModeType.None;
|
|
|
|
/// ****************************************************************
|
|
/// internal ProcessCommandLine [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Parse the command-line.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="args">
|
|
/// Command-line arguments.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
internal static void ProcessCommandLine( string[] args )
|
|
{
|
|
int i = 0;
|
|
|
|
while( i < args.Length )
|
|
{
|
|
if( '-' == args[i][0] || '/' == args[i][0] )
|
|
{
|
|
//
|
|
// Process the switch.
|
|
//
|
|
switch( args[i].Substring( 1 ).ToLower() )
|
|
{
|
|
case "i":
|
|
if( i == args.Length - 1 )
|
|
throw new CommandLineException( "Missing required argument 'certfile'." );
|
|
|
|
mode = ModeType.ImportOperatorCertificate;
|
|
|
|
i ++;
|
|
filename = args[i];
|
|
|
|
if( !File.Exists( filename ) )
|
|
throw new CommandLineException( "Certificate file '" + filename + "' does not exist." );
|
|
|
|
break;
|
|
|
|
case "e":
|
|
if( i == args.Length - 1 )
|
|
throw new CommandLineException( "Missing required argument 'certfile'." );
|
|
|
|
mode = ModeType.ExportOperatorCertificate;
|
|
|
|
i ++;
|
|
filename = args[i];
|
|
|
|
break;
|
|
|
|
case "o":
|
|
if( i == args.Length - 1 )
|
|
throw new CommandLineException( "Missing required argument 'operatorkey'." );
|
|
|
|
i ++;
|
|
operatorKey = args[i];
|
|
|
|
//
|
|
// strip {'s and }'s
|
|
//
|
|
operatorKey = operatorKey.Replace("{", string.Empty);
|
|
operatorKey = operatorKey.Replace("}", string.Empty);
|
|
|
|
break;
|
|
case "r":
|
|
if( i == args.Length - 1 )
|
|
{
|
|
throw new CommandLineException( "Missing required argument 'path to RCF file'." );
|
|
}
|
|
i ++;
|
|
rcfFile = args[i];
|
|
mode = ModeType.ImportRCF;
|
|
|
|
if( !File.Exists( rcfFile ) )
|
|
throw new CommandLineException( "RCF file '" + rcfFile + "' does not exist." );
|
|
|
|
break;
|
|
case "y":
|
|
overwrite = true;
|
|
break;
|
|
|
|
case "?":
|
|
goto case "help";
|
|
|
|
case "help":
|
|
throw new CommandLineException( "" );
|
|
|
|
default:
|
|
throw new CommandLineException( "Unknown command-line parameter '" + args[i] + "'." );
|
|
}
|
|
}
|
|
|
|
i ++;
|
|
}
|
|
|
|
//
|
|
// Make sure the appropriate options were set.
|
|
//
|
|
//if()
|
|
// throw new CommandLineException( "Missing required command-line parameters." );
|
|
}
|
|
|
|
public static void ImportOperatorCertificate()
|
|
{
|
|
X509Certificate certificate = X509Certificate.CreateFromCertFile( filename );
|
|
SaveOperatorInfo( operatorKey, certificate );
|
|
}
|
|
|
|
public static void ImportRCF()
|
|
{
|
|
FileStream rcfStream = File.Open( rcfFile, FileMode.Open, FileAccess.Read, FileShare.Read );
|
|
|
|
try
|
|
{
|
|
//
|
|
// Validate the RCF file.
|
|
//
|
|
SchemaCollection.Validate( rcfStream );
|
|
|
|
//
|
|
//
|
|
// Open our RCF file, it has already been checked to make sure it exists.
|
|
//
|
|
XmlTextReader rcfReader = new XmlTextReader( rcfStream );
|
|
|
|
while( true == rcfReader.Read() && false == rcfReader.EOF )
|
|
{
|
|
if( rcfReader.Name.Equals( "operator" ) && rcfReader.NamespaceURI.Equals( UDDI.Replication.Constants.Namespace ) )
|
|
{
|
|
//
|
|
// For each operator node, we want the following information. These are all
|
|
// mandatory elements, so if any were missing we should not have passed schema
|
|
// validation.
|
|
//
|
|
// operatorNodeID (this is the operatorKey)
|
|
// operatorStatus
|
|
// soapReplicationUrl
|
|
// certificate
|
|
// operatorCustodyName (operatorName)
|
|
//
|
|
|
|
//
|
|
// Note that contacts are currently being ignored. This is because we are not sending
|
|
// the businessKey for the operator. Since we store contacts based on businessKey (actually businessID)
|
|
// we do not have a way of storing contacts. IN 70 says that the operatorNodeID should actually be this
|
|
// businessKey, so once we decide to implement this, we'll process contacts.
|
|
//
|
|
|
|
X509Certificate certificate = null;
|
|
string operatorKey = null;
|
|
string operatorName = null;
|
|
string soapReplicationUrl = null;
|
|
int operatorStatus = 0;
|
|
string localOperatorKey = Config.GetString( "OperatorKey" ).ToLower();
|
|
|
|
do
|
|
{
|
|
switch( rcfReader.Name )
|
|
{
|
|
case "operatorNodeID":
|
|
{
|
|
operatorKey = rcfReader.ReadElementString();
|
|
break;
|
|
}
|
|
case "operatorCustodyName":
|
|
{
|
|
operatorName = rcfReader.ReadElementString();
|
|
break;
|
|
}
|
|
case "operatorStatus":
|
|
{
|
|
|
|
operatorStatus = OperatorStatus2ID( rcfReader.ReadElementString() );
|
|
break;
|
|
}
|
|
case "soapReplicationURL":
|
|
{
|
|
soapReplicationUrl = rcfReader.ReadElementString();
|
|
break;
|
|
}
|
|
case "certificate":
|
|
{
|
|
//
|
|
// Read our data in 1024 byte chunks. Keep an array list of these
|
|
// chunks.
|
|
//
|
|
int bytesRead = 0;
|
|
int chunkSize = 1024;
|
|
ArrayList chunks = new ArrayList();
|
|
|
|
do
|
|
{
|
|
byte[] data = new byte[ chunkSize ];
|
|
bytesRead = rcfReader.ReadBase64( data, 0, chunkSize );
|
|
|
|
if( bytesRead > 0 )
|
|
{
|
|
chunks.Add( data );
|
|
}
|
|
}while( bytesRead != 0 );
|
|
|
|
//
|
|
// Allocate a buffer to hold all of our chunks.
|
|
//
|
|
byte[] certificateData = new byte[ chunks.Count * chunkSize ];
|
|
|
|
//
|
|
// Copy each chunk into our buffer. This buffer is our certificate.
|
|
//
|
|
int index = 0;
|
|
foreach( byte[] chunkData in chunks )
|
|
{
|
|
Array.Copy( chunkData, 0, certificateData, index, chunkData.Length );
|
|
index += chunkData.Length;
|
|
}
|
|
|
|
//
|
|
// Create a certificate from our byte data.
|
|
//
|
|
certificate = new X509Certificate( certificateData );
|
|
break;
|
|
}
|
|
}
|
|
}while( true == rcfReader.Read() && false == rcfReader.EOF && false == rcfReader.Name.Equals( "operator" ) );
|
|
|
|
//
|
|
// Make sure we identify the local operator.
|
|
//
|
|
if( false == operatorKey.ToLower().Equals( localOperatorKey ) )
|
|
{
|
|
//
|
|
// Import this operator
|
|
//
|
|
SaveOperatorInfo( operatorKey, operatorName, soapReplicationUrl, operatorStatus, certificate );
|
|
Console.WriteLine( "Successfully imported {0}.", operatorName );
|
|
}
|
|
else
|
|
{
|
|
SaveOperatorInfo( null, operatorName, soapReplicationUrl, operatorStatus, certificate );
|
|
Console.WriteLine( "Successfully update the local operator." );
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
catch( XmlException xmlException )
|
|
{
|
|
Console.WriteLine( "Exception processing the RCF: " );
|
|
Console.WriteLine( "\t" );
|
|
Console.WriteLine( xmlException.ToString() );
|
|
}
|
|
catch( XmlSchemaException schemaException )
|
|
{
|
|
Console.WriteLine( "The RCF did not pass schema validation: " );
|
|
Console.WriteLine( "\t" );
|
|
Console.WriteLine( schemaException.ToString() );
|
|
}
|
|
finally
|
|
{
|
|
rcfStream.Close();
|
|
}
|
|
}
|
|
|
|
public static void ExportOperatorCertificate()
|
|
{
|
|
if( null == operatorKey )
|
|
{
|
|
operatorKey = Config.GetString( "OperatorKey" );
|
|
}
|
|
|
|
if( File.Exists( filename ) && !overwrite )
|
|
{
|
|
Console.Write( "Overwrite '{0}' [y/n]? ", filename );
|
|
int choice = Console.Read();
|
|
|
|
if( 'y' != (char)choice && 'Y' != (char)choice )
|
|
{
|
|
Console.WriteLine();
|
|
Console.WriteLine( "Operation aborted." );
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
byte[] data = null;
|
|
|
|
//
|
|
// Retrieve the certificate.
|
|
//
|
|
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
|
|
|
|
sp.ProcedureName = "net_operator_get";
|
|
|
|
sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
|
|
sp.Parameters.SetGuidFromString( "@operatorKey", operatorKey );
|
|
|
|
SqlDataReaderAccessor reader = sp.ExecuteReader();
|
|
|
|
try
|
|
{
|
|
if( reader.Read() )
|
|
data = reader.GetBinary( "certificate" );
|
|
}
|
|
finally
|
|
{
|
|
reader.Close();
|
|
}
|
|
|
|
FileStream file = File.Open( filename, FileMode.Create, FileAccess.Write, FileShare.None );
|
|
|
|
try
|
|
{
|
|
int filesize = (int)data.Length;
|
|
|
|
file.Write( data, 0, filesize );
|
|
|
|
Console.WriteLine( "Wrote {0} byte(s) to certificate file '{1}'.\r\nSource: {{{2}}}",
|
|
filesize,
|
|
filename,
|
|
operatorKey );
|
|
}
|
|
finally
|
|
{
|
|
file.Close();
|
|
}
|
|
}
|
|
|
|
private static int OperatorStatus2ID( string status )
|
|
{
|
|
//
|
|
// These values must match the values in UDO_operatorStatus
|
|
//
|
|
int id = 2;
|
|
switch( status )
|
|
{
|
|
case "disable":
|
|
{
|
|
id = 0;
|
|
break;
|
|
}
|
|
case "new":
|
|
{
|
|
id = 1;
|
|
break;
|
|
}
|
|
case "normal":
|
|
{
|
|
id = 2;
|
|
break;
|
|
}
|
|
case "resigned":
|
|
{
|
|
id = 3;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
private static void SaveOperatorInfo( string operatorKey, X509Certificate certificate)
|
|
{
|
|
//
|
|
// Default operator status to 2 (normal)
|
|
//
|
|
SaveOperatorInfo( operatorKey, operatorKey, null, 2, certificate );
|
|
}
|
|
|
|
private static void SaveOperatorInfo( string operatorKey,
|
|
string operatorName,
|
|
string soapReplicationUrl,
|
|
int operatorStatus,
|
|
X509Certificate certificate)
|
|
{
|
|
byte[] data = certificate.GetRawCertData();
|
|
|
|
ConnectionManager.BeginTransaction();
|
|
|
|
SqlStoredProcedureAccessor sp = new SqlStoredProcedureAccessor();
|
|
sp.ProcedureName = "net_operator_save";
|
|
|
|
if( null == operatorKey )
|
|
{
|
|
//
|
|
// Import a certificate for the local operator
|
|
//
|
|
|
|
operatorKey = Config.GetString( "OperatorKey" );
|
|
|
|
sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
|
|
sp.Parameters.Add( "@certSerialNo", SqlDbType.NVarChar, UDDI.Constants.Lengths.CertSerialNo );
|
|
sp.Parameters.Add( "@certIssuer", SqlDbType.NVarChar, UDDI.Constants.Lengths.CertIssuer );
|
|
sp.Parameters.Add( "@certSubject", SqlDbType.NVarChar, UDDI.Constants.Lengths.CertSubject );
|
|
sp.Parameters.Add( "@certificate", SqlDbType.Image );
|
|
|
|
sp.Parameters.SetGuidFromString( "@operatorKey", operatorKey );
|
|
sp.Parameters.SetString( "@certSerialNo", certificate.GetSerialNumberString() );
|
|
sp.Parameters.SetString( "@certIssuer", certificate.GetIssuerName() );
|
|
sp.Parameters.SetString( "@certSubject", certificate.GetName() );
|
|
sp.Parameters.SetBinary( "@certificate", data );
|
|
|
|
sp.ExecuteNonQuery();
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Create a new operator / publisher and import certificate
|
|
//
|
|
|
|
//
|
|
// First add a publisher for the new operator
|
|
//
|
|
|
|
SqlStoredProcedureAccessor sp2 = new SqlStoredProcedureAccessor();
|
|
|
|
sp2.ProcedureName = "UI_savePublisher";
|
|
|
|
sp2.Parameters.Add( "@PUID", SqlDbType.NVarChar, UDDI.Constants.Lengths.UserID );
|
|
sp2.Parameters.Add( "@name", SqlDbType.NVarChar, UDDI.Constants.Lengths.Name );
|
|
sp2.Parameters.Add( "@email", SqlDbType.NVarChar, UDDI.Constants.Lengths.Email );
|
|
//
|
|
// TODO: use UDDI.Constants.Lengths.Phone when the UI_savePublisher is fixed
|
|
//
|
|
sp2.Parameters.Add( "@phone", SqlDbType.VarChar, 20 );
|
|
|
|
sp2.Parameters.SetString( "@PUID", operatorKey );
|
|
sp2.Parameters.SetString( "@name", operatorKey );
|
|
sp2.Parameters.SetString( "@email", "" );
|
|
sp2.Parameters.SetString( "@phone", "" );
|
|
|
|
sp2.ExecuteNonQuery();
|
|
|
|
//
|
|
// Add the new operator and link it to the new publisher
|
|
//
|
|
sp.Parameters.Add( "@operatorKey", SqlDbType.UniqueIdentifier );
|
|
sp.Parameters.Add( "@operatorStatusID", SqlDbType.Int );
|
|
sp.Parameters.Add( "@PUID", SqlDbType.NVarChar, UDDI.Constants.Lengths.UserID );
|
|
sp.Parameters.Add( "@name", SqlDbType.NVarChar, UDDI.Constants.Lengths.Name );
|
|
sp.Parameters.Add( "@soapReplicationURL", SqlDbType.NVarChar, UDDI.Constants.Lengths.SoapReplicationURL );
|
|
sp.Parameters.Add( "@certSerialNo", SqlDbType.NVarChar, UDDI.Constants.Lengths.CertSerialNo );
|
|
sp.Parameters.Add( "@certIssuer", SqlDbType.NVarChar, UDDI.Constants.Lengths.CertIssuer );
|
|
sp.Parameters.Add( "@certSubject", SqlDbType.NVarChar, UDDI.Constants.Lengths.CertSubject );
|
|
sp.Parameters.Add( "@certificate", SqlDbType.Image );
|
|
|
|
sp.Parameters.SetGuidFromString( "@operatorKey", operatorKey );
|
|
sp.Parameters.SetInt( "@operatorStatusID", operatorStatus );
|
|
sp.Parameters.SetString( "@PUID", operatorKey );
|
|
sp.Parameters.SetString( "@name", operatorName );
|
|
sp.Parameters.SetString( "@soapReplicationURL", soapReplicationUrl );
|
|
sp.Parameters.SetString( "@certSerialNo", certificate.GetSerialNumberString() );
|
|
sp.Parameters.SetString( "@certIssuer", certificate.GetIssuerName() );
|
|
sp.Parameters.SetString( "@certSubject", certificate.GetName() );
|
|
sp.Parameters.SetBinary( "@certificate", data );
|
|
|
|
sp.ExecuteNonQuery();
|
|
}
|
|
|
|
ConnectionManager.Commit();
|
|
|
|
Console.WriteLine( "Wrote {0} byte(s) to operator key {{{1}}}.\r\nSource: '{2}'.",
|
|
data.Length,
|
|
operatorKey,
|
|
filename );
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public Main [static]
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Program entry point.
|
|
/// </summary>
|
|
/// ----------------------------------------------------------------
|
|
/// <param name="args">
|
|
/// Command-line arguments.
|
|
/// </param>
|
|
/// ****************************************************************
|
|
///
|
|
public static void Main( string[] args )
|
|
{
|
|
try
|
|
{
|
|
ConnectionManager.Open( true, false );
|
|
|
|
Debug.VerifySetting( "OperatorKey" );
|
|
|
|
Console.WriteLine( "Microsoft (R) UDDI Replication Configuration Utility." );
|
|
Console.WriteLine( "Copyright (C) Microsoft Corp. 2002. All rights reserved." );
|
|
Console.WriteLine();
|
|
|
|
WindowsIdentity identity = WindowsIdentity.GetCurrent();
|
|
WindowsPrincipal principal = new WindowsPrincipal( identity );
|
|
|
|
Context.User.SetRole( principal );
|
|
|
|
if( !Context.User.IsAdministrator )
|
|
{
|
|
Console.WriteLine( "Access denied.\r\n\r\nThis program must be executed by a member of the '"
|
|
+ Config.GetString( "GroupName.Administrators" ) + "'\r\ngroup. The current user '"
|
|
+ identity.Name + "' is not a member of this group." );
|
|
|
|
return;
|
|
}
|
|
|
|
ProcessCommandLine( args );
|
|
|
|
switch( mode )
|
|
{
|
|
case ModeType.ImportOperatorCertificate:
|
|
ImportOperatorCertificate();
|
|
break;
|
|
|
|
case ModeType.ExportOperatorCertificate:
|
|
ExportOperatorCertificate();
|
|
break;
|
|
case ModeType.ImportRCF:
|
|
ImportRCF();
|
|
break;
|
|
default:
|
|
throw new CommandLineException( "" );
|
|
}
|
|
}
|
|
catch( CommandLineException e )
|
|
{
|
|
//
|
|
// Display command-line help.
|
|
//
|
|
Console.WriteLine( "Syntax:" );
|
|
Console.WriteLine( " " + executable + " <options> [parameters]" );
|
|
Console.WriteLine();
|
|
Console.WriteLine( "Options:" );
|
|
Console.WriteLine( " -help Displays this help message." );
|
|
Console.WriteLine( " -i <certfile> Import a certificate. If the -o option is not" );
|
|
Console.WriteLine( " used, the certificate is imported for the" );
|
|
Console.WriteLine( " local operator." );
|
|
Console.WriteLine( " -e <certfile> Export a certificate. If the -o option is not" );
|
|
Console.WriteLine( " used, the certificate is exported from the" );
|
|
Console.WriteLine( " local operator." );
|
|
Console.WriteLine( " -o <operatorkey> The operator key to import/export a certificate" );
|
|
Console.WriteLine( " Omit this parameter to import a certificate for the" );
|
|
Console.WriteLine( " local operator." );
|
|
Console.WriteLine( " -y Supress file overwrite prompt." );
|
|
Console.WriteLine( " -r <rcf> Path to replication configuration file (RCF)." );
|
|
Console.WriteLine();
|
|
Console.WriteLine( "Examples:" );
|
|
Console.WriteLine( " " + executable + " -help" );
|
|
Console.WriteLine( " " + executable + " -o FF735874-28BD-41A0-96F3-02113FFD9D6C -i uddi.cer" );
|
|
Console.WriteLine( " " + executable + " -i uddi.cer" );
|
|
Console.WriteLine( " " + executable + " -r operators.xml" );
|
|
Console.WriteLine();
|
|
|
|
if( 0 != e.Message.Length )
|
|
Console.WriteLine( e.Message );
|
|
|
|
return;
|
|
}
|
|
catch( Exception e )
|
|
{
|
|
Console.WriteLine( e.ToString() );
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// ****************************************************************
|
|
/// public class CommandLineException
|
|
/// ----------------------------------------------------------------
|
|
/// <summary>
|
|
/// Exception class for errors encountered while parsing the
|
|
/// command-line.
|
|
/// </summary>
|
|
/// ****************************************************************
|
|
///
|
|
public class CommandLineException : ApplicationException
|
|
{
|
|
/// ************************************************************
|
|
/// public CommandLineException [constructor]
|
|
/// ------------------------------------------------------------
|
|
/// <summary>
|
|
/// CommandLineException constructor.
|
|
/// </summary>
|
|
/// ************************************************************
|
|
///
|
|
public CommandLineException()
|
|
: base()
|
|
{
|
|
}
|
|
|
|
/// ************************************************************
|
|
/// public CommandLineException [constructor]
|
|
/// ------------------------------------------------------------
|
|
/// <summary>
|
|
/// CommandLineException constructor.
|
|
/// </summary>
|
|
/// ------------------------------------------------------------
|
|
/// <param name="message">
|
|
/// Exception message.
|
|
/// </param>
|
|
/// ************************************************************
|
|
///
|
|
public CommandLineException( string message )
|
|
: base( message )
|
|
{
|
|
}
|
|
}
|
|
}
|