Esempio n. 1
0
        public void Up()
        {
            var  instanceId         = Guid.NewGuid().ToString();
            long viablePasswordCost = _config.PasswordCostLowerThreshold;

            var specteroCertKey = "";
            X509Certificate2 specteroCertificate = null;
            X509Certificate2 ca = null;

            var localIPs = Utility.GetLocalIPs(_config.IgnoreRFC1918);


            if (!_db.TableExists <Configuration>())
            {
                _db.CreateTable <Configuration>();
                _logger.LogDebug("Firstrun: Creating Configurations table and inserting default values");

                // Identity
                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.SystemIdentity,
                    Value = instanceId
                });

                // Schema version
                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.SchemaVersion,
                    Value = AppConfig.version
                });

                // Cloud Connectivity
                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.CloudConnectStatus,
                    Value = false.ToString()
                });

                // HTTP proxy
                var httpSkeleton      = Defaults.HTTP.Value;
                var proposedListeners = localIPs.Select(ip => Tuple.Create(ip.ToString(), 10240))
                                        .ToList();
                if (proposedListeners.Count > 0)
                {
                    httpSkeleton.listeners = proposedListeners;
                }

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.HttpConfig,
                    Value = JsonConvert.SerializeObject(httpSkeleton)
                });

                // Password Hashing
                _logger.LogDebug("Firstrun: Calculating optimal password hashing cost.");
                viablePasswordCost = AuthUtils.GenerateViableCost(_config.PasswordCostCalculationTestTarget,
                                                                  _config.PasswordCostCalculationIterations,
                                                                  _config.PasswordCostTimeThreshold, _config.PasswordCostLowerThreshold);
                _logger.LogDebug($"Firstrun: Determined {viablePasswordCost} to be the optimal password hashing cost.");
                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.PasswordHashingCost,
                    Value = viablePasswordCost.ToString()
                });

                // JWT security Key
                _logger.LogDebug("Firstrun: Generating JWT security key.");
                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.JWTSymmetricSecurityKey,
                    Value = PasswordUtils.GeneratePassword(48, 8)
                });

                // Crypto
                // 48 characters len with 12 non-alpha-num characters
                // Ought to be good enough for everyone. -- The IPv4 working group, 1996
                var caPassword     = PasswordUtils.GeneratePassword(48, 8);
                var serverPassword = PasswordUtils.GeneratePassword(48, 8);

                ca = _cryptoService.CreateCertificateAuthorityCertificate($"CN={instanceId}.ca.instance.spectero.io",
                                                                          null, null, caPassword);

                var serverCertificate = _cryptoService.IssueCertificate($"CN={instanceId}.instance.spectero.io", ca, null,
                                                                        new[] { KeyPurposeID.AnyExtendedKeyUsage, KeyPurposeID.IdKPServerAuth }, serverPassword,
                                                                        new KeyUsage(KeyUsage.DigitalSignature | KeyUsage.KeyEncipherment));

                specteroCertKey     = PasswordUtils.GeneratePassword(48, 8);
                specteroCertificate = _cryptoService.IssueCertificate(
                    "CN=" + "spectero", ca, null,
                    new[] { KeyPurposeID.IdKPClientAuth }, specteroCertKey);


                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.CeritificationAuthorityPassword,
                    Value = caPassword
                });

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.ServerCertificatePassword,
                    Value = serverPassword
                });

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.CertificationAuthority,
                    Value = Convert.ToBase64String(_cryptoService.GetCertificateBytes(ca, caPassword))
                });

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.ServerCertificate,
                    Value = Convert.ToBase64String(_cryptoService.GetCertificateBytes(serverCertificate, serverPassword))
                });

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.ServerPFXChain,
                    Value = Convert.ToBase64String(_cryptoService.ExportCertificateChain(serverCertificate, ca)) // Yes, passwordless. Somewhat intentionally, as this is mostly consumed by 3rd party apps.
                });

                // OpenVPN defaults

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.OpenVPNListeners,
                    Value = JsonConvert.SerializeObject(Defaults.OpenVPNListeners)
                });

                _db.Insert(new Configuration
                {
                    Key   = ConfigKeys.OpenVPNBaseConfig,
                    Value = JsonConvert.SerializeObject(Defaults.OpenVPN.Value)
                });
            }

            if (!_db.TableExists <User>())
            {
                _logger.LogDebug("Firstrun: Creating Users table");
                var password = PasswordUtils.GeneratePassword(16, 8);
                _db.CreateTable <User>();
                _db.Insert(new User
                {
                    AuthKey = "spectero",
                    Roles   = new List <User.Role>
                    {
                        User.Role.SuperAdmin
                    },
                    FullName     = "Spectero Administrator",
                    EmailAddress = "*****@*****.**",
                    Password     = BCrypt.Net.BCrypt.HashPassword(password, (int)viablePasswordCost),
                    Cert         = specteroCertificate != null && ca != null ? Convert.ToBase64String(_cryptoService.ExportCertificateChain(specteroCertificate, ca, specteroCertKey)) : "",
                    CertKey      = specteroCertKey,
                    Source       = User.SourceTypes.Local,
                    CreatedDate  = DateTime.Now
                });

                using (var tw = new StreamWriter(_firstRunConfigName, false))
                {
                    tw.WriteLine("username: spectero");
                    tw.WriteLine($"password: {password}");
                }
            }


            if (!_db.TableExists <Statistic>())
            {
                _logger.LogDebug("Firstrun: Creating Statistics table");
                _db.CreateTable <Statistic>();

                _logger.LogInformation("Firstrun: Initialization complete.");
            }
        }