/// <summary>
        /// Gets the certificate that should be used for client authentication
        /// </summary>
        /// <remarks>
        /// This method will throw an exception if the configuration properties used to
        /// look for the certificate are invalid. However, if the configuration is valid
        /// and no certificate is found, null will be returned and it is up to the caller
        /// to determine if an exception should be thrown in that case.
        /// </remarks>
        /// <exception cref="AdkTransportException">Thrown if the configuration properties used
        /// to look for the certificate are invalid or a certificate is found but
        /// it's certificate chain is invalid</exception>
        /// <returns>The certificate found or <c>null</c></returns>
        public Certificate GetClientAuthenticationCertificate()
        {
            HttpsProperties props = (HttpsProperties)fProps;
            Certificate     cert  =
                GetCertificateFromStore(OID_CLIENT_AUTHENTICATION, props.ClientCertName);

            if (cert == null)
            {
                return(null);
            }

            DebugTransport
                ("Using this certificate for Client Authentication: {0}", cert.ToString(true));

            // ANDY E 07/26/2005 Removed the following code that verifies the chain of the certificate.
            // The reason is that the certificate doesn't really need to be trusted on this machine,
            // only on the machine that is receiving the certificate. Enabling the trust check here
            // makes configuration more difficult, and doesn't really help anything. If this code is
            // uncommented there will have to be more documentation added to the HTTPS documentation to
            // tell what all needs to be there for client certificates to be accepted by the ADK, especially
            // and specifically when an agent is running as a service.
            //			CertificateStatus status = cert.GetCertificateChain().VerifyChain( null, AuthType.Client );
            //
            //			if ( status != CertificateStatus.ValidCertificate )
            //			{
            //				log.Warn( "Certificate selected for client authentication is not valid: " + status.ToString() );
            //				return null;
            //			}

            return(cert);
        }
        /// <summary>
        /// Returns the system Certificate Store to retrieve certificates from
        /// </summary>
        /// <param name="props"></param>
        /// <returns></returns>
        private CertificateStore GetSystemStore(HttpsProperties props)
        {
            string        certStoreLocation = props.CertStoreLocation;
            StoreLocation loc;

            if (certStoreLocation == null)
            {
                loc = StoreLocation.CurrentUser;
            }
            else
            {
                try
                {
                    loc =
                        (StoreLocation)
                        Enum.Parse(typeof(StoreLocation), certStoreLocation, true);
                }
                catch
                {
                    throw new AdkTransportException
                              ("Invalid CertificateStore location: " + certStoreLocation, null);
                }
            }

            string certStoreName = props.CertStore;

            if (certStoreName == null)
            {
                certStoreName = CertificateStore.MyStore;
            }

            DebugTransport("Using Certificate store {0} / {1}", loc, certStoreName);

            return(new CertificateStore(loc, certStoreName));
        }
        /// <summary>
        /// Gets the certificate that should be used for server authentication ( SSL )
        /// </summary>
        /// <remarks>
        /// This method will throw an exception if the configuration properties used to
        /// look for the certificate are invalid. However, if the configuration is valid
        /// and no certificate is found, null will be returned and it is up to the caller
        /// to determine if an exception should be thrown in that case.
        /// </remarks>
        /// <exception cref="AdkTransportException">Thrown if the configuration properties used
        /// to look for the certificate are invalid</exception>
        /// <returns>The certificate found or <c>null</c></returns>
        public Certificate GetServerAuthenticationCertificate()
        {
            HttpsProperties props = (HttpsProperties)fProps;
            Certificate     cert  =
                GetCertificateFromStore(OID_SERVER_AUTHENTICATION, props.SSLCertName);

            return(cert);
        }
        /// <summary>  Clone this HttpTransport.
        ///
        /// Cloning a transport results in a new HttpTransport instance with
        /// HttpProperties that inherit from this object's properties. However, the
        ///  web server owned by this transport will be shared with the cloned
        /// instance.
        /// </summary>
        public ITransport CloneTransport()
        {
            HttpProperties props;

            if (fProps is HttpsProperties)
            {
                props = new HttpsProperties((HttpsProperties)fProps.Parent);
            }
            else
            {
                props = new HttpProperties((HttpProperties)fProps.Parent);
            }
            //  This object and the clone share the  server
            HttpTransport t = new HttpTransport(props, sServer);

            return(t);
        }
