Exemplo n.º 1
0
        private async Task <MemoryStream> CreateAppSettingsFile(RemoteAgentSettings settings, CancellationToken cancellationToken)
        {
            var remoteSettings = new RemoteSettings();

            // copy any settings across.
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.AppSettings);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Network);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Permissions);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Plugins);
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Alerts);
            //TODO these should be copied by the copy properties.
            remoteSettings.Permissions.AllowedHubs  = settings.RemoteApplicationSettings.AllowedHubs;
            remoteSettings.Permissions.AllowedPaths = settings.RemoteApplicationSettings.AllowedPaths;
            settings.RemoteApplicationSettings.CopyProperties(remoteSettings.Privacy);
            remoteSettings.NamingStandards.LoadDefault();

            remoteSettings.AppSettings.UserPrompt = false;
            remoteSettings.AppSettings.WebServer  = (HttpContext.Request.IsHttps ? "https://" : "http://") +
                                                    HttpContext.Request.Host + HttpContext.Request.PathBase.Value;
            remoteSettings.AppSettings.RemoteAgentId = Guid.NewGuid().ToString();

            var user = await _operations.RepositoryManager.GetUserAsync(User, cancellationToken);

            var dbRemoteAgent = new DexihRemoteAgent()
            {
                RemoteAgentId = remoteSettings.AppSettings.RemoteAgentId,
                RestrictIp    = false,
                Name          = remoteSettings.AppSettings.Name,
                UserId        = user.Id
            };

            if (settings.EmbedUserName)
            {
                remoteSettings.AppSettings.UserToken = await _operations.RepositoryManager.GenerateRemoteUserTokenAsync(user, remoteSettings.AppSettings.RemoteAgentId, cancellationToken);

                var hashedToken = SecureHash.CreateHash(remoteSettings.AppSettings.UserToken);
                dbRemoteAgent.HashedToken       = hashedToken;
                remoteSettings.AppSettings.User = user.UserName;
            }

            if (settings.RemoteApplicationSettings.AutoGenerateCertificate)
            {
                remoteSettings.Network.CertificateFilename = "dexih.pfx";
                remoteSettings.Network.CertificatePassword = EncryptString.GenerateRandomKey();
            }

            remoteSettings.Logging.LogLevel.Default   = settings.LogLevel;
            remoteSettings.Logging.LogLevel.System    = settings.LogLevel;
            remoteSettings.Logging.LogLevel.Microsoft = settings.LogLevel;

            await _operations.RepositoryManager.SaveRemoteAgent(user.Id, dbRemoteAgent, cancellationToken);

            var json = JsonSerializer.Serialize(remoteSettings, new JsonSerializerOptions()
            {
                WriteIndented = true
            });
            var appSettingsStream = new MemoryStream(Encoding.ASCII.GetBytes(json));

            return(appSettingsStream);
        }
        public void HashFunctions(string testValue)
        {
            //Use a for loop to similate gen sequence.
            var hashString1 = SecureHash.CreateHash(testValue);
            var hashString2 = SecureHash.CreateHash(testValue);

            Assert.NotEqual(hashString1, hashString2); //two hashes in a row should not be equal as they are salted;

            var hashString3 = SecureHash.CreateHash(testValue + " ");

            Assert.True(SecureHash.ValidateHash(testValue, hashString1));
            Assert.True(SecureHash.ValidateHash(testValue, hashString2));

            Assert.False(SecureHash.ValidateHash(testValue, hashString3));
            Assert.False(SecureHash.ValidateHash(testValue + "1", hashString1));

            var uniqueHash1 = UniqueHash.CreateHash(testValue);
            var uniqueHash2 = UniqueHash.CreateHash(testValue);

            Assert.Equal(uniqueHash1, uniqueHash2);

            var uniqueHash3 = UniqueHash.CreateHash(testValue + " ");

            Assert.NotEqual(uniqueHash1, uniqueHash3);
        }
