Пример #1
0
        /// <inheritdoc />
        public override async Task <IFtpResponse> Process(FtpCommand command, CancellationToken cancellationToken)
        {
            // Reset the login
            var loginStateMachine = Connection.ConnectionServices.GetRequiredService <IFtpLoginStateMachine>();

            loginStateMachine.Reset();

            // Remember old features
            var fileSystemFeature       = Connection.Features.Get <IFileSystemFeature>();
            var connectionFeature       = Connection.Features.Get <IConnectionFeature>();
            var secureConnectionFeature = Connection.Features.Get <ISecureConnectionFeature>();

            // Reset to empty file system
            fileSystemFeature.FileSystem = new EmptyUnixFileSystem();
            fileSystemFeature.Path.Clear();

            // Remove the control connection encryption
            await secureConnectionFeature.CloseEncryptedControlStream(cancellationToken)
            .ConfigureAwait(false);

            // Dispose and remove all features (if disposable)
            var setFeatureMethod = Connection.Features.GetType().GetTypeInfo().GetDeclaredMethod("Set");

            foreach (var featureItem in Connection.Features)
            {
                if (!(featureItem.Value is IDisposable disposableFeature))
                {
                    continue;
                }

                try
                {
                    disposableFeature.Dispose();
                }
                catch (Exception ex)
                {
                    // Ignore exceptions
                    _logger?.LogWarning(
                        ex,
                        "Failed to feature of type {featureType}: {errorMessage}",
                        featureItem.Key,
                        ex.Message);
                }

                // Remove from features collection
                var setMethod = setFeatureMethod.MakeGenericMethod(featureItem.Key);
                setMethod.Invoke(Connection.Features, new object[] { null });
            }

            // Set the default FTP data connection feature
            var activeDataConnectionFeatureFactory = Connection.ConnectionServices.GetRequiredService <ActiveDataConnectionFeatureFactory>();
            var dataConnectionFeature = await activeDataConnectionFeatureFactory.CreateFeatureAsync(null, connectionFeature.RemoteAddress, _dataPort)
                                        .ConfigureAwait(false);

            Connection.Features.Set(dataConnectionFeature);

            return(new FtpResponseTextBlock(220, _serverMessages.GetBannerMessage()));
        }
Пример #2
0
        /// <inheritdoc />
        public override async Task <IFtpResponse?> Process(FtpCommand command, CancellationToken cancellationToken)
        {
            // User-Logout
            var authorizationInformationFeature = Connection.Features.Get <IAuthorizationInformationFeature>();
            var user = authorizationInformationFeature.FtpUser;
            var membershipProvider = authorizationInformationFeature.MembershipProvider;

            if (user != null && membershipProvider is IMembershipProviderAsync membershipProviderAsync)
            {
                await membershipProviderAsync.LogOutAsync(user, cancellationToken);
            }

            // Reset the login
            var loginStateMachine = Connection.ConnectionServices.GetRequiredService <IFtpLoginStateMachine>();

            loginStateMachine.Reset();

            // Reset encoding
            var encodingFeature = Connection.Features.Get <IEncodingFeature>();

            encodingFeature.Reset();

            // Remember old features
            var fileSystemFeature       = Connection.Features.Get <IFileSystemFeature>();
            var connectionFeature       = Connection.Features.Get <IConnectionFeature>();
            var secureConnectionFeature = Connection.Features.Get <ISecureConnectionFeature>();

            // Reset to empty file system
            fileSystemFeature.FileSystem = new EmptyUnixFileSystem();
            fileSystemFeature.Path.Clear();

            // Remove the control connection encryption
            await secureConnectionFeature.CloseEncryptedControlStream(cancellationToken)
            .ConfigureAwait(false);

            // Dispose and remove all features (if disposable)
            foreach (var featureItem in Connection.Features)
            {
                try
                {
                    switch (featureItem.Value)
                    {
                    case IFtpConnection _:
                        // Never dispose the connection itself.
                        break;

                    case IFtpDataConnectionFeature f:
                        await f.DisposeAsync().ConfigureAwait(false);

                        break;

                    case IDisposable disposable:
                        disposable.Dispose();
                        break;
                    }
                }
                catch (Exception ex)
                {
                    // Ignore exceptions
                    _logger?.LogWarning(
                        ex,
                        "Failed to dispose feature of type {FeatureType}: {ErrorMessage}",
                        featureItem.Key,
                        ex.Message);
                }

                // Remove from features collection
                Connection.Features[featureItem.Key] = null;
            }

            // Reset the FTP data connection configuration feature
            Connection.Features.Set <IFtpDataConnectionConfigurationFeature>(new FtpDataConnectionConfigurationFeature());

            // Set the default FTP data connection feature
            var activeDataConnectionFeatureFactory = Connection.ConnectionServices.GetRequiredService <ActiveDataConnectionFeatureFactory>();
            var dataConnectionFeature = await activeDataConnectionFeatureFactory.CreateFeatureAsync(null, connectionFeature.RemoteEndPoint, _dataPort)
                                        .ConfigureAwait(false);

            Connection.Features.Set(dataConnectionFeature);

            return(new FtpResponseTextBlock(220, _serverMessages.GetBannerMessage()));
        }