Beispiel #5
0
        public void SetUpTest()
        {
            Adk.Debug = AdkDebugFlags.All;
            Adk.Initialize();

            ServicePointManager.CertificatePolicy = new TestCertificatePolicy();
            ServicePointManager.CheckCertificateRevocationList = false;
            //ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

            fTransport = (HttpTransport)fAgent.TransportManager.GetTransport("https");

            fProps                 = (HttpsProperties)fTransport.Properties;
            fProps.Port            = 9000;
            fProps.CertStore       = CERT_STORE;
            fProps.ClientAuthLevel = 0;
            fProps.ClientCertName  = null;



            fZone = new TestZone();
            fZone.Properties.MessagingMode = AgentMessagingMode.Push;
        }
Beispiel #6
0
        private static NameValueCollection ParseAgentProperties(Agent agent)
        {
            //  Parse all other options...
            AgentProperties     props = agent.Properties;
            NameValueCollection misc  = new NameValueCollection();

            int    port       = -1;
            string host       = null;
            bool   useHttps   = false;
            string sslCert    = null;
            string clientCert = null;
            int    clientAuth = 0;

            for (int i = 0; i < sArguments.Length; i++)
            {
                if (sArguments[i].ToUpper().Equals("/sourceId".ToUpper()) &&
                    i != sArguments.Length - 1)
                {
                    agent.Id = sArguments[++i];
                }
                else if (sArguments[i].ToUpper().Equals("/noreg".ToUpper()))
                {
                    Reg = false;
                }
                else if (sArguments[i].ToUpper().Equals("/unreg".ToUpper()))
                {
                    Unreg = true;
                }
                else if (sArguments[i].ToUpper().Equals("/pull".ToUpper()))
                {
                    props.MessagingMode = AgentMessagingMode.Pull;
                }
                else if (sArguments[i].ToUpper().Equals("/push".ToUpper()))
                {
                    props.MessagingMode = AgentMessagingMode.Push;
                }
                else if (sArguments[i].ToUpper().Equals("/port".ToUpper()) &&
                         i != sArguments.Length - 1)
                {
                    try
                    {
                        port = Int32.Parse(sArguments[++i]);
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine("Invalid port: " + sArguments[i - 1]);
                    }
                }
                else if (sArguments[i].ToUpper().Equals("/https".ToUpper()))
                {
                    useHttps = true;
                }
                else if (sArguments[i].ToUpper().Equals("/sslCert".ToUpper()))
                {
                    sslCert = sArguments[++i];
                }
                else if (sArguments[i].ToUpper().Equals("/clientCert".ToUpper()))
                {
                    clientCert = sArguments[++i];
                }
                else if (sArguments[i].ToUpper().Equals("/clientAuth".ToUpper()))
                {
                    try
                    {
                        clientAuth = int.Parse(sArguments[++i]);
                    }
                    catch (FormatException)
                    {
                        clientAuth = 0;
                    }
                }
                else if (sArguments[i].ToUpper().Equals("/host".ToUpper()) &&
                         i != sArguments.Length - 1)
                {
                    host = sArguments[++i];
                }
                else if (sArguments[i].ToUpper().Equals("/timeout".ToUpper()) &&
                         i != sArguments.Length - 1)
                {
                    try
                    {
                        props.DefaultTimeout =
                            TimeSpan.FromMilliseconds(Int32.Parse(sArguments[++i]));
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine("Invalid timeout: " + sArguments[i - 1]);
                    }
                }
                else if (sArguments[i].ToUpper().Equals("/freq".ToUpper()) &&
                         i != sArguments.Length - 1)
                {
                    try
                    {
                        props.PullFrequency =
                            TimeSpan.FromMilliseconds(int.Parse(sArguments[++i]));
                    }
                    catch (FormatException)
                    {
                        Console.WriteLine
                            ("Invalid pull frequency: " + sArguments[i - 1]);
                    }
                }
                else if (sArguments[i].ToUpper().Equals("/opensif".ToUpper()))
                {
                    //  OpenSIF reports attempts to re-subscribe to objects as an
                    //  error instead of a success status code. The Adk would therefore
                    //  throw an exception if it encountered the error, so we can
                    //  disable that behavior here.

                    props.IgnoreProvisioningErrors = true;
                }
                else if (sArguments[i][0] == '/')
                {
                    if (i == sArguments.Length - 1 ||
                        sArguments[i + 1].StartsWith("/"))
                    {
                        misc[sArguments[i].Substring(1)] = null;
                    }
                    else
                    {
                        misc[sArguments[i].Substring(1)] = sArguments[++i];
                    }
                }
            }

            if (useHttps)
            {
                //  Set transport properties (HTTPS)
                HttpsProperties https = agent.DefaultHttpsProperties;
                if (sslCert != null)
                {
                    https.SSLCertName = sslCert;
                }
                if (clientCert != null)
                {
                    https.ClientCertName = clientCert;
                }

                https.ClientAuthLevel = clientAuth;

                if (port != -1)
                {
                    https.Port = port;
                }
                https.Host = host;

                props.TransportProtocol = "https";
            }
            else
            {
                //  Set transport properties (HTTP)
                HttpProperties http = agent.DefaultHttpProperties;
                if (port != -1)
                {
                    http.Port = port;
                }
                http.Host = host;

                props.TransportProtocol = "http";
            }

            return(misc);
        }
