Hide FTP credentials from code .NET C# - c#

I have an application that needs to upload a file to my FTP server, but I noticed that anybody could decompile that app and get the FTP's user and password.
The code is this:
using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential("ftpuser", "ftppassword");
client.UploadFile("ftp://ip/" + Computer + "_" + ExecTime + ".txt", "STOR", Application.StartupPath + #"\Stats.txt");
}
And I would like to hide those credentials from anyone. How could this be done?

It might be wiser to implement public FTP with no credentials and very limited access only to the resources you want. Obfuscation won't work since someone will de-obfuscate it anyway. Since you want to upload files from the client you may want to put some sort of controller so the upload mechanism can't be abused.
Or... simply give each user an account with limited access and problem sorted :).
I think this is more of a design problem :)

Related

Not able to download JDK in C# program

I am trying to write a C# program where I need to download jdk on the machine. I have written some code but it only downloads like 3-4 kb every time
static void Main(string[] args)
{
WebClient client = new WebClient();
string address = "https://download.oracle.com/otn/java/jdk/8u211-b12/478a62b7d4e34b78b671c754eaaf38ab/jdk-8u211-windows-x64.exe";
Uri uri = new Uri(address);
var desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string fileName = desktop + "\\jdk.exe";
Console.WriteLine("Downloading file");
client.DownloadFile(address, fileName);
Console.WriteLine("Done Downloading File");
Console.ReadLine();
}
If you put the address in a browser, you will quickly see why.
Downloading JDK8 requires you to be logged in now. They do this for older versions of Java. I believe JDK8 started this behavior about a month of so ago.
The URL which you refer redirects to a SSO (Single Sign On) page of oracle site. Probably the 4kb data can be related to the web page and not .exe file. If you plan to automate the download make sure to pass username and password to the SSO page.

Attaching auto generated pdf to email in asp.net app

I have a very specific requirement. In my web app, I have to generate a pdf invoice from the database values, and an email body. I can easily send this using SMTP which works perfect.
But, problem is we can't rely on system to always be perfect, and this is an invoice. So, we need to open the default mail client instead of using SMTP. Right now, I have following code
//Code to create the script for email
string emailJS = "";
emailJS += "window.open('mailto:testmail#gmail.com?body=Test Mail" + "&attachment=" + emailAttachment + "');";
//Register the script for post back
ClientScript.RegisterStartupScript(this.GetType(), "mailTo", emailJS, true);
This opens the email perfectly, but no attachment is working. Path is supposed to be /Web/Temp/123.pdf.
If I use the same path as normal url like below, it opens the file in new window properly.
ClientScript.RegisterStartupScript(this.GetType(), "newWindow", "window.open('/Web/Temp/123.pdf');", true);
So, clearly file exists, but it exists on the server. Outlook on the other hand open on client machine. So, I can't use the full determined path like C:\Web\Temp\123.pdf. If I try that, it will try to find the file on client machine, where the folder itself might not exist.
I am trying to figure out what can I do here. If there is another method I should try.
P.S. No, I can't send the email directly. That will cause a hell lot more problem in future for me.
Edit:
I also found one weird problem. If I add a double quote to the file path in attachment, a \ is added automatically. #"&attachment=""" + Server.MapPath(emailAttachment) + #"""');" gives me output as &attachment=\"C:\Web\Temp\123.pdf\".
I am trying to escape that double quote and somehow it adds that slash. I know this is a completely different problem, but thought I should mention here, instead of creating a new question.
Edit:
I tried a fixed path on localhost. So, I am basically testing the app on the same machine where file is getting stored. still, no attachment at all.
string emailJS = "";
emailJS += #"window.open('mailto:jitendragarg#gmail.com?body=Test Mail" + emailAttachment + #"&attachment=";
emailJS += #"""D:\Dev\CSMS\CSMSWeb\Temp\635966781817446275.Pdf""');";
//emailJS += Server.MapPath(emailAttachment) + #"');";
//Register the script for post back
ClientScript.RegisterStartupScript(this.GetType(), "mailTo", emailJS, true);
Updated the path to make sure it is proper. Now, it just throws error saying command line argument not valid.
Edit:
Is there any other method I can try? I have the file path on the server side. Maybe I can download the file automatically to some default folder on client machine and open from there? Is that possible?
Edit: I tried one more option.
emailJS += #"mailto:testmail#gmail.com?body=Test Mail" + #"&attachment=";
emailJS += #"\\localhost\CSMSWeb\Temp\635966781817446275.Pdf";
//emailJS += Server.MapPath(emailAttachment) + #"');";
Process.Start(emailJS);
The Process.Start line works but it does nothing at all. There is no process that starts, no error either.
Edit:
yay. I finally got the user to approve using a separate form to display the subject and body, instead of opening the default mail client. although, I would still prefer to solve this problem as is.
So, the problem here is the fact that mailto only supports direct file path for attachment. That is, path has to be local to use machine, or intranet path within the network.
In other words, path like http://yourapp/Web/Temp/123.pdf won't work, and /Web/Temp/123.pdf being essentially the same won't work either. These are not paths, but links to files that has to be downloaded and stored locally before they can be used as attachments - mailto protocol has no support for that.
However, since your application is intranet, what you could do is make sure intended users have access to some network shared folder on your server, and then provide them with network path to the file, that is \\theserver\files\123.pdf

