public async static Task <X509Certificate2> GetSSLCertificate(StoreName storeName, string subject)
        {
            var x509Certificates = await SSLCertificateServices.GetSSLCertificates(storeName);

            X509Certificate2 x509Certificate = x509Certificates.Where(c => c.HasPrivateKey && c.Subject == subject).OrderByDescending(c => c.NotAfter).FirstOrDefault();

            return(x509Certificate);
        }
        public async static Task <bool> TryFindAndBindLatestSSLCertToPort(int portNumber, string subject, StoreName storeName = StoreName.My, Action <string> OnInfoLog = null, Action <string> OnErrorLog = null, bool RemoveAnyPreviousBinding = true, string IP = "0.0.0.0")
        {
            if (string.IsNullOrWhiteSpace(subject))
            {
                OnErrorLog?.Invoke("Unable to bind SSL Cert to Port as no certificate subject was specified.");
                return(false);
            }
            //List<X509Certificate2> x509Certificates = new List<X509Certificate2>();
            var certs = await SSLCertificateServices.GetSSLCertificates(storeName);

            X509Certificate2 x509Certificate = certs.Where(c => c.HasPrivateKey && c.Subject == subject).OrderByDescending(c => c.NotAfter).FirstOrDefault();

            if (x509Certificate == null)
            {
                OnErrorLog?.Invoke("Unable to find SSL Certificate with subject '" + subject + "' in certificte store '" + storeName.ToString() + "'");
                return(false);
            }

            string applicationId = null;
            var    asm           = Assembly.GetEntryAssembly();

            if (asm == null)
            {
                applicationId = Guid.NewGuid().ToString();
            }
            else
            {
                try
                {
                    applicationId = ((GuidAttribute)Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;
                }
                catch
                { }
            }
            if (applicationId == null)
            {
                applicationId = Guid.NewGuid().ToString();
            }


            if (!SSLCertificateServices.SSLCertBinded(x509Certificate.Thumbprint, portNumber))
            {
                //Remove any Previously Binded SSL Sert at PORT
                if (RemoveAnyPreviousBinding)
                {
                    RemoveSSLCertFromPort(IP, portNumber, (log) => OnInfoLog?.Invoke(log));
                }

                try
                {
                    string BindCommand = "netsh http add sslcert ipport=" + IP + ":" + portNumber + " certhash=" + x509Certificate.Thumbprint + " appid={" + applicationId + "}";
                    OnInfoLog?.Invoke("Binding SSL Certificate '" + subject + "' to " + IP + ":" + portNumber); // + " via Command=" + BindCommand)
                    string BindResultText = ExecuteCommand(BindCommand).RemoveAllNewLines().Trim(' ');
                    OnInfoLog?.Invoke(BindResultText);
                }
                catch (Exception ex)
                {
                    OnErrorLog?.Invoke("Unable to bind generate SSL Certificate to Port " + portNumber + "\r\n" + ex.ToString());
                    return(false);
                }
            }
            return(true);
        }
Example #3
0
        public async Task <bool> StartAsync()
        {
            this.OnInfoLog?.Invoke("Starting Vlix Web Server...");

            _listener = new HttpListener();

            if (this.Config.EnableHTTP)
            {
                _listener.Prefixes.Add("http://*:" + this.Config.HTTPPort.ToString() + "/");
            }
            if (this.Config.EnableHTTPS)
            {
                if (this.Config.EnableHTTP && (this.Config.HTTPPort == this.Config.HTTPSPort))
                {
                    this.OnErrorLog?.Invoke("Failed to start HTTPS Web Server (HTTPS Port cannot be the same as HTTP Port)!");
                    throw new Exception("Failed to start HTTPS Web Server (HTTPS Port cannot be the same as HTTP Port)!");
                }
                if (!await SSLCertificateServices.TryFindAndBindLatestSSLCertToPort(this.Config.HTTPSPort, this.Config.SSLCertificateSubjectName, this.Config.SSLCertificateStoreName, (log) => this.OnInfoLog?.Invoke(log), (log) => this.OnErrorLog?.Invoke(log)).ConfigureAwait(false))
                {
                    this.OnErrorLog?.Invoke("Failed to Start Web Server (Unable to bind SSL Cert to Port)!");
                    throw new Exception("Failed to Start Web Server (Unable to bind SSL Cert to Port)!");
                }
                ;
                _listener.Prefixes.Add("https://*:" + this.Config.HTTPSPort.ToString() + "/");
                _ = Task.Run(async() =>
                {
                    while (true)
                    {
                        await Task.Delay(60000 * 5).ConfigureAwait(false);
                        if (!await SSLCertificateServices.TryFindAndBindLatestSSLCertToPort(this.Config.HTTPSPort, this.Config.SSLCertificateSubjectName, this.Config.SSLCertificateStoreName, (log) => this.OnInfoLog?.Invoke(log), (log) => this.OnErrorLog?.Invoke(log)).ConfigureAwait(false))
                        {
                            this.OnErrorLog?.Invoke("Failed to Start Web Server (Unable to bind SSL Cert to Port)!");
                            throw new Exception("Failed to Start Web Server (Unable to bind SSL Cert to Port)!");
                        }
                        ;
                    }
                });
            }
            if (!this.Config.EnableHTTP && !this.Config.EnableHTTPS)
            {
                this.OnInfoLog?.Invoke("Unable to start as both HTTP (Port " + this.Config.HTTPPort + ") and HTTPS (Port " + this.Config.HTTPSPort + ") is disabled");
                return(false);
            }
            if (this.Config.EnableHTTP && !this.Config.EnableHTTPS)
            {
                this.OnInfoLog?.Invoke("Listening to port " + this.Config.HTTPPort + "(HTTP), Directory = '" + this.Config.WWWDirectoryParsed() + "'");
            }
            if (!this.Config.EnableHTTP && this.Config.EnableHTTPS)
            {
                this.OnInfoLog?.Invoke("Listening to port " + this.Config.HTTPSPort + "(HTTPS), Directory = '" + this.Config.WWWDirectoryParsed() + "'");
            }
            if (this.Config.EnableHTTP && this.Config.EnableHTTPS)
            {
                this.OnInfoLog?.Invoke("Listening to port " + this.Config.HTTPPort + "(HTTP) and " + this.Config.HTTPSPort + "(HTTPS), Directory = '" + this.Config.WWWDirectoryParsed() + "'");
            }

            _listener.Start();
            _listener.BeginGetContext(OnContext, null); //The thread stops here waiting for content to come

            this.OnInfoLog?.Invoke("Vlix HTTP Server Started!");
            return(true);
        }