How to Use Managed Code (C#) to Create an FTP Home Directory Provider for the Days of the Week

I had a question from someone that had an interesting scenario: they had a series of reports that their manufacturing company generates on a daily basis, and they wanted to automate uploading those files over FTP from their factory to their headquarters. Their existing automation created report files with names like Widgets.log, Sprockets.log, Gadgets.log, etc.

But they had an additional request: they wanted the reports dropped into folders based on the day of the week. People in their headquarters could retrieve the reports from a share on their headquarters network where the FTP server would drop the files, and anyone could look at data from anytime within the past seven days.

This seemed like an extremely trivial script for me to write, so I threw together the following example batch file for them:

@echo off
pushd "C:\Reports"
for /f "usebackq delims= " %%a in (`date /t`) do (
  echo open MyServerName>ftpscript.txt
  echo MyUsername>>ftpscript.txt
  echo MyPassword>>ftpscript.txt
  echo mkdir %%a>>ftpscript.txt
  echo cd %%a>>ftpscript.txt
  echo asc>>ftpscript.txt
  echo prompt>>ftpscript.txt
  echo mput *.log>>ftpscript.txt
  echo bye>>ftpscript.txt
)
ftp.exe -s:ftpscript.txt
del ftpscript.txt
popd

This would have worked great for most scenarios, but they pointed out a few problems in their specific environment: manufacturing and headquarters were in different geographical regions of the world, therefore in different time zones, and they wanted the day of the week to be based on the day of the week where their headquarters was located. They also wanted to make sure that if anyone logged in over FTP, they would only see the reports for the current day, and they didn't want to take a chance that something might go wrong with the batch file and they might overwrite the logs from the wrong day.

With all of those requirements in mind, this was beginning to look like a problem for a custom home directory provider to tackle. Fortunately, this was a really easy home directory provider to write, and I thought that it might make a good blog.

Note: I wrote and tested the steps in this blog using both Visual Studio 2010 and Visual Studio 2008; if you use an different version of Visual Studio, some of the version-specific steps may need to be changed.

In This Blog

Prerequisites

The following items are required to complete the procedures in this blog:

  1. The following version of IIS must be installed on your Windows computer, and the Internet Information Services (IIS) Manager must also be installed:
    • IIS 7.0 must be installed on Windows Server 2008
    • IIS 7.5 must be installed on Windows Server 2008 R2 or Windows 7
  2. The new FTP 7.5 service must be installed. To install FTP 7.5, follow the instructions in the following topic:
  3. You must have FTP publishing enabled for a site. To create a new FTP site, follow the instructions in the following topic:
  4. You need to create the folders for the days of the week under your FTP root directory; for example, Sunday, Monday, Tuesday, etc.

Step 1: Set up the Project Environment

In this step, you will create a project in Microsoft Visual Studio for the demo provider.

  1. Open Visual Studio 2008 or Visual Studio 2010.
  2. Click the File menu, then New, then Project.
  3. In the New Projectdialog box:
    • Choose Visual C# as the project type.
    • Choose Class Library as the template.
    • Type FtpDayOfWeekHomeDirectory as the name of the project.
    • Click OK.
  4. When the project opens, add a reference path to the FTP extensibility library:
    • Click Project, and then click FtpDayOfWeekHomeDirectory Properties.
    • Click the Reference Paths tab.
    • Enter the path to the FTP extensibility assembly for your version of Windows, where C: is your operating system drive.
      • For Windows Server 2008 and Windows Vista:
        • C:\Windows\assembly\GAC_MSIL\Microsoft.Web.FtpServer\7.5.0.0__31bf3856ad364e35
      • For 32-bit Windows 7 and Windows Server 2008 R2:
        • C:\Program Files\Reference Assemblies\Microsoft\IIS
      • For 64-bit Windows 7 and Windows Server 2008 R2:
        • C:\Program Files (x86)\Reference Assemblies\Microsoft\IIS
    • Click Add Folder.
  5. Add a strong name key to the project:
    • Click Project, and then click FtpDayOfWeekHomeDirectory Properties.
    • Click the Signing tab.
    • Check the Sign the assembly check box.
    • Choose <New...> from the strong key name drop-down box.
    • Enter FtpDayOfWeekHomeDirectoryKey for the key file name.
    • If desired, enter a password for the key file; otherwise, clear the Protect my key file with a password check box.
    • Click OK.
  6. Note: FTP 7.5 Extensibility does not support the .NET Framework 4.0; if you are using Visual Studio 2010, or you have changed your default framework version, you may need to change the framework version for this project. To do so, use the following steps:
    • Click Project, and then click FtpDayOfWeekHomeDirectory Properties.
    • Click the Application tab.
    • Choose .NET Framework 3.5 in the Target framework drop-down menu.
    • Save, close, and re-open the project.
  7. Optional: You can add a custom build event to add the DLL automatically to the Global Assembly Cache (GAC) on your development computer:
    • Click Project, and then click FtpDayOfWeekHomeDirectory Properties.
    • Click the Build Events tab.
    • Enter the appropriate commands in the Post-build event command linedialog box, depending on your version of Visual Studio:
      • If you are using Visual Studio 2010:
        net stop ftpsvc
        call "%VS100COMNTOOLS%\vsvars32.bat">null
        gacutil.exe /if "$(TargetPath)"
        net start ftpsvc
      • If you are using Visual Studio 2008:
        net stop ftpsvc
        call "%VS90COMNTOOLS%\vsvars32.bat">null
        gacutil.exe /if "$(TargetPath)"
        net start ftpsvc
      Note: You need to be logged in as an administrator in order to restart the FTP service and add the dll to the Global Assembly Cache.
  8. Save the project.

Step 2: Create the Extensibility Class

In this step, you will implement the extensibility interfaces for the demo provider.

  1. Add the necessary references to the project:
    • Click Project, and then click Add Reference...
    • On the .NET tab, click Microsoft.Web.FtpServer.
    • Click OK.
  2. Add the code for the authentication class:
    • In Solution Explorer, double-click the Class1.cs file.
    • Remove the existing code.
    • Paste the following code into the editor:
      using System;
      using System.Collections.Generic;
      using System.Collections.Specialized;
      using Microsoft.Web.FtpServer;
      
      public class FtpDayOfWeekHomeDirectory :
          BaseProvider,
          IFtpHomeDirectoryProvider
      {
          // Store the path to the default FTP folder.
          private static string _defaultDirectory = string.Empty;
      
          // Override the default initialization method.
          protected override void Initialize(StringDictionary config)
          {
              // Retrieve the default directory path from configuration.
              _defaultDirectory = config["defaultDirectory"];
              // Test for the default home directory (Required).
              if (string.IsNullOrEmpty(_defaultDirectory))
              {
                  throw new ArgumentException(
                    "Missing default directory path in configuration.");
              }
          }
      
          // Define the home directory provider method.
          string IFtpHomeDirectoryProvider.GetUserHomeDirectoryData(
              string sessionId,
              string siteName,
              string userName)
          {
              // Return the path to the folder for the day of the week.
              return String.Format(
                  @"{0}\{1}",
                  _defaultDirectory,
                  DateTime.Today.DayOfWeek);
          }
      }
  3. Save and compile the project.

Note: If you did not use the optional steps to register the assemblies in the GAC, you will need to manually copy the assemblies to your IIS 7 computer and add the assemblies to the GAC using the Gacutil.exe tool. For more information, see the following topic on the Microsoft MSDN Web site:

Global Assembly Cache Tool (Gacutil.exe)

Step 3: Add the Demo Provider to FTP

In this step, you will add your provider to the global list of custom providers for your FTP service, configure your provider's settings, and enable your provider for an FTP site.

Adding your Provider to FTP

  1. Determine the assembly information for your extensibility provider:
    • In Windows Explorer, open your "C:\Windows\assembly" path, where C: is your operating system drive.
    • Locate the FtpDayOfWeekHomeDirectory assembly.
    • Right-click the assembly, and then click Properties.
    • Copy the Culture value; for example: Neutral.
    • Copy the Version number; for example: 1.0.0.0.
    • Copy the Public Key Token value; for example: 426f62526f636b73.
    • Click Cancel.
  2. Add the extensibility provider to the global list of FTP authentication providers:
    • Open the Internet Information Services (IIS) Manager.
    • Click your computer name in the Connections pane.
    • Double-click FTP Authentication in the main window.
    • Click Custom Providers... in the Actions pane.
    • Click Register.
    • Enter FtpDayOfWeekHomeDirectory for the provider Name.
    • Click Managed Provider (.NET).
    • Enter the assembly information for the extensibility provider using the information that you copied earlier. For example:
      FtpDayOfWeekHomeDirectory,FtpDayOfWeekHomeDirectory,version=1.0.0.0,Culture=neutral,PublicKeyToken=426f62526f636b73
    • Click OK.
    • Clear the FtpDayOfWeekHomeDirectory check box in the providers list.
    • Click OK.

Note: If you prefer, you could use the command line to add the provider to FTP by using syntax like the following example:

cd %SystemRoot%\System32\Inetsrv

appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"[name='FtpDayOfWeekHomeDirectory',type='FtpDayOfWeekHomeDirectory,FtpDayOfWeekHomeDirectory,version=1.0.0.0,Culture=neutral,PublicKeyToken=426f62526f636b73']" /commit:apphost

Configuring your Provider's Settings

At the moment there is no user interface that allows you to configure properties for a custom home directory provider, so you will have to use the following command line:

cd %SystemRoot%\System32\Inetsrv

appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpDayOfWeekHomeDirectory']" /commit:apphost

appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpDayOfWeekHomeDirectory'].[key='defaultDirectory',value='C:\Inetpub\ftproot']" /commit:apphost

Note: The highlighted area contains the value that you need to update with the root directory of your FTP site.

Enabling your Provider for an FTP site

At the moment there is no user interface that allows you to enable a custom home directory provider for an FTP site, so you will have to use the following command line:

cd %SystemRoot%\System32\Inetsrv

appcmd.exe set config -section:system.applicationHost/sites /+"[name='My FTP Site'].ftpServer.customFeatures.providers.[name='FtpDayOfWeekHomeDirectory']" /commit:apphost

appcmd.exe set config -section:system.applicationHost/sites /"[name='My FTP Site'].ftpServer.userIsolation.mode:Custom" /commit:apphost

Note: The highlighted areas contain the name of the FTP site where you want to enable the custom home directory provider.

Summary

In this blog I showed you how to:

  • Create a project in Visual Studio 2010 or Visual Studio 2008 for a custom FTP home directory provider.
  • Implement the extensibility interface for custom FTP home directories.
  • Add a custom home directory provider to your FTP service.

When users connect to your FTP site, the FTP service will drop their session in the corresponding folder for the day of the week under the home directory for your FTP site, and they will not be able to change to the root directory or a directory for a different day of the week.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FTP and LDAP - Part 2: How to Set Up an Active Directory Lightweight Directory Services (AD LDS) Server

This blog is designed as a complement to my FTP and LDAP - Part 1: How to Use Managed Code (C#) to Create an FTP Authentication Provider that uses an LDAP Server blog post. In this second blog, I'll walk you through the steps to set up an Active Directory Lightweight Directory Services (AD LDS) server, which you can use with the custom FTP LDAP Authentication provider that I discussed in my last blog.

In This Blog

Step 1: Installing AD LDS

The following steps will walk you through installing Active Directory Lightweight Directory Services on a computer that is running Windows Server 2008.

Adding the AD LDS Role

  1. Open the Windows Server 2008 Server Manager, click Roles in the navigation pane, and then click Add Roles.
  2. Check the box for Active Directory Lightweight Directory Services, and then click Next.
  3. Read the information on the Introduction to Active Directory Lightweight Directory Services page, and then click Next.
  4. Verify the Confirmation Installation Settings, and then click Next.
  5. The installation will start; this may take several minutes to complete.
  6. When the installation has completed, click Close.

Creating an AD LDS instance

Note: Before completing these steps I created a local user account named "LdapAdmin" that I would specify the administrative account for managing my LDAP instance. This user account was only a member of the local "Users" group, and not a member of the local "Administrators" group.

  1. Click Start, then click Administrative Tools, and then click Active Directory Lightweight Directory Services Setup Wizard.
  2. When the Active Directory Lightweight Directory Services Setup Wizard appears, click Next.
  3. Select A unique instance, and then click Next.
  4. Enter a name for your instance, for example "MyTestInstance," and then click Next.
  5. Verify the port numbers for LDAP connections, and then click Next.
  6. Choose Yes, create an application directory partition, and then enter a unique partition name by using X.500 path syntax. For example: "CN=MyServer,DC=MyDomain,DC=local". When you have finished entering your partition name, click Next.
  7. Verify the paths to the AD LDS files for this instance, and then click Next.
  8. Choose an account for your service account. (Note: Because I was creating a standalone LDAP server, I chose to use the network service account.) Once you have chosen an account, click Next.
  9. If you choose to use the network service account, the AD LDS wizard will prompt you about replication. Click Yes to continue.
  10. Choose an account as your AD LDS administrator. (Note: In my situation I chose the LdapAdmin account that I had created earlier; I did this so that I wouldn't be storing the credentials for an administrative account.) Once you have chosen an account, click Next.
  11. Choose one of the following LDIF files to import; these will be used to create user accounts.
    • MS-User.LDF
    • MS-InetOrgPerson.LDF
    Note: I tested my FTP LDAP authentication provider with both LDIF files.
  12. Verify your installation options, and then click Next.
  13. When prompted for your AD LDS credentials, enter the credentials for the account that you chose to administer your AD LDS instance.
  14. The wizard will begin to install the requisite files and create your instance; this may take several minutes to complete.

  15. When the wizard has completed, click Finish.

Step 2: Using ADSI Edit to add Users and Groups

Connecting to your AD LDS Server

  1. Click Start, and then Administrative Tools, and then ADSI Edit.
  2. Click Action, and then click Connect to...
  3. When the Connection Settingsdialog box is displayed:
    • Enter the LDAP path for your AD LDS server in the Select or type a Distinguished Name or Naming Contexttext box. For example:
      • CN=MyServer,DC=MyDomain,DC=local
    • Enter the server name and port in the Select or type a domain or servertext box. For example:
      • MYSERVER:389
    • The preceding steps should create the following path in the Pathtext box:
      • LDAP://MYSERVER:389/CN=MyServer,DC=MyDomain,DC=local
       
    • Click the Advanced button; when the Advanceddialog box is displayed:
      • Check the Specify Credentials box.
      • Enter the user name and password for your AD LDS server.
      • Click OK.
  4. Click OK.

Adding a User Object

  1. Expand the tree until you have highlighted the correct LDAP path for your server. For example:
    • CN=MyServer,DC=MyDomain,DC=local.
  2. Click Action, and then New, and then Object...
  3. Highlight the appropriate user class, and then click Next.
  4. Enter the common name for your user, and then click Next. For example: enter FtpUser for the common name.
  5. Click Finish.
  6. Right-click the user that you created, and then click Properties.
  7. Select msDS-UserAccountDisabled in the list of attributes, and then click Edit.
  8. Select False, and then click OK.
  9. Select userPrincipalName in the list of attributes, and then click Edit.
  10. Enter your user's common name for the value, and then click OK. For example: enter FtpUser for the common name.
  11. Click OK to close the user properties dialog box.
  12. Right-click the user that you created, and then click Reset Password...
  13. Enter and confirm the password for your user.
  14. Click OK.

Adding Users to Groups

  1. Retrieve the Distinguished Name (DN) for a user:
    • Right-click the user that you created, and then click Properties.
    • Select distinguishedName in the list of attributes, and then click View.
    • Copy the value, and then click OK. For example: CN=FtpUser,CN=MyServer,DC=MyDomain,DC=local.
    • Click OK to close the user's properties dialog box.
  2. Add the user to a group:
    • Expand the tree until you have highlighted a group in your server. For example, you could use the built-in CN-Users group.
    • Right-click the group, and then click Properties.
    • Select member in the list of attributes, and then click Edit.
    • When the editor dialog box is displayed, click Add DN...
    • When the Add Distinguished Name (DN) dialog box appears, paste the user DN syntax that you copied earlier. For example: CN=FtpUser,CN=MyServer,DC=MyDomain,DC=local.
    • Click OK to close the Add DN dialog box.
    • Click OK to close the group's properties dialog box.

More Information

For additional information about working with AD LDS instances, see the following URLs:

Enabling the Custom FTP LDAP Authentication Provider for an FTP site

While this is technically outside the scope of setting up the LDAP server, I'm reposting the notes from my last blog about adding the FTP LDAP Authentication provider and adding authorization rules for FTP users or groups.

  1. Add the custom authentication provider for an FTP site:
    • Open an FTP site in the Internet Information Services (IIS) Manager.
    • Double-click FTP Authentication in the main window.
    • Click Custom Providers... in the Actions pane.
    • Check FtpLdapAuthentication in the providers list.
    • Click OK.
  2. Add an authorization rule for the authentication provider:
    • Double-click FTP Authorization Rules in the main window.
    • Click Add Allow Rule... in the Actions pane.
    • You can add either of the following authorization rules:
      • For a specific user:
        • Select Specified users for the access option.
        • Enter a user name that you created in your AD LDS partition.
      • For a role or group:
        • Select Specified roles or user groups for the access option.
        • Enter the role or group name that you created in your AD LDS partition.
      • Select Read and/or Write for the Permissions option.
    • Click OK.

Once these settings are configured and users connect to your FTP site, the FTP service will attempt to authenticate users from your LDAP server by using the custom FTP LDAP Authentication provider.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FTP and LDAP - Part 1: How to Use Managed Code (C#) to Create an FTP Authentication Provider that uses an LDAP Server

Over the past few years I've created a series of authentication providers for the FTP 7.5 service that ships with Windows Server 2008 R2 and Windows 7, and is available for download for Windows Server 2008. Some of these authentication providers are available on the http://learn.iis.net/page.aspx/590/developing-for-ftp-75/ website, while others have been in my blog posts.

With that in mind, I had a question a little while ago about using an LDAP server to authenticate users for the FTP service, and it seemed like that would make a great subject for another custom FTP authentication provider blog post.

The steps in this blog will lead you through the steps to use managed code to create an FTP authentication provider that uses a server running Active Directory Lightweight Directory Services (AD LDS) that is located on your local network.

Note: I wrote and tested the steps in this blog using both Visual Studio 2010 and Visual Studio 2008; if you use an different version of Visual Studio, some of the version-specific steps may need to be changed.

In This Blog

Prerequisites

The following items are required to complete the procedures in this blog:

  1. The following version of IIS must be installed on your Windows computer, and the Internet Information Services (IIS) Manager must also be installed:
    • IIS 7.0 must be installed on Windows Server 2008
    • IIS 7.5 must be installed on Windows Server 2008 R2 or Windows 7
  2. The new FTP 7.5 service must be installed. To install FTP 7.5, follow the instructions in the following topic:
  3. You must have FTP publishing enabled for a site. To create a new FTP site, follow the instructions in the following topic:
  4. You must have an AD LDS server available on your local network. Note: See my How to Set Up an Active Directory Lightweight Directory Services (AD LDS) Server blog post for more information.

Note: To test this blog, I used AD LDS on Windows Server 2008; if you use a different LDAP server, you may need to change some of the LDAP syntax in the code samples. To get started using AD LDS, see the following topics:

I tested this blog by using the user objects from both the MS-User.LDF and MS-InetOrgPerson.LDF Lightweight Directory interchange Format (LDIF) files.

Important

To help improve the performance for authentication requests, the FTP service caches the credentials for successful logins for 15 minutes by default. This means that if you change the password in your AD LDS server, this change may not be reflected for the cache duration. To alleviate this, you can disable credential caching for the FTP service. To do so, use the following steps:

  1. Open a command prompt.
  2. Type the following commands:
    cd /d "%SystemRoot%\System32\Inetsrv"
    Appcmd.exe set config -section:system.ftpServer/caching /credentialsCache.enabled:"False" /commit:apphost
    Net stop FTPSVC
    Net start FTPSVC
  3. Close the command prompt.

Step 1: Set up the Project Environment

In this step, you will create a project in Visual Studio 2008 for the demo provider.

  1. Open Microsoft Visual Studio 2008.
  2. Click the File menu, then New, then Project.
  3. In the New Projectdialog box:
    • Choose Visual C# as the project type.
    • Choose Class Library as the template.
    • Type FtpLdapAuthentication as the name of the project.
    • Click OK.
  4. When the project opens, add a reference path to the FTP extensibility library:
    • Click Project, and then click FtpLdapAuthentication Properties.
    • Click the Reference Paths tab.
    • Enter the path to the FTP extensibility assembly for your version of Windows, where C: is your operating system drive.
      • For Windows Server 2008 and Windows Vista:
        • C:\Windows\assembly\GAC_MSIL\Microsoft.Web.FtpServer\7.5.0.0__31bf3856ad364e35
      • For 32-bit Windows 7 and Windows Server 2008 R2:
        • C:\Program Files\Reference Assemblies\Microsoft\IIS
      • For 64-bit Windows 7 and Windows Server 2008 R2:
        • C:\Program Files (x86)\Reference Assemblies\Microsoft\IIS
    • Click Add Folder.
  5. Add a strong name key to the project:
    • Click Project, and then click FtpLdapAuthentication Properties.
    • Click the Signing tab.
    • Check the Sign the assembly check box.
    • Choose <New...> from the strong key name drop-down box.
    • Enter FtpLdapAuthenticationKey for the key file name.
    • If desired, enter a password for the key file; otherwise, clear the Protect my key file with a password check box.
    • Click OK.
  6. Note: FTP 7.5 Extensibility does not support the .NET Framework 4.0; if you are using Visual Studio 2010, or you have changed your default framework version, you may need to change the framework version. To do so, use the following steps:
    • Click Project, and then click FtpLdapAuthentication Properties.
    • Click the Application tab.
    • Choose .NET Framework 3.5 in the Target framework drop-down menu.
    • Save, close, and re-open the project.
  7. Optional: You can add a custom build event to add the DLL automatically to the Global Assembly Cache (GAC) on your development computer:
    • Click Project, and then click FtpLdapAuthentication Properties.
    • Click the Build Events tab.
    • Enter the appropriate commands in the Post-build event command linedialog box, depending on your version of Visual Studio:
      • If you are using Visual Studio 2010:
        net stop ftpsvc
        call "%VS100COMNTOOLS%\vsvars32.bat">null
        gacutil.exe /if "$(TargetPath)"
        net start ftpsvc
      • If you are using Visual Studio 2008:
        net stop ftpsvc
        call "%VS90COMNTOOLS%\vsvars32.bat">null
        gacutil.exe /if "$(TargetPath)"
        net start ftpsvc
      Note: You need to be logged in as an administrator in order to restart the service and add the dll to the Global Assembly Cache.
  8. Save the project.

Step 2: Create the Extensibility Class

In this step, you will implement the authentication and role extensibility interfaces for the demo provider.

  1. Add the necessary references to the project:
    • Click Project, and then click Add Reference...
    • On the .NET tab, click Microsoft.Web.FtpServer.
    • Click OK.
    • Repeat the above steps to add the following references to the project:
      • System.Configuration
      • System.DirectoryServices
      • System.DirectoryServices.AccountManagement
  2. Add the code for the authentication class:
    • In Solution Explorer, double-click the Class1.cs file.
    • Remove the existing code.
    • Paste the following code into the editor:
      using System;
      using System.Collections.Specialized;
      using System.Configuration.Provider;
      using System.DirectoryServices;
      using System.DirectoryServices.AccountManagement;
      using Microsoft.Web.FtpServer;
      
      public class FtpLdapAuthentication :
        BaseProvider,
        IFtpAuthenticationProvider,
        IFtpRoleProvider
      {
        private static string _ldapServer = string.Empty;
        private static string _ldapPartition = string.Empty;
        private static string _ldapAdminUsername = string.Empty;
        private static string _ldapAdminPassword = string.Empty;
      
        // Override the default initialization method.
        protected override void Initialize(StringDictionary config)
        {
          // Retrieve the provider settings from configuration.
          _ldapServer = config["ldapServer"];
          _ldapPartition = config["ldapPartition"];
          _ldapAdminUsername = config["ldapAdminUsername"];
          _ldapAdminPassword = config["ldapAdminPassword"];
      
          // Test for the LDAP server name (Required).
          if (string.IsNullOrEmpty(_ldapServer) || string.IsNullOrEmpty(_ldapPartition))
          {
            throw new ArgumentException(
              "Missing LDAP server values in configuration.");
          }
        }
      
        public bool AuthenticateUser(
          string sessionId,
          string siteName,
          string userName,
          string userPassword,
          out string canonicalUserName)
        {
          canonicalUserName = userName;
          // Attempt to look up the user and password.
          return LookupUser(true, userName, string.Empty, userPassword);
        }
      
        public bool IsUserInRole(
          string sessionId,
          string siteName,
          string userName,
          string userRole)
        {
          // Attempt to look up the user and role.
          return LookupUser(false, userName, userRole, string.Empty);
        }
      
        private static bool LookupUser(
          bool isUserLookup,
          string userName,
          string userRole,
          string userPassword)
        {
          PrincipalContext _ldapPrincipalContext = null;
          DirectoryEntry _ldapDirectoryEntry = null;
      
          try
          {
            // Create the context object using the LDAP connection information.
            _ldapPrincipalContext = new PrincipalContext(
              ContextType.ApplicationDirectory,
              _ldapServer,
      
              _ldapPartition,
              ContextOptions.SimpleBind,
              _ldapAdminUsername,
              _ldapAdminPassword);
      
            // Test for LDAP credentials.
            if (string.IsNullOrEmpty(_ldapAdminUsername) || string.IsNullOrEmpty(_ldapAdminPassword))
            {
              // If LDAP credentials do not exist, attempt to create an unauthenticated directory entry object.
              _ldapDirectoryEntry = new DirectoryEntry("LDAP://" + _ldapServer + "/" + _ldapPartition);
            }
            else
            {
              // If LDAP credentials exist, attempt to create an authenticated directory entry object.
              _ldapDirectoryEntry = new DirectoryEntry("LDAP://" + _ldapServer + "/" + _ldapPartition,
                _ldapAdminUsername, _ldapAdminPassword, AuthenticationTypes.Secure);
            }
      
            // Create a DirectorySearcher object from the cached DirectoryEntry object.
            DirectorySearcher userSearcher = new DirectorySearcher(_ldapDirectoryEntry);
            // Specify the the directory searcher to filter by the user name.
            userSearcher.Filter = String.Format("(&(objectClass=user)(cn={0}))", userName);
            // Specify the search scope.
            userSearcher.SearchScope = SearchScope.Subtree;
            // Specify the directory properties to load.
            userSearcher.PropertiesToLoad.Add("distinguishedName");
            // Specify the search timeout.
            userSearcher.ServerTimeLimit = new TimeSpan(0, 1, 0);
            // Retrieve a single search result.
            SearchResult userResult = userSearcher.FindOne();
            // Test if no result was found.
            if (userResult == null)
            {
              // Return false if no matching user was found.
              return false;
            }
            else
            {
              if (isUserLookup == true)
              {
                try
                {
                  // Attempt to validate credentials using the username and password.
                  return _ldapPrincipalContext.ValidateCredentials(userName, userPassword, ContextOptions.SimpleBind);
                }
                catch (Exception ex)
                {
                  // Throw an exception if an error occurs.
                  throw new ProviderException(ex.Message);
                }
              }
              else
              {
                // Retrieve the distinguishedName for the user account.
                string distinguishedName = userResult.Properties["distinguishedName"][0].ToString();
      
                // Create a DirectorySearcher object from the cached DirectoryEntry object.
                DirectorySearcher groupSearcher = new DirectorySearcher(_ldapDirectoryEntry);
                // Specify the the directory searcher to filter by the group/role name.
                groupSearcher.Filter = String.Format("(&(objectClass=group)(cn={0}))", userRole);
                // Specify the search scope.
                groupSearcher.SearchScope = SearchScope.Subtree;
                // Specify the directory properties to load.
                groupSearcher.PropertiesToLoad.Add("member");
                // Specify the search timeout.
                groupSearcher.ServerTimeLimit = new TimeSpan(0, 1, 0);
                // Retrieve a single search result.
                SearchResult groupResult = groupSearcher.FindOne();
      
                // Loop through the member collection.
                for (int i = 0; i < groupResult.Properties["member"].Count; ++i)
                {
                  string member = groupResult.Properties["member"][i].ToString();
                  // Test if the current member contains the user's distinguished name.
                  if (member.IndexOf(distinguishedName, StringComparison.OrdinalIgnoreCase) > -1)
                  {
                    // Return true (role lookup succeeded) if the user is found.
                    return true;
                  }
                }
                // Return false (role lookup failed) if the user is not found for the role.
                return false;
              }
            }
          }
          catch (Exception ex)
          {
            // Throw an exception if an error occurs.
            throw new ProviderException(ex.Message);
          }
        }
      }
  3. Save and compile the project.

Note: If you did not use the optional steps to register the assemblies in the GAC, you will need to manually copy the assemblies to your IIS 7 computer and add the assemblies to the GAC using the Gacutil.exe tool. For more information, see the following topic on the Microsoft MSDN Web site:

Global Assembly Cache Tool (Gacutil.exe)

Step 3: Add the Demo Provider to FTP

In this step, you will add your provider to the list of providers for your FTP service, configure your provider for your LDAP server, and enable your provider to authenticate users for an FTP site.

Adding your Provider to FTP

  1. Determine the assembly information for your extensibility provider:
    • In Windows Explorer, open your "C:\Windows\assembly" path, where C: is your operating system drive.
    • Locate the FtpLdapAuthentication assembly.
    • Right-click the assembly, and then click Properties.
    • Copy the Culture value; for example: Neutral.
    • Copy the Version number; for example: 1.0.0.0.
    • Copy the Public Key Token value; for example: 426f62526f636b73.
    • Click Cancel.
  2. Add the extensibility provider to the global list of FTP authentication providers:
    • Open the Internet Information Services (IIS) Manager.
    • Click your computer name in the Connections pane.
    • Double-click FTP Authentication in the main window.
    • Click Custom Providers... in the Actions pane.
    • Click Register.
    • Enter FtpLdapAuthentication for the provider Name.
    • Click Managed Provider (.NET).
    • Enter the assembly information for the extensibility provider using the information that you copied earlier. For example:
      FtpLdapAuthentication,FtpLdapAuthentication,version=1.0.0.0,Culture=neutral,PublicKeyToken=426f62526f636b73
    • Click OK.
    • Clear the FtpLdapAuthentication check box in the providers list.
    • Click OK.

Configuring your Provider's Settings

  1. Determine the connection information for your LDAP server; there are four pieces of information that you will need to know in order to configure the extensibility provider to talk to your LDAP server:
    • Server Name and TCP/IP Port: This is the name (or IP address) of the server that is hosting your LDAP service; the port is usually 389. These will be added to your provider using the "SERVERNAME:PORT" syntax.
    • LDAP Partition: This is the LDAP path within your LDAP service to your data, for example: "CN=ServerName,DC=DomainName,DC=DomainExtension."
    • LDAP Username: This is a username that has access to your LDAP server; this is not the name of an account that you will use for FTP access, and it does not have to be a Windows account.
    • LDAP Password: This is the password that is associated with the LDAP username.
  2. Using the information from the previous steps, configure the options for the provider:
    • At the moment there is no user interface that enables you to add properties for a custom authentication module, so you will have to use the following command line. You will need to update the highlighted areas with the information from the previous steps and the information for your LDAP server:
      cd %SystemRoot%\System32\Inetsrv

      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpLdapAuthentication']" /commit:apphost

      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpLdapAuthentication'].[key='ldapServer',value='MYSERVER:389']" /commit:apphost

      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpLdapAuthentication'].[key='ldapPartition',value='CN=MyServer,DC=MyDomain,DC=local']" /commit:apphost

      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpLdapAuthentication'].[key='ldapAdminUsername',encryptedValue='MyAdmin']" /commit:apphost

      appcmd.exe set config -section:system.ftpServer/providerDefinitions /+"activation.[name='FtpLdapAuthentication'].[key='ldapAdminPassword',encryptedValue='MyPassword1']" /commit:apphost
    • Note: The highlighted areas are the values for the ldapServer, ldapPartition, ldapAdminUsername, and ldapAdminPassword settings, which configure your network environment for your LDAP server.

Enabling your Provider for an FTP site

  1. Add the custom authentication provider for an FTP site:
    • Open an FTP site in the Internet Information Services (IIS) Manager.
    • Double-click FTP Authentication in the main window.
    • Click Custom Providers... in the Actions pane.
    • Check FtpLdapAuthentication in the providers list.
    • Click OK.
  2. Add an authorization rule for the authentication provider:
    • Double-click FTP Authorization Rules in the main window.
    • Click Add Allow Rule... in the Actions pane.
    • You can add either of the following authorization rules:
      • For a specific user:
        • Select Specified users for the access option.
        • Enter a user name that you created in your AD LDS partition.
      • For a role or group:
        • Select Specified roles or user groups for the access option.
        • Enter the role or group name that you created in your AD LDS partition.
      • Select Read and/or Write for the Permissions option.
    • Click OK.

Summary

In this blog I showed you how to:

  • Create a project in Visual Studio 2010 or Visual Studio 2008 for a custom FTP authentication provider.
  • Implement the extensibility interface for custom FTP authentication.
  • Add a custom authentication provider to your FTP service.

When users connect to your FTP site, the FTP service will attempt to authenticate users from your LDAP server by using your custom authentication provider.

Additional Information

The PrincipalContext.ValidateCredentials() method will validate the user name in the userName parameter with the value of the userPrincipalName attribute of the user object in AD LDS. Because of this, the userPrincipalName attribute for a user object is expected to match the name of the user account that an FTP client will use to log in, which will should be the same value as the cn attribute for the user object. Therefore, when you create a user object in AD LDS, you will need to set the corresponding userPrincipalName attribute for the user object. In addition, when you create a user object in AD LDS, the msDS-UserAccountDisabled attribute is set to TRUE by default, so you will need to change the value of that attribute to FALSE before you attempt to log in.

For more information, see my follow-up blog that is titled FTP and LDAP - Part 2: How to Set Up an Active Directory Lightweight Directory Services (AD LDS) Server.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

Happy 40th Birthday FTP!

Following on the heels of Clive Webster's article that FTP is 40 years old, let me be the next person to wish FTP a wonderful 40th birthday!

Happy Birthday FTP!

Yeah, that was kind of silly, wasn't it...? ;-]

Credential Caching in FTP 7.0 and FTP 7.5

I've seen a few situations where people that are using the FTP 7.0 and FTP 7.5 service have noticed that it takes a while for their password changes to be reflected by the FTP service. To put this another way, here are the typical symptoms that people describe to me:

  • A user successfully logs into their FTP site using their username and password
  • The user logs out of their FTP site
  • The user changes their password
  • The user attempts to log into their FTP site using their username and their new password, but this fails
  • The user can successfully log into their FTP site using their username and their old password
  • (Note: As a corollary, restarting the FTP service fixes the symptoms)

Here's why this happens: to help improve the performance for authentication requests, the FTP service caches the credentials for successful logins. (The cache duration is set to 15 minutes by default.) This means that if you change your password, your changes may not be reflected for the cache duration.

The good news is, the FTP credential cache settings can be changed easily, and I have documented all of the settings for FTP caching in the IIS configuration reference at the following URLs:

Quoting and paraphrasing the above documentation, there are the two settings that you can configure on the <credentialsCache> element:

AttributeDescription
enabled Optional Boolean attribute.

true if credential caching is enabled; otherwise, false.

The default value is true.
flushInterval Optional uint attribute.

Specifies the cache lifetime, in seconds, for credentials that are stored in the cache.

Note: This value must be between 5 and 604,800 seconds.

The default value is 900.

What this means to you is - you can completely disable credential caching, or you can specify a different timeout. For example, on several of my development servers I often disable credential caching; this allows me to change passwords whenever I want, which is very useful when I am creating custom authentication providers. For my production servers I tend to stick with the default values, although I might change those values when I'm troubleshooting a problem.

I usually configure the settings from a command line or a batch file, although the articles that I listed earlier have steps for using the IIS Manager to change the settings for FTP credential caching. Just the same, here are some examples for setting the values by using appcmd.exe:

How to Disable FTP Credential Caching

cd /d "%SystemRoot%\System32\Inetsrv"
appcmd.exe set config -section:system.ftpServer/caching /credentialsCache.enabled:"False" /commit:apphost
net stop FTPSVC
net start FTPSVC

How to Specify a Custom Timeout for FTP Credential Caching

cd /d "%SystemRoot%\System32\Inetsrv"
appcmd.exe set config -section:system.ftpServer/caching /credentialsCache.enabled:"True" /commit:apphost
appcmd.exe set config -section:system.ftpServer/caching /credentialsCache.flushInterval:"300" /commit:apphost
net stop FTPSVC
net start FTPSVC

I hope this helps. ;-]


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FTP Clients - Part 9: Expression Web 4

For this installment in my series about FTP Clients I'm going to review the FTP features in Microsoft's Expression Web 4 (EW4). You can find out more about the Microsoft Expression series of products from the following URL:

http://www.microsoft.com/expression/

Note: There are a lot of really cool features that are built into EW4, like Search Engine Optimization (SEO) tools, rich extensibility APIs, previewing content side-by-side in multiple browser windows through SuperPreview, built-in support for programming languages like ASP/ASP.NET/PHP/etc. But that being said, in keeping with the main theme of my FTP client series, this review is focusing on just the FTP aspects of EW4 - not the entire product.

EW4 Splash Screen

At the time of this blog post, EW4 is a for-retail product that is available as part of the Expression Studio 4 Web Professional and Expression Studio 4 Ultimate suites.

Expression Web 4 Overview

The EW4 user interface follows the same design paradigm as earlier versions of Expression Web, albeit with the darker color scheme that Expression products have been using in recent versions. While EW4 contains many features that you would expect in a Microsoft Office application, it does not resemble the Office 2007/2010 user interface, so there is no ribbon-style toolbar. (This is a bad thing if you love the Office ribbon and a good thing if you hate the Office ribbon; but I'll leave that up to you to decide. <grin>)

Fig. 1 - EW4's built-in support for PHP Files

One minor personal issue that I have with Expression Web is that VBA was deprecated a while ago, so EW4 doesn't have a macro language that I can use to automate tasks like I would do with previous versions. It's possible to create "add-ins" for Expression Web, but there's a lot of overhead associated with that. From my perspective, that's pretty much like saying to someone, "I know that you would like to get across town and you already have a really nice car, but we're going to take that away. If you take 17 different buses and then walk three or four blocks, you will eventually wind up where you want to go. Of course, it will take you several hours longer and it's a really big hassle, but sooner or later you'll get there." (No comments about carbon footprint - please. <grin>)

That being said, EW4 is a great web site editor and is a good FTP client, and EW4 is much better than its predecessors. (Note: By "predecessors" I mean earlier versions of Expression Web and FrontPage.) I'll explain more in the following sections of this post.

Opening an FTP Site

Opening a site is straight-forward, and for the most part the user interface is the same whether you are opening a site over FTP/FTPS or over HTTP using WebDAV or FPSE.

Fig. 2 - Opening a Site in EW4

When you are opening an FTP or HTTP site for the first time, your list of managed sites will be empty. As you open sites, the list of sites will be populated for each site there you have the Add to managed sites check box selected.

Fig. 3 - EW4's Open Site Dialog Box

Once you have entered your site information, EW4 will prompt you for your remote editing options. This allows you to choose between editing the live site over FTP or editing a local copy and publishing your changes at a later date & time.

Fig. 4 - EW4's Remote Site Editing Options Dialog Box

The last dialog before opening the FTP site is the all-too-familiar prompt for your user credentials, albeit with a warning about FTP credentials being transmitted without encryption. (This is why you should use FTPS, but I'll discuss that later in this post.)

Fig. 5 - EW4's Remote Site Editing Options

Once the credentials have been verified by the FTP server, EW4 will display your site and you can begin editing your content.

Fig. 6 - An example phpBB site opened in EW4

EW4 has some basic site management functionality, which is accessed through the Site -> Manage Site List menu. From there you can add or remove sites from the list. Unfortunately you cannot modify the settings for sites in the list; you have to remove and re-add sites with different settings.

Fig. 7 - Opening the EW4 Site Manager
Fig. 8 - Viewing the list of managed sites

That's it for the simple stuff - now we'll take a look at the specific FTP topics that I've discussed in my other FTP client blog posts.

Using EW4 with FTP over SSL (FTPS)

EW4 supports both Implicit and Explicit FTPS, so the choice is up to you to decide which method to use. The FTPS method is specified by the port number that you choose when you are connecting.

I realize that I have posted the following information in almost all of my posts in this FTP client series, but in the interests of completeness it needs to be said again - the following rules apply for FTP7 when determining whether you are using Implicit or Explicit FTPS:

  • If you enable SSL in FTP7 and you assign the FTP site to port 990, you are using Implicit FTPS.
  • If you enable SSL in FTP7 and you assign the FTP site to any port other than port 990, you are using Explicit FTPS.

EW4 doesn't have a way of specifying Explicit or Implicit FTPS other than the port numbers listed above. That being said, more often than not you will probably be using Explicit FTPS on the default port (21) so you won't need to enter a port at all.

For example, if you are using EW4 with Explicit FTPS on the default port, you can skip adding a port number.

Fig. 9 - Opening a site using Explicit FTPS

However, if you are using Implicit FTPS, you need make sure that you configure EW4 to connect on port 990.

Fig. 10 - Opening a site using Implicit FTPS

Using EW4 with FTP Virtual Host Names

Because EW4's login dialog allows you to specify the virtual host name as part of the user credentials, EW4 works great with FTP7's virtual host names. All that you need to do is use the "ftp.example.com|username" or "ftp.example.com\username" syntax when specifying your username, and when you connect to the FTP7 server it will route your requests to the correct FTP virtual host site.

Fig. 11 - Specifying an FTP Virtual Host name

EW4 Does Not Support True FTP Hosts

Unfortunately EW4 does not have built-in for the HOST command, nor does it have support for entering commands that will be sent before the client has logged in, so you cannot use true FTP host names when using EW4 to connect to FTP7 sites that are configured with host names.

Scorecard for Expression Web 4

This concludes our quick look at some of the FTP features that are available with EW4, and here are the scorecard results:

Client NameDirectory
Browsing
Explicit
FTPS
Implicit
FTPS
Virtual
Hosts
True
HOSTs
Expression Web 4 Y Y Y Y N1
1 As noted earlier, EW4 has no way to send a HOST command, so true FTP HOSTs are not supported.

Note: I've included the following disclaimer in all of my posts, and this post is no exception - there are a great number of additional features that EW4 provides - once again I'm just keeping the focus on those topic areas that apply to FTP7. ;-]


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FTP Clients - Part 8: SmartFTP Client

For this installment in my series about FTP Clients I'm going to review the SmartFTP Client from SmartSoft Ltd. For this blog post I used the SmartFTP Client Ultimate Edition version 4.0.1105.0, and it is available from the following URL:

http://www.smartftp.com/

At the time of this blog post, SmartFTP is a for-retail product that is available in three editions: Home, Professional, and Ultimate. A description of the prices and features that are available in each edition is currently available from the following URL:

http://www.smartftp.com/features/editions.php

As for myself, I would use at least the Professional edition, and that statement is based on the features that I typically look for in an FTP client. (Although I would have loved to have had the Ultimate Edition several years ago when I used Telnet to connect to servers. <grin>)

The SmartFTP Client is pretty intuitive and it's easy to navigate within the application. If you are used to using typical Windows applications then you should find that the user interface follows most of the established paradigms that you would expect from a Microsoft application; it seemed to me that the design emulated the relevant parts of Windows Explorer, Visual Studio, and Office with an FTP focus.

For example, switching your directory listing views align with most Windows applications, and the site management functionality is managed through a hierarchical set of "Favorites."

Each "Favorite" has a variety of additional settings that you can edit by open the properties dialog for the favorite.

One of the great features in all editions of the SmartFTP client is a nicely-implemented Remote Edit functionality, which allows you to invoke your favorite editor from inside the client's GUI.

Command-Line Support versus Extensibility

The SmartFTP Client does not have a built-in command-line interface, although there is a script-based command-line interface that you can download separately from the SmartFTP web site. That being said, that script is not created by the folks at SmartSoft, and it's functionality is extremely limited.

For me personally, the SmartFTP Client's extensibility model more than makes up for the lack of command-line functionality. More often than not I'm simply using the command-line in order to script FTP operations, and the SmartFTP extensibility features provide a great deal more capabilities than I would have available to me when automating a command-line FTP client.

I haven't spent a great deal of time working with the extensibility features, but so far I am pretty impressed. I was able to take one of the samples and retool it into a simple FTP client pretty easily. (I will include that as an example in a later blog post.) In the meantime, you can download the SDK for the SmartFTP Client from the following URL:

http://www.smartftp.com/features/sdk/

Using FTP over SSL (FTPS)

The SmartFTP Client supports both Implicit and Explicit FTPS, so the choice is up to you to decide which method to use. The FTPS method is stored as the Protocol in a favorite's properties, which is easily located in the General settings for a favorite.

Once again, the following rules apply for FTP7 when determining whether to specify Implicit or Explicit FTPS:

  • If you enable SSL in FTP7 and you assign the FTP site to port 990, you are using Implicit FTPS - the SmartFTP Client refers to this as FTP over SSL (Implicit).
  • If you enable SSL in FTP7 and you assign the FTP site to any port other than port 990, you are using Explicit FTPS - the SmartFTP Client refers to this as FTP over SSL (Explicit).

If you are using Implicit FTPS, make sure that you configure your FTP client to connect on port 990.

Using FTP Virtual Hosts

Because the SmartFTP Client's properties for favorites allow you to specify the virtual host name as part of the user credentials, the SmartFTP Client works great with FTP7's virtual host names. All that you need to do is use the "ftp.example.com|username" syntax when specifying your username, and when you connect to the FTP7 server it will route your requests to the correct FTP virtual host site.

Using True FTP Hosts

The SmartFTP Client provides built-in support for the HOST command, which means that you can have real multi-homed FTP sites when using the SmartFTP Client to connect to FTP7 sites that are configured with host names. In order to use true HOSTs in the SmartFTP Client, you need to configure the client to send the FEAT command before logging in. This is configured in the Connection settings in the drop-down menu for "Send FEAT."

As an FYI - I had some discussions with Mat Berchtold from SmartSoft while I was writing this review, and Mat informed me that the SmartFTP Client doesn't automatically assume support for the HOST command; sending the FEAT command before logging in allows the client to discover if HOST is supported before continuing.

Host Names and Firewalls

Mat Berchtold from SmartSoft also mentioned that some firewalls do not yet recognize the HOST command, and therefore those firewalls may not pass the HOST command through the firewall. That's something to think about if you start to see connection failures related to hostnames not being found - you can check your FTP server's logs to see if the HOST command is arriving at the server.

Scorecard for the SmartFTP Client

This concludes our quick look at some of the features that are available with the SmartFTP Client, and here's the scorecard results:

Client NameDirectory
Browsing
Explicit
FTPS
Implicit
FTPS
Virtual
Hosts
True
HOSTs
SmartFTP Client Ultimate 4.0.1105.0 Y Y Y Y Y 1
1 As noted earlier, true FTP HOSTs are fully supported, but you need to configure the SmartFTP Client to send the FEAT command before logging in.

Note: I've included the following disclaimer in all of my posts, and this post is no exception. ;-] There are a great number of additional features that the SmartFTP Client provides - once again I'm just keeping the focus on those topic areas that apply to FTP7.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FTP Clients - Part 7: Kermit FTP Client

Since I started reviewing FTP clients I've had a few requests to look at a few different FTP clients, and I've managed to analyze a few of those clients in my blog. A few weeks ago I had a request from one of my readers that really caught my interest - Shabbir Talib contacted me through my blog and asked me to review the Kermit FTP Client. I found his request especially appealing because I used to use Kermit before the public learned about the Internet; back then I was using Kermit to access dial-up Bulletin Board Systems (BBS's) and to connect to my college's VAX system. That being said, I hadn't used Kermit in years so I couldn't resist taking a look.

To start things off, the Kermit Project is developed and distributed by Columbia University in New York City. More information about the project, downloadable installation packages, and software licenses for purchase are available from:

http://www.columbia.edu/kermit/

I need to stress here the Kermit is actually a full suite of connectivity applications, the Kermit FTP Client is only one part of that communications suite. So from the outset the Kermit is more than overkill if you're just looking to transfer some files to and from your FTP site. The Kermit Dialer takes the place of what most FTP clients would have as a Site Manager, and opening that application will display a large number of templates for various connection types.

Rephrasing my earlier statement, saying that Kermit is overkill is really an unfair assessment when you consider the sheer number of options that Kermit gives you. If you are used to creating and configuring FTP site connections in most FTP clients, you generally have a small handful of options that you can specify. This is not true for Kermit 2.1.3 - the wizard for creating a new FTP connection in the Kermit GUI led me through eleven wizard-based pages of options before the connection was created.

Once you connect, however, the Kermit GUI is just a wrapper for command-line FTP functionality - so you have to know what you're doing in FTP to get around, and there is no explorer-style functionality like you get with graphical FTP clients like Core FTP or FileZilla.

Command-Line and Scripting Support

Since the Kermit GUI is just a wrapper for the command-line, you may have already guessed correctly that the Kermit FTP Client (ftp.exe) works just fine from a command prompt. What's more, Kermit has a built-in scripting language that far surpasses the scripting capabilities for the built-in Windows command-line ftp client (also named ftp.exe.) For example, you can script what action to take if something goes wrong - like retrying a failed upload. More information about scripting the Kermit FTP Client is available at the following URL:

http://www.columbia.edu/kermit/ftpscripts.html

From what I've seen of Kermit's scripting support, this appears to be an extremely rich feature for people that need more options for scripting an FTP client.

Using FTP over SSL (FTPS)

The Kermit FTP Client supports FTPS, and it allows you to configure options such as separate protection levels for the command and data channels for a connection.

Once you have the security options specified for the connection, connecting to an FTP site using FTPS is pretty straightforward.

No Implicit FTPS Support

I could find nothing in the Kermit FTP Client documentation that referenced support for implicit FTPS, and when I configured one of my FTP sites to use implicit FTPS I could not connect to it using Kermit. (But in all fairness, you may recall from some of my earlier blog posts that Implicit FTPS is often considered deprecated.)

Using FTP Virtual Hosts

Like the MOVEit Freely FTP client, everything is happening from a command-line, so you can use both FTP7's Virtual Hosts and the actual FTP HOST command. (As I have mentioned in previous blog posts, you should take a look at my Virtual Hosts and Host Names in FTP7 blog post for more information about FTP Virtual Host Names and FTP True Host Names, and see https://datatracker.ietf.org/drafts/draft-hethmon-mcmurray-ftp-hosts/ for more information about status of the FTP HOST command.)

That being said, FTP7 virtual hosts are supported by using the "ftp.example.com|username" syntax when specifying your username, and when you connect to the FTP7 server it will route your requests to the correct FTP virtual host site.

True FTP hosts can be used by specifying the FTP HOST command using the Kermit FTP Client's support for custom commands. The syntax for this command is listed below:

ftp quote host ftp.example.com

Note: You need to send the HOST command before sending USER and PASS.

Scorecard for the Kermit FTP Client

This concludes our quick look at some of the features that are available with the Kermit FTP Client, and here's the scorecard results:

Client NameDirectory
Browsing
Explicit
FTPS
Implicit
FTPS
Virtual
Hosts
True
HOSTs
Kermit FTP Client 2.1.3 N Y N Y Y 1
1 As noted earlier, true FTP HOSTs are available when using the "ftp quote HOST ftp.example.com" syntax.

Note: Keeping with my standard disclaimer, there are a great number of additional features that the Kermit FTP Client provides - I'm just keeping the focus on those topic areas that apply to FTP7.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

eWeek Reviews for IIS 7.5 and FTP 7.5

One of my coworkers, Vijay Sen, just forwarded the following eWeek review of IIS 7.5 to me:

The review was written by Jim Rapoza, and he said some great things about IIS 7.5, which ships with both Windows Server 2008 R2 and Windows 7 client. But what really made my day was the following things that he said about FTP 7.5:

Another welcome change in IIS 7.5 is the elevation of FTP as a full-fledged part of the server. In previous versions, setup and management of an FTP server in IIS were done pretty much separately from Web server management. In IIS 7.5, FTP administration is fully integrated into the IIS Management Console.

I found this to be a very good implementation of FTP, making it possible to quickly set up secure FTP servers and tie them to my Websites. Especially nice was the ability to easily use virtual host names for the FTP sites. All in all, the FTP implementation in IIS 7.5 is one of the best I've seen, even when compared with dedicated FTP server products.

It's great to see all of our hard work being recognized!

Open-mouthed smile

My thanks once again to everyone on the FTP and IIS feature teams that helped make this version of the FTP service: Jaroslav, Emily, Daniel, Umer, Suditi, Ciprian, Jeong, Dave, Andrew, Carlos, Brian, Wade, Ulad, Nazim, Reagan, Claudia, Rick, Tim, Tobin, Kern, Jenny, Nitasha, Venkat, Vijay. (I hope that I didn't leave anyone out!)


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/

FTP Clients - Part 6: Core FTP LE

For this installment in my series about FTP Clients, I'd like to take a look at the Core FTP client. For this blog post I used Core FTP Lite Edition (LE) version 1.3c (build 1447) and version 2.1 (build 1603), although all of my screen shots are from version 2.1. Core FTP is available from the following URL:

http://www.coreftp.com/

At the time of this blog post, Core FTP provides the LE for free and charges a small fee for a professional version.

Like most graphical FTP clients, the Core FTP LE user interface is pretty easy to use and rather straight-forward - you have separate windows for your local and remote files/folders, as well as a logging window that lists the FTP commands that are sent and the FTP server's responses:

Core FTP LE has a great Site Manager feature, which allows you to store commonly-used connections to FTP sites:

Clicking on the Advanced button gives you a great deal of additional configuration settings, and I'll say more about that later:

Command-Line Support

This is one of my favorite Core FTP LE features: command-line support. Yes - I'm a geek - and I like being able to script things and run batch jobs to automate whatever I can, so command-line support is always a plus for me. That said, the interface for the Core FTP LE command-line client is not an interactive experience like you get with the built-in Windows FTP.EXE or MOVEit Freely command-line clients. The Core FTP LE command-line client is provided as via the Corecmd.exe file that is installed in the main the Core FTP LE application directory, and is used for a single FTP operation like GET or PUT - although you can pass the name of a script file to execute several commands before/after logging in or before/after a file transfer.

So my final judgment is that the Core FTP LE client doesn't have great command-line support, but it's still really nice to have.

Using FTP over SSL (FTPS)

The Core FTP LE client supports both Implicit and Explicit FTPS, so the choice is up to you which method to use. When creating a connection to a server, Core FTP LE has three FTP options that you can use with FTP7:

  • AUTH SSL
  • AUTH TLS
  • FTPS (SSL DIRECT)

It's important to choose this option correctly, otherwise you will run into problems when trying access a site using FTPS. If you'll recall from my "FTP Clients - Part 2: Explicit FTPS versus Implicit FTPS" and my other FTP client blog posts, Explicit FTPS allows the client to initiate SSL/TLS whenever it wants, but for most FTP clients that will be when logging in to your FTP site, and in that regard it may almost seem like Implicit FTPS, but behind the scenes the FTP client and server are communicating differently.

In the case of FTP7, the following rules apply:

  • If you enable FTPS in FTP7 and you assign the FTP site to port 990, you are using Implicit FTPS - Core FTP LE refers to this as FTPS (SSL DIRECT). (Note: make sure that you configure your FTP client to connect on port 990.)
  • If you enable FTPS in FTP7 and you assign the FTP site to any port other than port 990, you are using Explicit FTPS - Core FTP LE allows you to configure your connection to use AUTH SSL or AUTH TLS for the explicit connection.

The type of FTPS is specified on the Connection drop-down menu:

Once you have chosen an FTPS connection, the Core FTP LE client offers you additional options where you can customize which parts of the session will be encrypted:

You can combine the Core FTP SSL options with the advanced SSL policies for your FTP7 sites to customize your security level:

Using FTP Virtual Hosts

Because Core FTP LE's site manager allows you to specify the virtual host name as part of the user credentials, Core FTP LE works great with FTP7's virtual host names. All that you need to do is use the "ftp.example.com|username" syntax when specifying your username, and when you connect to the FTP7 server it will route your requests to the correct FTP virtual host site.

Using True FTP Hosts

A really great feature of Core FTP LE is the ability to send pre-login commands, and since this feature allows you to enter custom commands you can specify the actual FTP HOST command as part of your login:

This is a tremendous feature if you're hosting multiple FTP sites on the same IP address, and gives Core FTP LE some of the best support for true FTP HOSTs.

Scorecard for Core FTP LE

That wraps it up for our quick round-trip for some of Core FTP LE's features, and here's the scorecard results:

Client NameDirectory
Browsing
Explicit
FTPS
Implicit
FTPS
Virtual
Hosts
True
HOSTs
Core FTP LE 1.3 Rich Y Y Y Y 1
Core FTP LE 2.1 Rich Y Y Y Y 1
1 As noted earlier, true FTP HOSTs are available in Site Manager using pre-login commands.

Note: Keeping with my standard disclaimer, there are a great number of additional features that Core FTP LE provides - and I just focused on the topic areas that apply to FTP7.


Note: This blog was originally posted at http://blogs.msdn.com/robert_mcmurray/