Exemplo n.º 3
0
        public async Task <JsonResult> Login([FromBody] RemoteSettings remoteSettings, CancellationToken cancellationToken)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    _logger.LogInformation(LoggingEvents.RemoteLogin, "Login - Remote Agent Login {user}, {servername}, remoteAgentId {remoteAgentId}, version {version}", User, remoteSettings.AppSettings.User, remoteSettings.AppSettings.Name, remoteSettings.Runtime.Version);

                    var user = await _operations.RepositoryManager.GetUserFromLoginAsync(remoteSettings.AppSettings.User, cancellationToken);

                    if (user == null)
                    {
                        _logger.LogWarning(LoggingEvents.RemoteLogin, "Login - Invalid remote login attempt using Email: " + User);
                        return(Json(new { Success = false, Message = "Invalid login attempt." }));
                    }

                    if (remoteSettings.Runtime.Version.Substring(0, 7) != "1.0-rc.")
                    {
                        _logger.LogWarning(LoggingEvents.RemoteLogin, "Login - Invalid remote login attempt incorrect version: " + remoteSettings.Runtime.Version + " from login: "******"The remote agent version number is not compatible with the current integration hub web site.  Please update." }));
                    }

                    var remoteIp = GetRequestIP(true);
                    if (remoteIp == "::1")
                    {
                        remoteIp = "127.0.0.1";
                    }

                    _logger.LogInformation(LoggingEvents.RemoteLogin, "Login - Remote Agent Login {user}, {servername}, remoteAgentId {remoteAgentId}, version {version}, ipAddress {ipAddress}", User, remoteSettings.AppSettings.User, remoteSettings.AppSettings.Name, remoteSettings.Runtime.Version, remoteIp);

                    var dbRemoteAgent = await _operations.RepositoryManager.RemoteAgentLogin(remoteIp, remoteSettings.AppSettings.RemoteAgentId, cancellationToken);

                    bool authenticated;
                    if (!string.IsNullOrEmpty(remoteSettings.AppSettings.UserToken))
                    {
                        if (dbRemoteAgent == null)
                        {
                            return(Json(new { Success = false, Message = $"The specified remoteAgentId does not exist, cannot be used from this ip address ({remoteIp}) or has been revoked." }));
                        }

                        authenticated = await _operations.RepositoryManager.VerifyUserTokenAsync(user, remoteSettings.AppSettings.RemoteAgentId, remoteSettings.AppSettings.UserToken, cancellationToken);

                        if (!authenticated)
                        {
                            return(Json(new { Success = false, Message = "The authentication token provided is invalid." }));
                        }

                        // validate the login token.
                        var storedUserToken = dbRemoteAgent.HashedToken;
                        var passed          = SecureHash.ValidateHash(remoteSettings.AppSettings.UserToken, storedUserToken);

                        if (!passed)
                        {
                            return(Json(new { Success = false, Message = "The UserToken/RemoteID did not match the current value for this user.  Please generate a new token." }));
                        }
                    }
                    else if (!string.IsNullOrEmpty(remoteSettings.Runtime.Password))
                    {
                        var result = await _signInManager.PasswordSignInAsync(user, remoteSettings.Runtime.Password, false, lockoutOnFailure : false);

                        authenticated = result.Succeeded;
                        remoteSettings.Runtime.GenerateUserToken = true;
                    }
                    else
                    {
                        return(Json(new { Success = false, Message = "There was no password or authentication token provided." }));
                    }

                    var newUserToken = "";

                    if (authenticated && remoteSettings.Runtime.GenerateUserToken)
                    {
                        if (string.IsNullOrEmpty(remoteSettings.Runtime.Password))
                        {
                            return(Json(new { Success = false, Message = "To generate a new user token, a password must be specified." }));
                        }

                        if (dbRemoteAgent == null)
                        {
                            dbRemoteAgent = new DexihRemoteAgent()
                            {
                                UserId        = user.Id,
                                RestrictIp    = true,
                                IpAddresses   = new [] { remoteIp },
                                Name          = remoteSettings.AppSettings.Name,
                                RemoteAgentId = remoteSettings.AppSettings.RemoteAgentId,
                            };
                        }
                        else
                        {
                            if (dbRemoteAgent.UserId != user.Id)
                            {
                                return(Json(new { Success = false, Message = "The remote agent can not be updated as it is registered with a different user id." }));
                            }

                            dbRemoteAgent.Name = remoteSettings.AppSettings.Name;

                            if (dbRemoteAgent.RestrictIp && !(dbRemoteAgent.IpAddresses != null && dbRemoteAgent.IpAddresses.Contains(remoteIp)))
                            {
                                if (dbRemoteAgent.IpAddresses == null)
                                {
                                    dbRemoteAgent.IpAddresses = new [] { remoteIp };
                                }
                                else
                                {
                                    dbRemoteAgent.IpAddresses = dbRemoteAgent.IpAddresses.Append(remoteIp).ToArray();
                                }
                            }
                        }

                        newUserToken = await _operations.RepositoryManager.GenerateRemoteUserTokenAsync(user, remoteSettings.AppSettings.RemoteAgentId, cancellationToken);

                        // hash the token so that it's not stored in plain text.
                        var hashedToken = SecureHash.CreateHash(newUserToken);

                        dbRemoteAgent.HashedToken = hashedToken;

                        dbRemoteAgent = await _operations.RepositoryManager.SaveRemoteAgent(user.Id, dbRemoteAgent, cancellationToken);
                    }

                    if (authenticated)
                    {
                        if (dbRemoteAgent == null)
                        {
                            return(Json(new { Success = false, Message = $"There is no remote agent registered with the id {remoteSettings.AppSettings.RemoteAgentId} ." }));
                        }

                        if (dbRemoteAgent.UserId != user.Id)
                        {
                            return(Json(new { Success = false, Message = $"There user {user.Email} is not associated with this remote agent {remoteSettings.AppSettings.RemoteAgentId} ." }));
                        }

                        if (dbRemoteAgent.RestrictIp && !(dbRemoteAgent.IpAddresses != null && dbRemoteAgent.IpAddresses.Contains(remoteIp)))
                        {
                            return(Json(new { Success = false, Message = $"The remote agent has restrictions on the IP, and the IP address {remoteIp} is not allowed.." }));
                        }

                        if (dbRemoteAgent.Name != remoteSettings.AppSettings.Name)
                        {
                            dbRemoteAgent.Name = remoteSettings.AppSettings.Name;
                            await _operations.RepositoryManager.SaveRemoteAgent(dbRemoteAgent.UserId, dbRemoteAgent, cancellationToken);
                        }

                        await _signInManager.RefreshSignInAsync(user);

                        // create a hash of the userid, which is used as part of the dynamic url.
                        var userHash = user.Id.CreateSHA1();

                        // create a security key, which is not sent the the browser client, and used to ensure the instance id hasn't been hijacked by another remote agent.
                        var(instanceId, securityToken) = await _remoteServers.AuthorizeRemoteAgent(remoteSettings.AppSettings.Name, dbRemoteAgent.RemoteAgentKey, remoteSettings.AppSettings.EncryptionKey, remoteIp, user.Id, cancellationToken);

                        return(Json(new {
                            Success = true,
                            instanceId,
                            securityToken,
                            UserToken = newUserToken,
                            IpAddress = remoteIp,
                            Message = "Login success",
                            UserHash = userHash,
                            _operations.Config.DefaultProxyUrl,
                            dbRemoteAgent.RemoteAgentKey
                        }));
                    }
                    else
                    {
                        return(Json(new { Success = false, Message = "Invalid password or revoked security token." }));
                    }
                }

                // If we got this far, something failed, redisplay form
                return(Json(new { Success = false, Message = "Login failed." }));
            }
            catch (Exception ex)
            {
                return(Json(new ReturnValue(false, "An unexpected error occurred logging in: message: " + ex.Message, ex)));
            }
        }