1

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.

c00000fd
  • 20,994
  • 29
  • 177
  • 400

1 Answers1

1

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.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • Yeah, I had a similar experience. I tried it with one server and it failed. But then worked on another. So there must be something on the server end. (I'm using shared web hosting, so I don't have full access to the servers to investigate it more.) Interestingly enough, doing it via SSH or SFTP seems to work. I'm using SSH.NET library. So the issue must be in the FTP handler on the server end. Just a guess though... – c00000fd Oct 04 '17 at 06:07
  • Hmm... just saw your edit. Yeah, it could be an asterisk. – c00000fd Oct 04 '17 at 06:07