Beispiel #7
0
    /// <summary>  Parse the command-line. This method may be called repeatedly, usually
    /// once from the sample agent's <c>main</code> function prior to
    /// initializing the Adk and again from the <c>Agent.initialize</code>
    /// method after initializing the Agent superclass. When called without an
    /// Agent instance, only those options that do not rely on an AgentProperties
    /// object are processed (e.g. the /D option).
    /// <p>
    /// *
    /// If a file named 'agent.rsp' exists in the current directory, any command
    /// line options specified will be appended to the command-line arguments
    /// passed to this method. Each line of the agent.rsp text file may be
    /// comprised of one or more arguments separated by spaces, so that the
    /// entirely set of arguments can be on one line or broken up onto many
    /// lines.<p>
    /// *
    /// </summary>
    /// <param name="agent">An Agent instance that will be updated when certain
    /// command-line options are parsed
    /// </param>
    /// <param name="arguments">The string of arguments provided by the <c>main</code>
    /// function
    ///
    /// </param>
    public static NameValueCollection parseCL(Agent agent,
                                              string[] arguments)
    {
        if (args == null)
        {
            args = arguments;

            if (args.Length > 0 && args[0][0] != '/')
            {
                //  Look for an agent.rsp response file
                FileInfo rsp = new FileInfo(args[0]);
                if (rsp.Exists)
                {
                    try
                    {
                        ArrayList v = new ArrayList();
                        using (StreamReader reader = File.OpenText(rsp.FullName))
                        {
                            string line = null;
                            while ((line = reader.ReadLine()) != null)
                            {
                                // allow comment lines, starting with a ;
                                if (!line.StartsWith(";"))
                                {
                                    foreach (string token in line.Split(' '))
                                    {
                                        v.Add(token);
                                    }
                                }
                            }
                            reader.Close();
                        }

                        //  Append any arguments found to the args array
                        if (v.Count > 0)
                        {
                            args = new string[args.Length + v.Count];
                            Array.Copy(arguments, 0, args, 0, arguments.Length);
                            v.CopyTo(args, arguments.Length);
                            Console.Out.Write
                                ("Reading command-line arguments from " + args[0] + ": ");
                            for (int i = 0; i < args.Length; i++)
                            {
                                Console.Out.Write(args[i] + " ");
                            }
                            Console.WriteLine();
                            Console.WriteLine();
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine
                            ("Error reading command-line arguments from agent.rsp file: " + ex);
                    }
                }
            }
        }

        if (agent == null)
        {
            //  Look for options that do not affect the AgentProperties...
            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].ToUpper().Equals("/debug".ToUpper()))
                {
                    if (i < args.Length - 1)
                    {
                        try
                        {
                            Adk.Debug = AdkDebugFlags.None;
                            int k = Int32.Parse(args[++i]);
                            if (k == 1)
                            {
                                Adk.Debug = AdkDebugFlags.Minimal;
                            }
                            else if (k == 2)
                            {
                                Adk.Debug = AdkDebugFlags.Moderate;
                            }
                            else if (k == 3)
                            {
                                Adk.Debug = AdkDebugFlags.Detailed;
                            }
                            else if (k == 4)
                            {
                                Adk.Debug = AdkDebugFlags.Very_Detailed;
                            }
                            else if (k == 5)
                            {
                                Adk.Debug = AdkDebugFlags.All;
                            }
                        }
                        catch (Exception)
                        {
                            Adk.Debug = AdkDebugFlags.All;
                        }
                    }
                    else
                    {
                        Adk.Debug = AdkDebugFlags.All;
                    }
                }
                else if (args[i].StartsWith("/D"))
                {
                    string prop = args[i].Substring(2);
                    if (i != args.Length - 1)
                    {
                        Properties.SetProperty(prop, args[++i]);
                    }
                    else
                    {
                        Console.WriteLine("Usage: /Dproperty value");
                    }
                }
                else if (args[i].ToUpper().Equals("/log".ToUpper()) && i != args.Length - 1)
                {
                    try
                    {
                        Adk.SetLogFile(args[++i]);
                    }
                    catch (IOException ioe)
                    {
                        Console.WriteLine("Could not redirect debug output to log file: " + ioe);
                    }
                }
                else if (args[i].ToUpper().Equals("/ver".ToUpper()) && i != args.Length - 1)
                {
                    Version = SifVersion.Parse(args[++i]);
                }
                else if (args[i].Equals("/?"))
                {
                    Console.WriteLine();
                    Console.WriteLine
                    (
                        "These options are common to all Adk Example agents. For help on the usage");
                    Console.WriteLine
                    (
                        "of this agent in particular, run the agent without any parameters. Note that");
                    Console.WriteLine
                    (
                        "most agents support multiple zones if a zones.properties file is found in");
                    Console.WriteLine("the current directory.");
                    Console.WriteLine();
                    printHelp();

                    Environment.Exit(0);
                }
            }

            return(null);
        }

        //  Parse all other options...
        AgentProperties     props = agent.Properties;
        NameValueCollection misc  = new NameValueCollection();

        int    port       = -1;
        string host       = null;
        bool   useHttps   = false;
        string sslCert    = null;
        string clientCert = null;
        int    clientAuth = 0;

        for (int i = 0; i < args.Length; i++)
        {
            if (args[i].ToUpper().Equals("/sourceId".ToUpper()) && i != args.Length - 1)
            {
                agent.Id = args[++i];
            }
            else if (args[i].ToUpper().Equals("/noreg".ToUpper()))
            {
                Reg = false;
            }
            else if (args[i].ToUpper().Equals("/unreg".ToUpper()))
            {
                Unreg = true;
            }
            else if (args[i].ToUpper().Equals("/pull".ToUpper()))
            {
                props.MessagingMode = AgentMessagingMode.Pull;
            }
            else if (args[i].ToUpper().Equals("/push".ToUpper()))
            {
                props.MessagingMode = AgentMessagingMode.Push;
            }
            else if (args[i].ToUpper().Equals("/port".ToUpper()) && i != args.Length - 1)
            {
                try
                {
                    port = Int32.Parse(args[++i]);
                }
                catch (FormatException)
                {
                    Console.WriteLine("Invalid port: " + args[i - 1]);
                }
            }
            else if (args[i].ToUpper().Equals("/https".ToUpper()))
            {
                useHttps = true;
            }
            else if (args[i].ToUpper().Equals("/sslCert".ToUpper()))
            {
                sslCert = args[++i];
            }
            else if (args[i].ToUpper().Equals("/clientCert".ToUpper()))
            {
                clientCert = args[++i];
            }
            else if (args[i].ToUpper().Equals("/clientAuth".ToUpper()))
            {
                try
                {
                    clientAuth = int.Parse(args[++i]);
                }
                catch (FormatException)
                {
                    clientAuth = 0;
                }
            }
            else if (args[i].ToUpper().Equals("/host".ToUpper()) && i != args.Length - 1)
            {
                host = args[++i];
            }
            else if (args[i].ToUpper().Equals("/timeout".ToUpper()) && i != args.Length - 1)
            {
                try
                {
                    props.DefaultTimeout = TimeSpan.FromMilliseconds(Int32.Parse(args[++i]));
                }
                catch (FormatException)
                {
                    Console.WriteLine("Invalid timeout: " + args[i - 1]);
                }
            }
            else if (args[i].ToUpper().Equals("/freq".ToUpper()) && i != args.Length - 1)
            {
                try
                {
                    props.PullFrequency = TimeSpan.FromMilliseconds(int.Parse(args[++i]));
                }
                catch (FormatException)
                {
                    Console.WriteLine("Invalid pull frequency: " + args[i - 1]);
                }
            }
            else if (args[i].ToUpper().Equals("/opensif".ToUpper()))
            {
                //  OpenSIF reports attempts to re-subscribe to objects as an
                //  error instead of a success status code. The Adk would therefore
                //  throw an exception if it encountered the error, so we can
                //  disable that behavior here.

                props.IgnoreProvisioningErrors = true;
            }
            else if (args[i][0] == '/')
            {
                if (i == args.Length - 1 || args[i + 1].StartsWith("/"))
                {
                    misc[args[i].Substring(1)] = null;
                }
                else
                {
                    misc[args[i].Substring(1)] = args[++i];
                }
            }
        }

        if (useHttps)
        {
            //  Set transport properties (HTTPS)
            HttpsProperties https = agent.DefaultHttpsProperties;
            if (sslCert != null)
            {
                https.SSLCertName = sslCert;
            }
            if (clientCert != null)
            {
                https.ClientCertName = clientCert;
            }

            https.ClientAuthLevel = clientAuth;

            if (port != -1)
            {
                https.Port = port;
            }
            https.Host              = host;
            https.PushHost          = host;
            props.TransportProtocol = "https";
        }
        else
        {
            //  Set transport properties (HTTP)
            HttpProperties http = agent.DefaultHttpProperties;
            if (port != -1)
            {
                http.Port = port;
            }
            http.Host = host;

            props.TransportProtocol = "http";
        }

        return(misc);
    }
        /// <summary>
        /// Returns the system Certificate Store to retrieve certificates from
        /// </summary>
        /// <param name="props"></param>
        /// <returns></returns>
        private CertificateStore GetSystemStore( HttpsProperties props )
        {
            string certStoreLocation = props.CertStoreLocation;
            StoreLocation loc;
            if ( certStoreLocation == null )
            {
                loc = StoreLocation.CurrentUser;
            }
            else
            {
                try
                {
                    loc =
                        (StoreLocation)
                        Enum.Parse( typeof ( StoreLocation ), certStoreLocation, true );
                }
                catch
                {
                    throw new AdkTransportException
                        ( "Invalid CertificateStore location: " + certStoreLocation, null );
                }
            }

            string certStoreName = props.CertStore;
            if ( certStoreName == null )
            {
                certStoreName = CertificateStore.MyStore;
            }

            DebugTransport( "Using Certificate store {0} / {1}", loc, certStoreName );

            return new CertificateStore( loc, certStoreName );
        }
 /// <summary>  Clone this HttpTransport.
 /// 
 /// Cloning a transport results in a new HttpTransport instance with
 /// HttpProperties that inherit from this object's properties. However, the
 ///  web server owned by this transport will be shared with the cloned
 /// instance.
 /// </summary>
 public ITransport CloneTransport()
 {
     HttpProperties props;
     if ( fProps is HttpsProperties )
     {
         props = new HttpsProperties( (HttpsProperties) fProps.Parent );
     }
     else
     {
         props = new HttpProperties( (HttpProperties) fProps.Parent );
     }
     //  This object and the clone share the  server
     HttpTransport t = new HttpTransport( props, sServer );
     return t;
 }
