
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using SmartCard.Runtime.Remoting.Channels.APDU;
using System.IO;
using System.Xml;
using System.Collections;
using MyCompany.Server.EncryptionSink;

namespace MyCompany.Server
{
    /// <summary>
    /// Třída SinkServerApp registruje vzdálené služby a nastavuje vrstvu pro šifrování 
    /// </summary>
    public class SinkServerApp
    {
        // Specifikuje vystavovanou adresu URI
        private const string REMOTE_OBJECT_URI = "EncryptionSinkService.uri";

        //Probíhá registrace  služby a nastavení vrstev
        public static int Main()
        {
            string algorithm = string.Empty;
            string keyfile = string.Empty;
            StreamReader reader = null;
            XmlTextReader xmlReader = null;

            // Inicializace XML readru
            try
            {
                reader = new StreamReader(@"C:\Pub\AppConfig.xml");
                xmlReader = new XmlTextReader(reader);

                while (xmlReader.Read())
                {
                    switch (xmlReader.Name)
                    {
                        case "algorithm":                       // Použitý algoritmus
                            algorithm = xmlReader.ReadString();
                            break;

                        case "keyfile":                         // Umístění souboru s klíčem
                            keyfile = xmlReader.ReadString();
                            break;
                    }
                }
            }
            finally
            {
                if (xmlReader != null)
                    xmlReader.Close();
                if (reader != null)
                    reader.Close();
            }

            FileStream fs = new FileStream(keyfile, FileMode.Open);
            byte[] encryptionKey = new Byte[fs.Length];
            fs.Read(encryptionKey, 0, encryptionKey.Length);
            fs.Close();

            //Nastavení vlastností Sinku (vrstva určená pro šifrování)
            Hashtable properties = new Hashtable();
            properties["algorithm"] = algorithm;
            properties["key"] = encryptionKey;

            IServerChannelSinkProvider newProvider = new EncryptionServerSinkProvider(properties, null);
            newProvider.Next = new APDUServerFormatterSinkProvider();

            // Registrování komunikačního kanálu, na kterém bude služba naslouchat 
            ChannelServices.RegisterChannel(new APDUServerChannel(newProvider, 33));

            // Registruje danou aplikaci jako server            
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(Service),
                REMOTE_OBJECT_URI,
                WellKnownObjectMode.Singleton);

            return 0;
        }
    }
}

