c# WebClient ftp Upload security - c#

I have a small function that uploads and download through c# WebClient. I just want to make sure if this is the correct way of doing it without breaking any security rules. This currently work for my application but i am just wondering is the way im doing it is right?
WebClient client = new WebClient();
client.Proxy = new WebProxy();
client.Credentials = new System.Net.NetworkCredential(_username, _password);
client.BaseAddress = _URLPath; // ftp://10.10.10.10/
client.UploadFile(_filePath.Substring(_filePath.LastIndexOf("\\") + 1), _filePath); //filePath = C:\\text.bak
client.DownloadFile(myFile, myFile); //Download myFile = "text.txt"
client.Dispose();
Basically the application uploads a file called "text.bak" from my C:\ and the server right away generates a text file from that called "text.txt" and i download it right away.
Am i leaking any security issues? Thanks

Related

C# Ftp uploading when network break, how to resume? [duplicate]

I am using below code (C# .NET 3.5) to upload a file:
FtpWebRequest request =
(FtpWebRequest)WebRequest.Create("ftp://someweb.mn/altanzulpharm/file12.zip");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.KeepAlive = true;
request.UseBinary = true;
request.Credentials = new NetworkCredential(username, password);
FileStream fs = File.OpenRead(FilePath);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream ftpstream = request.GetRequestStream();
ftpstream.Write(buffer, 0, buffer.Length);
ftpstream.Close();
But the upload breaks when internet interrupted. Interruption occurs for a very small amount of time, almost a millisecond. But uploading breaks forever!
Is it possible to continue or resume uploading after interruption of internet?
I don't believe FtpWebRequest supports re-connection after losing connection. You can resume upload from given position if server supports it (this support is not required and presumably less common that retry for download).
You'll need to set FtpWebRequet.ContentOffset upload. Part of sample from the article:
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(serverUri);
request.ContentOffset = offset;
Internal details of restore in FTP protocol itself - RFC959: 3.5 - Error recovery and restart. Question showing retry code for download - Downloading from FTP with c#, can't retry when fail
The only way to resume transfer after a connection is interrupted with FtpWebRequest, is to reconnect and start writing to the end of the file.
For that use FtpWebRequest.ContentOffset.
A related question for upload with full code (although for C#):
How to download FTP files with automatic resume in case of disconnect
Or use an FTP library that can resume the transfer automatically.
For example WinSCP .NET assembly does. With it, a resumable upload is as trivial as:
// Setup session options
var sessionOptions = new SessionOptions
{
Protocol = Protocol.Ftp,
HostName = "ftp.example.com",
UserName = "user",
Password = "mypassword"
};
using (var session = new Session())
{
// Connect
session.Open(sessionOptions);
// Resumable upload
session.PutFileToDirectory(#"C:\path\file.zip", "/home/user");
}
(I'm the author of WinSCP)

s3 File Uploading is so slow C#

I'm using the transferUtility class to upload files into S3 using input stream in .NET. The problem is, uploading a file of 4MB takes around a minute. I tried both transferUtility.Upload and S3Client.PutObject and the upload time didn't seem to change. The code is below:
WebRequest.DefaultWebProxy = null;
this.S3Client = new Amazon.S3.AmazonS3Client(accessKeyId, secretAccessKey, endPoint);
this.transferUtility = new TransferUtility(this.S3Client);
Amazon.S3.Transfer.TransferUtilityUploadRequest transferRequest = new TransferUtilityUploadRequest();
transferRequest.BucketName = s3Bucket;
transferRequest.CannedACL = Amazon.S3.S3CannedACL.PublicRead;
transferRequest.InputStream = (Stream)fileStream;
transferRequest.Key = newFileName;
transferRequest.Headers.Expires = new DateTime(2020, 1, 1);
this.transferUtility.Upload(transferRequest);
Any help would be appreciated.
Thank you,
I found that this is happening because of an uploading the file stream to the application server takes a very long time.
This is likely also due to the C# SDK MD5sum'ing every chunk it uploads (CPU performance hit and thus slows down the upload while an MD5Sum is computed).
See https://github.com/aws/aws-sdk-net/issues/832#issuecomment-383756520 for workaround.

Upload directory of files to FTP server using WebClient

I have searched and searched and cannot find a way to do this. I have files in a directory I want to upload. The file names change constantly so I cannot upload by file name. Here is what I have tried.
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential("User", "Password");
foreach (var filePath in files)
client.UploadFile("ftp://site.net//PICS_CAM1//", "STOR", #"PICS_CAM1\");
}
But I am getting a compiler error:
The name 'files' does not exist in the current context
Everything I have researched says this should work.
Does anyone have a good way to upload a directory of files via WebClient?
You have to define and set the files. If you wanted to upload all files in a certain local directory, use for example Directory.EnumerateFiles.
Also the address argument of WebClient.UploadFile has to be a full URL to a target file, not just a URL to a target directory.
IEnumerable<string> files = Directory.EnumerateFiles(#"C:\local\folder");
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential("username", "password");
foreach (string file in files)
{
client.UploadFile(
"ftp://example.com/remote/folder/" + Path.GetFileName(file), file);
}
}
For a recursive upload, see:
Recursive upload to FTP server in C#
I think your web client upload will work fine. Your issue is that your variable files is not in scope.
You need to post more of your code so we can see better

WebClient with Mono for android to create file on server

I would like to write data to a file on a server. Therefore, I use the following code:
System.Net.WebClient webClient = new System.Net.WebClient();
string webAddress = "https://sd2dav.1und1.de/"; //1&1 Webdav
string destinationFilePath = webAddress + "testfile.txt";
webClient.Credentials = new System.Net.NetworkCredential("myuser", "mypassword");
Stream stream = webClient.OpenWrite(destinationFilePath,"PUT");
UnicodeEncoding uniEncoding = new UnicodeEncoding();
using(StreamWriter sw = new StreamWriter(stream, uniEncoding))
{
sw.Write("text");
sw.Flush();
}
webClient.Dispose();
This works fine when compiled with Visual Studio 2008, .net 3.5 and executed on Windows 7. However, I would like to do this with Mono for Android (4.4.54). Here, the code executes, but nothing happens: The file is not created on the server.
Is this a bug in Mono for Android or is anything wrong with the code above? Do you know a way to get this working?
Update: I filed a bug at https://bugzilla.xamarin.com/show_bug.cgi?id=10163 regarding this issue. Hopefully, the guys from Xamarin will take care of this. Furthermore, I presented an alternative way of sending the data to the server at https://stackoverflow.com/questions/14786214/alternative-to-webclient-openwrite.

Can't connect to FTP: (553) File name not allowed

I need to FTP a file to a directory. In .Net I have to use a file on the destination folder to create a connection so I manually put Blank.dat on the server using FTP. I checked the access (ls -l) and it is -rw-r--r--. But when I attempt to connect to the FTP folder I get: "The remote server returned an error: (553) File name not allowed" back from the server. The research I have done says that this may arrise from a permissions issue but as I have said I have permissions to view the file and can run ls from the folder. What other reasons could cause this issue and is there a way to connect to the folder without having to specify a file?
byte[] buffer;
Stream reqStream;
FileStream stream;
FtpWebResponse response;
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create(new Uri(string.Format("ftp://{0}/{1}", SRV, DIR)));
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(UID, PASS);
request.UseBinary = true;
request.Timeout = 60000 * 2;
for (int fl = 0; fl < files.Length; fl++)
{
request.KeepAlive = (files.Length != fl);
stream = File.OpenRead(Path.Combine(dir, files[fl]));
reqStream = request.GetRequestStream();
buffer = new byte[4096 * 2];
int nRead = 0;
while ((nRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
reqStream.Write(buffer, 0, nRead);
}
stream.Close();
reqStream.Close();
response = (FtpWebResponse)request.GetResponse();
response.Close();
}
Although replying to an old post just thought it might help someone.
When you create your ftp url make sure you are not including the default directory for that login.
for example this was the path which I was specifying and i was getting the exception 553 FileName not allowed exception
ftp://myftpip/gold/central_p2/inbound/article_list/jobs/abc.txt
The login which i used had the default directory gold/central_p2.so the supplied url became invalid as it was trying to locate the whole path in the default directory.I amended my url string accordingly and was able to get rid of the exception.
my amended url looked like
ftp://myftpip/inbound/article_list/jobs/abc.txt
Thanks,
Sab
This may help for Linux FTP server.
So, Linux FTP servers unlike IIS don't have common FTP root directory. Instead, when you log on to FTP server under some user's credentials, this user's root directory is used. So FTP directory hierarchy starts from /root/ for root user and from /home/username for others.
So, if you need to query a file not relative to user account home directory, but relative to file system root, add an extra / after server name. Resulting URL will look like:
ftp://servername.net//var/lalala
You must be careful with names and paths:
string FTP_Server = #"ftp://ftp.computersoft.com//JohnSmith/";
string myFile="text1.txt";
string myDir=#"D:/Texts/Temp/";
if you are sending to ftp.computersoft.com/JohnSmith a file caled text1.txt located at d:/texts/temp
then
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(FTP_Server+myFile);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(FTP_User, FTP_Password);
StreamReader sourceStream = new StreamReader(TempDir+myFile);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
notice that at one moment you use as destination
ftp://ftp.computersoft.com//JohnSmith/text1.txt
which contains not only directory but the new file name at FTP server as well (which in general can be different than the name of file on you hard drive)
and at other place you use as source
D:/Texts/Temp/text1.txt
your directory has access limit.
delete your directory and then create again with this code:
//create folder
FtpWebRequest request = (FtpWebRequest)FtpWebRequest.Create("ftp://mpy1.vvs.ir/Subs/sub2");
request.Method = WebRequestMethods.Ftp.MakeDirectory;
request.Credentials = new NetworkCredential(username, password);
request.UsePassive = true;
request.UseBinary = true;
request.KeepAlive = true ;
using (var resp = (FtpWebResponse)request.GetResponse())
{
}
I saw something similar to this a while back, it turned out to be the fact that I was trying to connect to an internal iis ftp server that was secured using Active Directory.
In my network credentials I was using new NetworkCredential(#"domain\user", "password"); and that was failing. Switching to new NetworkCredential("user", "password", "domain"); worked for me.
I hope this will be helpful for someone
if you are using LINUX server, replace your request path from
FtpWebRequest req= (FtpWebRequest)WebRequest.Create(#"ftp://yourdomain.com//yourpath/" + filename);
to
FtpWebRequest req= (FtpWebRequest)WebRequest.Create(#"ftp://yourdomain.com//public_html/folderpath/" + filename);
the folder path is how you see in the server(ex: cpanel)
Although it's an older post I thought it would be good to share my experience. I came faced the same problem however I solved it myself. The main 2 reasons of this problem is Error in path (if your permissions are correct) happens when your ftp path is wrong. Without seeing your path it is impossible to say what's wrong but one must remember the things
a. Unlike browser FTP doesn't accept some special characters like ~
b. If you have several user accounts under same IP, do not include username or the word "home" in path
c. Don't forget to include "public_html" in the path (normally you need to access the contents of public_html only) otherwise you may end up in a bottomless pit
Another reason for this error could be that the FTP server is case sensitive. That took me good while to figure out.
I had this problem when I tried to write to the FTP site's root directory pro grammatically. When I repeated the operation manually, the FTP automatically rerouted me to a sub-directory and completed the write operation. I then changed my code to prefix the target filename with the sub-directory and the operation was successful.
Mine was as simple as a file name collision. A previous file hadn't been sent to an archive folder so we tried to send it again. Got the 553 because it wouldn't overwrite the existing file.
Check disk space on the remote server first.
I had the same issue and found out it was because the remote server i was attempting to upload files to had run out of disk space on the partition or filessytem.
To whom it concerns...
I've been stuck for a long time with this problem.
I tried to upload a file onto my web server like that:
Say that my domain is www.mydomain.com.
I wanted to upload to a subdomain which is order.mydomain.com, so I've used:
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create($#"ftp://order.mydomain.com//uploads/{FileName}");
After many tries and getting this 553 error, I found out that I must make the FTP request refer to the main domain not the sub domain and to include the subdomain as a subfolder (which is normally created when creating subdomains).
As I've created my subdomain subfolder out of the public_html (at the root), so I've changed the FTP Request to:
FtpWebRequest ftpReq = (FtpWebRequest)WebRequest.Create($#"ftp://www.mydomain.com//order.mydomain.com//uploads/{FileName}");
And it finally worked.

Categories