Beispiel #10
0
        private Certificate GetCertificateFromStore(string oid,
                                                    string certName)
        {
            HttpsProperties props = (HttpsProperties)fProps;

            // First, look for a file-based certificate, if specified in the props
            CertificateStore certStore = null;
            string           certFile  = props.SSLCertFile;

            if (certFile != null)
            {
                FileInfo info = new FileInfo(certFile);
                if (info.Exists)
                {
                    if (info.Extension == ".pfx")
                    {
                        string cfp = props.SSLCertFilePassword;
                        certStore = CertificateStore.CreateFromPfxFile(info.FullName, cfp);
                        DebugTransport("Using certificate file '{0}'", info.FullName);
                    }
                    else
                    {
                        throw new AdkTransportException
                                  ("Certificate file must be in the .PFX format", null);
                    }
                }
                else
                {
                    throw new FileNotFoundException
                              ("Unable to locate specified certificate file: " + certFile, certFile);
                }
            }

            if (certStore == null)
            {
                certStore = GetSystemStore(props);
            }

            Certificate cert = null;

            if (certName != null)
            {
                cert = certStore.FindCertificateBySubjectName(certName);
            }
            else
            {
                // Find the first applicable certificate
                foreach (Certificate c in certStore.EnumCertificates())
                {
                    if (!c.HasPrivateKey())
                    {
                        DebugTransport
                            ("Ignoring Certificate {0} because it has no private key",
                            c.ToString(true));
                        continue;
                    }
                    if (!c.SupportsDataEncryption)
                    {
                        DebugTransport
                            ("Ignoring Certificate {0} because it doesn't support data encryption",
                            c.ToString(true));
                        continue;
                    }
                    if (c.GetEffectiveDate() > DateTime.Now)
                    {
                        DebugTransport
                            ("Ignoring Certificate {0} because the effective date is in the future.",
                            c.ToString(true));
                        continue;
                    }
                    if (c.GetExpirationDate() < DateTime.Now)
                    {
                        DebugTransport
                            ("Ignoring Certificate {0} because it has expired", c.ToString(true));
                        continue;
                    }
                    StringCollection enhancedUsages = c.GetEnhancedKeyUsage();
                    if (enhancedUsages.Count > 0 && !enhancedUsages.Contains(oid))
                    {
                        DebugTransport
                            ("Ignoring Certificate {0} because it has an enhanced key usage attribute, that doesn't include {1}",
                            c.ToString(true), oid);
                        continue;
                    }
                    cert = c;
                    break;
                }
            }

            return(cert);
        }