WebException: Cannot open passive data connection

May be this question seems duplicate to you. But still I want exact cause of solution for my problem.
The problem is I am requesting a file from FTP with username and password. After ftp connection initialization, it throws me an exception WebException: Cannot open passive data connection.
But I am able to download the same file using web browser like Chrome with same username and password.
It is a Unity 3D game where user info is actually requested and some user related files will be downloaded. I am using MonoDevelop to code
The server an AWS server. Its IP address is recently changed and it was restarted. I am using the new IP and getting list of files in an XML format. I am able to parse the xml data and be able to request the file.
Here is the code sample I am using for FTP.
reqFTP = (FtpWebRequest)FtpWebRequest.CreateDefault(new Uri("ftp://" + serverIP + ":" + serverPort + "/" + this.receiveInfo.fileDirectory + "/" + downloadLoc));
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
Debug.Log (reqFTP.RequestUri);
reqFTP.UseBinary = true;
reqFTP.UsePassive = true;
reqFTP.Credentials = new NetworkCredential(this.receiveInfo.ftpUsername , this.receiveInfo.ftpPassword);
object state = new object ();
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Please help me to solve this issue. Atleast some useful information is much appreciated as I am very new to this kind of stuff.
I found the answer to my question.
The problem was with the FTP configuration. When the server was restarted the old ftp settings were imposed on the server. So it was blocking all passive ftp connections from clients. The AWS support person changed the configuration, then it started working.
After the config file was changed, the issue got solved. There is no need to change the code. The code is correct.

How to write to an iSeries FileShare from ASP.Net

I've written an asp.net webapp that writes a file to a location on our iSeries FileShare.
The path looks like this: \IBMServerAddress\Filepath
This code executes perfectly on my local machine, but fails when it's deployed to my (windows) WebServer.
I understand that i may need to do some sort of impersonation to authenticate access to the IFS, but i'm unsure of how to proceed.
Here's the code i'm working with:
string filepath = "\\\\IBMServerAddress\\uploads\\";
public int SaveToDisk(string data, string plant)
{
//code for saving to disk
StreamWriter stream = null;
stream = File.CreateText(filepath + plant + ".txt"); // creating file
stream.Write(data + "\r\n"); //Write data to file
stream.Close();
return 0;
}
Again, this code executes perfectly on my local machine but does not work when deployed to my Windows WebServer - access to filepath is denied.
Thanks for your help.
EDIT: I've tried adding a network account with the same credentials as the IFS user, created a UNC path (iseries)on IIS7 to map the network drive (using the same credentials) - but receive this error:
Access to the path 'iseries\' is denied.
My understanding of Windows in general is that normally services don't have access to standard network shares like a program being run by a user does.
So the first thing would be to see if you can successfully write to a windows file share from the web server.
Assuming that works, you'll need one of two things in order to write to the IBM i share..
1) An IBM i user ID and password that matches the user ID and password the process is being run under
2) A "guest account" configured on IBM i Netserver
http://www-01.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzahl/rzahlsetnetguestprof.htm
You might have better luck with using Linux/UNIX based Network File System (NFS) which is supported in both Windows and the IBM i.

SFTP with .NET 3.5

