private async Task Connect(CancellationToken cancellationToken) { _logger.LogInformation("The listener service is waiting for authentication from the server..."); var connectionResult = EConnectionResult.Disconnected; connectionResult = await _sharedSettings.WaitForLogin(false, cancellationToken); if (connectionResult == EConnectionResult.Connected) { _hubConnection = BuildHubConnection(HttpTransportType.WebSockets, cancellationToken); connectionResult = await StartListener(cancellationToken); } if (connectionResult != EConnectionResult.Connected) { _logger.LogError($"Failed to start web sockets connection. Reason: {connectionResult}. Shutting down service."); _applicationLifetime.StopApplication(); } }
protected override async Task ExecuteAsync(CancellationToken cancellationToken) { try { if (cancellationToken.IsCancellationRequested) { return; } var connectionResult = await _sharedSettings.WaitForLogin(false, cancellationToken); if (connectionResult != EConnectionResult.Connected) { return; } var useHttps = !string.IsNullOrEmpty(_remoteSettings.Network.CertificateFilename); var certificatePath = _remoteSettings.CertificateFilePath(); _logger.LogInformation($"Using the ssl certificate at {certificatePath}"); if (_remoteSettings.Network.AutoGenerateCertificate) { // if no certificate name or password are specified, generate them automatically. if (string.IsNullOrEmpty(_remoteSettings.Network.CertificateFilename)) { throw new RemoteSecurityException( "The applicationSettings -> Network -> AutoGenerateCertificate is true, however there no setting for CertificateFilename"); } if (string.IsNullOrEmpty(_remoteSettings.Network.CertificatePassword)) { throw new RemoteSecurityException( "The applicationSettings -> Network -> AutoGenerateCertificate is true, however there no setting for CertificateFilename"); } useHttps = true; var renew = false; if (File.Exists(certificatePath)) { // Create a collection object and populate it using the PFX file using (var cert = new X509Certificate2(certificatePath, _remoteSettings.Network.CertificatePassword)) { // var effectiveDate = DateTime.Parse(cert.GetEffectiveDateString()); var expiresDate = DateTime.Parse(cert.GetExpirationDateString()); // if cert expires in next 14 days, then renew. if (DateTime.Now > expiresDate.AddDays(-14)) { renew = true; } } } else { renew = true; } // generate a new ssl certificate if (renew) { await RenewSslCertificate(certificatePath, cancellationToken); } } if (_remoteSettings.Network.EnforceHttps) { if (string.IsNullOrEmpty(_remoteSettings.Network.CertificateFilename)) { throw new RemoteSecurityException( "The server requires https, however a CertificateFile name is not specified."); } if (!File.Exists(certificatePath)) { throw new RemoteSecurityException( $"The certificate with the filename {certificatePath} does not exist."); } using (var cert = new X509Certificate2( certificatePath, _remoteSettings.Network.CertificatePassword)) { var effectiveDate = DateTime.Parse(cert.GetEffectiveDateString()); var expiresDate = DateTime.Parse(cert.GetExpirationDateString()); if (DateTime.Now < effectiveDate) { throw new RemoteSecurityException( $"The certificate with the filename {certificatePath} is not valid until {effectiveDate}."); } if (DateTime.Now > expiresDate) { throw new RemoteSecurityException( $"The certificate with the filename {certificatePath} expired on {expiresDate}."); } } } if (!useHttps && _remoteSettings.Network.EnforceHttps) { throw new RemoteSecurityException( "The remote agent is set to EnforceHttps, however no SSL certificate was found or able to be generated."); } if (!useHttps || File.Exists(certificatePath)) { if (_remoteSettings.Network.DownloadPort == null) { throw new RemoteSecurityException("The web server download port was not set."); } var port = _remoteSettings.Network.DownloadPort.Value; if (_remoteSettings.Network.EnableUPnP) { await EnableUPnp(port); } while (!cancellationToken.IsCancellationRequested) { try { _logger.LogInformation("Starting the data upload/download web server."); var host = new WebHostBuilder() .UseStartup <Startup>() .ConfigureServices(s => { s.AddSingleton(_sharedSettings); s.AddSingleton(_liveApis); s.AddSingleton(_memoryCache); s.AddSingleton(_logger); }) .UseKestrel(options => { options.Listen(IPAddress.Any, _remoteSettings.Network.DownloadPort ?? 33944, listenOptions => { // if there is a certificate then default to https if (useHttps) { listenOptions.UseHttps( certificatePath, _remoteSettings.Network.CertificatePassword); } }); }) .UseUrls((useHttps ? "https://*:" : "http://*:") + port) .Build(); await host.RunAsync(cancellationToken); } catch (OperationCanceledException) { } } } _logger.LogInformation("HttpService has stopped."); } catch (Exception ex) { _logger.LogError(ex, $"The following error was encountered with the http listening service. Http connections will not be available. {ex.Message}"); } }