Exemplo n.º 1
0
        public async Task <IActionResult> GetLocalIPs()
        {
            var ips       = Utility.GetLocalIPs(AppConfig.IgnoreRFC1918);
            var addresses = ips.Select(ip => ip.ToString()).ToList();

            if (addresses.Count == 0)
            {
                var ip = await _outgoingIpResolver.Resolve();

                addresses.Add(ip.ToString());
            }

            _response.Result = addresses;
            return(Ok(_response));
        }
Exemplo n.º 2
0
        Connect(HttpContext httpContext, string nodeKey)
        {
            var errors = new Dictionary <string, object>();

            // Ok, we aren't already connected. Let's go try talking to the backend and set ourselves up.
            var request = new RestRequest("unauth/node", Method.POST)
            {
                RequestFormat = DataFormat.Json
            };

            var generatedPassword = PasswordUtils.GeneratePassword(24, 0);
            var body = new UnauthNodeAddRequest {
                InstallId = _identityProvider.GetGuid().ToString()
            };

            var ownIp = await _ipResolver.Resolve();

            body.Ip = ownIp.ToString();

            body.Port = httpContext.Connection.LocalPort;

            body.Protocol = "http"; // TODO: When HTTPs support lands, use -> httpContext.Request.Protocol.ToLower() which returns things like http/1.1 (needs further parsing);

            body.NodeKey     = nodeKey;
            body.AccessToken = _defaultCloudUserName + ":" + generatedPassword;

            // This is data about *THIS* specific system being contributed to the cloud/CRM.
            body.SystemData = _apm.GetAllDetails();
            body.Version    = AppConfig.version;

            // Ok, we got the user created. Everything is ready, let's send off the request.
            var serializedBody = JsonConvert.SerializeObject(body);

            _logger.LogDebug($"We will be sending: {serializedBody}");

            request.AddParameter("application/json; charset=utf-8", serializedBody, ParameterType.RequestBody);

            // We have to ensure this user actually exists before sending off the request.
            // First, we need to remove any cached representation.
            AuthUtils.ClearUserFromCacheIfExists(_cache, _defaultCloudUserName);

            // Check if the cloud connect user exists already.
            var user = await _db.SingleAsync <User>(x => x.AuthKey == _defaultCloudUserName) ?? new User();

            user.AuthKey        = _defaultCloudUserName;
            user.PasswordSetter = generatedPassword;
            user.EmailAddress   = _defaultCloudUserName + $"@spectero.com";
            user.FullName       = "Spectero Cloud Management User";
            user.Roles          = new List <User.Role> {
                User.Role.SuperAdmin
            };
            user.Source        = User.SourceTypes.SpecteroCloud;
            user.CloudSyncDate = DateTime.Now;
            user.CertKey       = PasswordUtils.GeneratePassword(48, 6);

            var userCertBytes = _cryptoService.IssueUserChain(user.AuthKey, new[] { KeyPurposeID.IdKPClientAuth }, user.CertKey);

            user.Cert = Convert.ToBase64String(userCertBytes);

            // Checks if user existed already, or is being newly created.
            if (user.Id != 0L)
            {
                await _db.UpdateAsync(user);
            }
            else
            {
                user.CreatedDate = DateTime.Now;
                await _db.InsertAsync(user);
            }

            var response = _restClient.Execute(request);


            if (response.ErrorException != null)
            {
                _logger.LogError(response.ErrorException, "CC: Connect attempt to the Spectero Cloud failed!");

                errors.Add(Core.Constants.Errors.FAILED_TO_CONNECT_TO_SPECTERO_CLOUD, response.ErrorMessage);

                await DeleteCloudUserIfExists();

                return(false, errors, HttpStatusCode.ServiceUnavailable, null);
            }

            CloudAPIResponse <Node> parsedResponse = null;

            try
            {
                // Parse after error checking.
                parsedResponse = JsonConvert.DeserializeObject <CloudAPIResponse <Node> >(response.Content);
            }
            catch (JsonException e)

            {
                // The Cloud Backend fed us bogus stuff, let's bail.
                _logger.LogError(e, "CC: Connect attempt to the Spectero Cloud failed!");
                _logger.LogDebug("Cloud API said: " + response.Content);

                errors.Add(Core.Constants.Errors.FAILED_TO_CONNECT_TO_SPECTERO_CLOUD, e.Message);

                await DeleteCloudUserIfExists();

                return(false, errors, HttpStatusCode.ServiceUnavailable, parsedResponse);
            }


            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (response.StatusCode)
            {
            case HttpStatusCode.Created:

                await ConfigUtils.CreateOrUpdateConfig(_db, ConfigKeys.CloudConnectStatus, true.ToString());

                await ConfigUtils.CreateOrUpdateConfig(_db, ConfigKeys.CloudConnectIdentifier, parsedResponse?.result.id.ToString());

                await ConfigUtils.CreateOrUpdateConfig(_db, ConfigKeys.CloudConnectNodeKey, nodeKey);

                break;

            default:
                // Likely a 400 or a 409, just show the response as is.
                errors.Add(Core.Constants.Errors.FAILED_TO_CONNECT_TO_SPECTERO_CLOUD, "");
                errors.Add(Core.Constants.Errors.RESPONSE_CODE, response.StatusCode);
                errors.Add(Core.Constants.Errors.NODE_PERSIST_FAILED, parsedResponse?.errors);

                _logger.LogDebug("Cloud API said: " + response.Content);

                await DeleteCloudUserIfExists();

                return(false, errors, HttpStatusCode.ServiceUnavailable, parsedResponse);
            }

            return(true, errors, HttpStatusCode.OK, parsedResponse);
        }