I need to connect to an SFTP server to download and upload files using C#/.NET 3.5.
Does the .NET 3.5 framework provide any built-in tools/mechanisms/libraries to connect to an SFTP server to download and upload files?
There are commercial solutions:
http://www.rebex.net/sftp.net/
http://www.enterprisedt.com/products/edtftpnetpro/overview.html
...and free:
http://www.tamirgal.com/blog/page/SharpSSH.aspx
I personally have no experience with any of them.
There's no support for SFTP in .NET framework, in any version.
The answer by Sanj shows how to use WinSCP by driving its console application. While that's indeed possible, where actually WinSCP .NET assembly that does it for a developer, giving him/her native .NET interface to the WinSCP scripting.
There's even a WinSCP NuGet package.
A trivial SFTP upload C# example:
// Setup session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "example.com",
UserName = "user",
Password = "mypassword",
SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...="
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Upload files
session.PutFiles(#"d:\toupload\*", "/home/user/").Check();
}
And the same for VB.NET:
' Setup session options
Dim sessionOptions As New SessionOptions
With sessionOptions
.Protocol = Protocol.Sftp
.HostName = "example.com"
.UserName = "user"
.Password = "mypassword"
.SshHostKeyFingerprint = "ssh-rsa 2048 xxxxxxxxxxx...="
End With
Using session As New Session
' Connect
session.Open(sessionOptions)
' Upload files
session.PutFiles("d:\toupload\*", "/home/user/").Check()
End Using
There are lot of other examples in both languages (and more).
You can have WinSCP GUI generate an SFTP code template, like above, for you, including C#, VB.NET and PowerShell.
As mentioned above, the assembly is just a wrapper around WinSCP scripting, so it's not a completely native .NET code. As such it does not fit all use cases in .NET framework. It is mostly suitable for automating tasks, not for developing GUI or web applications.
For a fully native .NET SFTP library, see SSH.NET, which is strangely not mentioned in any answer yet.
(I'm the author of WinSCP)
No, .NET doesn't ship with any SFTP libraries. However, WinSCP is a free utility you can download. I've used it before to download information from a PayPal report server.
It has a nice command line setup for you to automate the download / upload of files too. So from my .NET app, you just invoke the process with the specific arguments and wait until it completes.
I prefer WinSCP. It's free and I've tried it before, it works perfectly. If you download the COM file and you could do something like below:
NOTE: I'm passing the params from ini.
const string logname = "log.xml";
string username = ini.IniReadValue("sftp", "Username");
string password = ini.IniReadValue("sftp", "Password");
string remotehost = ini.IniReadValue("sftp", "Remote Host");
string dloadpath = ini.IniReadValue("Download", "Local Path");
Process winscp = new Process();
winscp.StartInfo.FileName = #ini.IniReadValue("winscp", "compath");
winscp.StartInfo.Arguments = "/log=" + logname;
winscp.StartInfo.UseShellExecute = false;
winscp.StartInfo.RedirectStandardInput = true;
winscp.StartInfo.RedirectStandardOutput = true;
winscp.StartInfo.CreateNoWindow = true;
try
{
winscp.Start();
lblconfirm.Text = "Status: WinSCP Started Successfully";
}
catch (Exception ex)
{
writeLog("from PutSFTP: Could not run the WinSCP executable " + winscp.StartInfo.FileName + Environment.NewLine + ex.Message);
}
winscp.StandardInput.WriteLine("option batch abort");
winscp.StandardInput.WriteLine("option confirm off");
winscp.StandardInput.WriteLine("open sftp://" + username + ":" + password + "#" + remotehost);
winscp.StandardInput.WriteLine("cd " + ini.IniReadValue("Download", "Remote Path"));
winscp.StandardInput.WriteLine(#"get " + "/" + ini.IniReadValue("Download", "Remote Path") + "/*" + ini.IniReadValue("Download", "FileType") + " " + ini.IniReadValue("Download", "Local Path"));
winscp.StandardInput.Close();
string output = winscp.StandardOutput.ReadToEnd();
lblconfirm.Text = "Download Success! Check logs for moe info";
winscp.WaitForExit();
The framework does not provide SFTP support.
IIS 7.x (which comes with Windows server 2008 or Windows 7) supports only FTPs, not sFTP natively (explanation see update below) - however there are server solutions like this one available for the sFTP protocol.
If you require an sFTP client, Microsoft has not provided any support so far. But I've made very good expericence with a 3rd party .NET component named wodSFTP.NET, which is a sFTP client.
Here you can find the product & documentation: wodSFTP.NET.
Examples and online-documentation can be downloaded without any charge or registration from them.
Note that you can choose whether you buy the version without or with Sourcecode in C#. They have a SSH component as well. Examples are always available (regardless of the version you choose) in C# and VB.NET.
Example (from the website www.weonlydo.com, converted to C#):
var wodSFTP1 = new WeOnlyDo.Client.SFTP();
// Authenticate with server using hostname, login, password.
wodSFTP1.Hostname = "your_hostname";
wodSFTP1.Login = "your_login";
wodSFTP1.Password = "your_password";
wodSFTP1.Blocking = True; // Use synchronous connections
wodSFTP1.Connect();
wodSFTP1.GetFile("c:\", "/home/somepath/somefile.txt");
This example uses blocking (synchronous) mode. Note that you can also use the component asynchronously - in this case events will be fired and you can write event handlers to react on them.
Note that this example does not use a key to authenticate, but of course this is also supported (you can use key-based authentication, password-based authentication or both).
Update: FTPs and sFTP are different protocols. Please follow the links for an explanation.
Since there is no native support, uou can search in Google for other, commercial, components, just type something like 'SFTP components .NET'

Categories