.netubuntuftpftpwebrequestftpwebresponse

FtpWebResponse fails to create directory for WebRequestMethods.Ftp.MakeDirectory method for a specific directory name on Ubuntu server


I'm trying to stress-test my .NET application's function that uploads files via FTP(s) protocol. This function uses the .NET's built-in FtpWebResponse class (in case a user's server does not support SSH connection.) I'm using the following code to try to create the "test up1/archive: * OR | or $ or < and >." directory on an Ubuntu server in my user's directory:

//First call succeeds
string strPath = "ftp://webhost.com/%2F/UserDir/" +
    Uri.EscapeDataString("test up1") + "/";
createDirViaFTP(strPath);

//but then this call fails
strPath += Uri.EscapeDataString("archive: * OR | or $ or < and >.") + "/";
createDirViaFTP(strPath);


static bool createDirViaFTP(string strURI)
{
    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(strURI);
    request.EnableSsl = bUseSsl;   //can be either false or true
    request.Credentials =  = new NetworkCredential(strUsrName, secUsrPwd);
    request.UseBinary = true;
    request.Timeout = -1;

    request.Method = WebRequestMethods.Ftp.MakeDirectory;

    try
    {
        using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
        {
            if (response.StatusCode == FtpStatusCode.PathnameCreated)
            {
                //Created OK
                return true;
            }
        }
    }
    catch(Exception ex)
    {
        //Failed
        Console.WriteLine("EXCEPTION: Path=" + strURI + "\n" + ex.Message);
    }

    return false;
}

The second call to my createDirViaFTP throws the following exception when I try to create "archive: * OR | or $ or < and >." dir:

EXCEPTION: Path=ftp://webhost.com/%2F/UserDir/test%20up1/archive%3A%20*%20OR%20%7C%20or%20%24%20or%20%3C%20and%20%3E./
The remote server returned an error: (550) File unavailable (e.g., file not found, no access).

But why? What am I doing wrong here? All those symbols in the second directory name should be legal Linux file names. I can create that same directory via SSH shell.


Solution

  • I cannot create such folder on *nix ProFTPD FTP server, even though I can create such folder on the same system in shell.

    In FTP, I get

    550 archive: * OR | or $ or < and >.: Invalid directory name

    And that's probably, what the FtpWebRequest gets too. It just blindly translates any 550 error to "File unavailable".

    So I do not think it's a problem of your code, but rather a restriction of the FTP server on file/directory names.

    Notably, ProFTPD unconditionally disallows asterisk in directory names.

    See core_mkd function:

    MODRET core_mkd(cmd_rec *cmd) {
      int res;
      char *decoded_path, *dir;
    
      CHECK_CMD_MIN_ARGS(cmd, 2);
    
      /* XXX Why is there a check to prevent the creation of any directory
       * name containing an asterisk?
       */
      if (strchr(cmd->arg, '*')) {
        pr_response_add_err(R_550, _("%s: Invalid directory name"), cmd->arg);
    
        pr_cmd_set_errno(cmd, EINVAL);
        errno = EINVAL;
        return PR_ERROR(cmd);
      }
      ...
    

    And indeed, if I remove the * from the directory name, creation succeeds. So I guess, that you also use ProFTPD FTP server for your tests.