C# Win Form App and FTP connection - c#

I'm creating a Windows Form Application (C#) that connects to the FTP server, using Visual Studio 2013 Express.
Problem: The remote server returned an error: (530) Not logged in.
Notes:
no problems connecting to the server using primary FTP account;
determined that the problem is caused by # symbol in the ftpUser;
tried replacing ftpUser and ftpPW with the values;
host - GoDaddy - unlike primary account, all secondary FTP accounts need to have #example.com in their username;
verified, using FileZilla, that the secondary account credentials are correct;
in point 5), noticed in FileZilla log, Server does not support non-ASCII characters - even though it connects/transfers files without problems;
Below you will find the code that I'm using:
//Set Host, User and Password for the FTP;
string ftpHost = "ftp.example.com";
string ftpUser = "user#example.com";
string ftpPW = "passw0rd";
string ftpFullPath = #"ftp://" + ftpHost + ftpfilepath;
//Establish a connection to the server;
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(ftpFullPath);
ftp.Credentials = new NetworkCredential(ftpUser, ftpPW);
ftp.KeepAlive = true;
ftp.UseBinary = true;
I'm wondering if the server is translating the proxy as username#host (i.e. user#example.com#ftp.example.com;
I apologize in advance if I made any mistakes in the lingo. I'm fairly new to programming.

You are missing the separation folder char (usually / or //) so the FTP server can index the file you want to get. Change this line and try with:
string ftpFullPath = #"ftp://" + ftpHost + "/" ftpfilepath;
Or
string ftpFullPath = #"ftp://" + ftpHost + "//" ftpfilepath;
Or (better way if available):
string ftpFullPath = #"ftp://" + Path.Combine(ftpHost, ftpfilepath);

Related

Connecting to WMI Remotely with C# to a non-domain PC not working

I use the Microsoft.Management.Infrastructure namespace to connect to remote computers to get WMI information and it works. But when I try to connect to a non-domain PC it does not work. Can anyone pinpoint what I am doing wrong.
Here is the code:
string computer = "Computer_B";
string domain = "WORKGROUP";
string username = ".\\LocalAdminUserName";
string plaintextpassword;
Console.WriteLine("Enter password:");
plaintextpassword = Console.ReadLine();
SecureString securepassword = new SecureString();
foreach (char c in plaintextpassword)
{
securepassword.AppendChar(c);
}
CimCredential Credentials = new
CimCredential(PasswordAuthenticationMechanism.Default, domain,
username,securepassword);
WSManSessionOptions SessionOptions = new WSManSessionOptions();
SessionOptions.AddDestinationCredentials(Credentials);
CimSession Session = CimSession.Create(computer, SessionOptions);
var allVolumes = Session.QueryInstances(#"root\cimv2", "WQL", "SELECT * FROM Win32_LogicalDisk");
// Loop through all volumes
foreach (CimInstance oneVolume in allVolumes)
{
Console.Writeline(oneVolume.CimInstanceProperties["SystemName"].Value.ToString());
}
I am not sure what to take as paramaters for domain and username for a local computer. I have already done/tryed the following:
run winrm quickconfig on the remote local computer
use PasswordAuthenticationMechanism.Negotiate cause I have read Kerberos only
works for domain users and password
added the computer I run the code on to the TrustedHosts on the local computer with winrm config. Also tryed adding * to the TrustedHosts
Used for username="computer_B\LocalAdminUserName". I have also tryed with domain=""
Any suggestions what I am doing wrong?
The error I keep getting is: WinRM cannot process the request. The following error with error code 0x8009030e occurred while using Negotiate authentication: A specified logon session does not exist. It may already have been terminated.
This can occur if the provided credentials are not valid on the target server, or if the server identity could not be verified. If you trust the server identity, add the server name to the TrustedHosts list, and then retry the request. Use winrm.cmd to view or edit the TrustedHosts list. Note that computers in the TrustedHosts list might not be authenticated. For more information about how to edit the TrustedHosts list, run the following command: winrm help config.
Try out the code below, this is working on impersonation logic.
ConnectionOptions cOption = new ConnectionOptions();
ManagementScope scope = null;
Boolean isLocalConnection = isLocalhost(machine);
if (isLocalConnection)
{
scope = new ManagementScope(nameSpaceRoot + "\\" + managementScope, cOption);
}
else
{
scope = new ManagementScope("\\\\" + machine + "\\" + nameSpaceRoot + "\\" + managementScope, cOption);
}
if (!String.IsNullOrEmpty(ACTIVE_DIRECTORY_USERNAME) && !String.IsNullOrEmpty(ACTIVE_DIRECTORY_PASSWORD) && !isLocalConnection)
{
scope.Options.Username = ACTIVE_DIRECTORY_USERNAME;
scope.Options.Password = ACTIVE_DIRECTORY_PASSWORD;
}
scope.Options.EnablePrivileges = true;
scope.Options.Authentication = AuthenticationLevel.PacketPrivacy;
scope.Options.Impersonation = ImpersonationLevel.Impersonate;
scope.Connect();

Programmatically login 10 users to remote desktop session

I am trying to create an application that will programmatically login 10 users using RDP. The purpose is to autologin these users so someone does not have to manually do it. The first server I tested against (Server 2012) worked just fine. However, I tried a Server 2008 R2 and it continues to prompt me for a password. Here is the code.
static void Main(string[] args)
{
var password = ConfigurationManager.AppSettings["Password"];
var machine = ConfigurationManager.AppSettings["MachineName"];
var userNameList = new List<string>(ConfigurationManager.AppSettings["UserName"].Split(new char[] { ';' }));
foreach(string name in userNameList)
{
Process rdpProcess = new Process();
rdpProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\cmdkey.exe");
rdpProcess.StartInfo.Arguments = "/generic:TERMSRV/" + machine + "/user:" + name + " /pass:" + password;
rdpProcess.Start();
rdpProcess.StartInfo.FileName = Environment.ExpandEnvironmentVariables(#"%SystemRoot%\system32\mstsc.exe");
rdpProcess.StartInfo.Arguments = "/v " + machine;
rdpProcess.Start();
Thread.Sleep(3000);
}
}
I added the sleep as the connections were coming too fast and I was getting "connection is busy" errors.
Can anyone see anything I am doing wrong?
Don't really know why this was the case but my 2008 servers will not work with FQDN. IP works fine though. Whatever..

ftp upload error : “The given path's format is not supported."

I can download a file without any issues from FTP but cannot upload a file from local to FTP. I have changed it to blackslash and forward slashes on address path but still have the same error.
string _ftpURL = #"192.168.0.134";
string _UserName = "root"; //User Name of the SFTP server
string _Password = "porter"; //Password of the SFTP server
int _Port = 2222; //Port No of the SFTP server (if any)
string _ftpDirectory = "/home/root/systools/WM"; //The directory in SFTP server where the files will be uploaded
string LocalDirectory = " E:\\charan\\final test\\WebMobility.db"; //Local directory from where the files will be uploaded
Sftp Connection = new Sftp(_ftpURL, _UserName, _Password);
Connection.Connect(_Port);
**Connection.Put(LocalDirectory, _ftpDirectory);**
Connection.Close();
I believe you have an addional blank in your local directory variable:
string LocalDirectory = " E:\\charan\\final test\\WebMobility.db";
change it to
string LocalDirectory = "E:\\charan\\final test\\WebMobility.db";
If you're using one "/" without disabling the escape sequence, you're string won't be interpreted properly.
Try it with
string _ftpDirectory = #"/home/root/systools/WM";
or
string _ftpDirectory = "//home//root//systools//WM";
You can read more about escape sequences here

C# Mysql connection working only on localhost

I'm connecting to a mysql database in c#, and it all works well as long as I input the server address as "localhost" or its ip, but if I try a remote ip it fails with:
Error: 0 : Unable to connect to any of the specified MySQL hosts.
here's the code:
server = Properties.Settings.Default.DBHost;
port = Properties.Settings.Default.DBPort;
database = Properties.Settings.Default.DBName ;
uid = Properties.Settings.Default.DBUser;
password = Properties.Settings.Default.DBPassword ;
string connectionString;
connectionString = "SERVER=" + server + ";" + "PORT=" + port + ";" + "DATABASE=" + database + ";" + "UID=" + uid + ";" + "PASSWORD=" + password + ";";
connection = new MySqlConnection(connectionString);
[...]
if (this.OpenConnection() == true){
// exec db operations
}
else{
MessageBox.Show("Database Connection Error.");
}
Tested:
No firewall restrictions
Same error in different computers
Already tried on with different remote databases, all with set privileges and accessible from other sources
If its your mysql server then,
Check you port is open or not. (probably 3306)
Change your bind-address in your my.ini file (from 127.0.0.1 to 0.0.0.0)
Double check the user your trying to connect to server has necessary privileges
If its not your mysql server then,
Ask the provider whether they are supporting remote connections or not.
1st you have to check if your server is supporting remote MySQL database Connection then
You can try this MySQL Connection String Builder example, i'm working with all the time .. no errors :
_connectionStr = new MySqlConnectionStringBuilder
{
Server = "127.0.0.1",
Database = myDatabase,
UserID = myUserName,
Password = myPassword,
ConnectionTimeout=60,
Port = 3306,
AllowZeroDateTime = true
};
_con = new MySqlConnection(_connectionStr.ConnectionString);
try
{
_con.Open();
}
catch
{
MessageBox.Show("Error, help i can't get connected!");
}
Hope this works!
Maybe your MySQL Server is not configured to listen to any of your IP Interface.
Maybe it is just listening into your "localhost:3306"
Check it in your MySQL Server config file "bind-address".

Set Port number when using FtpWebRequest in C#

I keep getting a exception when I try to FTP to my Win 2008 Server from C# code using VS2008 as debugger.
My test class looks like this:
public class FTP
{
private string ftpServerIP = "192.168.10.35:21";
private string ftpUserID = "Administrator";
private string ftpPassword = "XXXXXXXX";
private string uploadToFolder = "uploadtest";
public void Upload(string filename)
{
FileInfo fileInf = new FileInfo(filename);
string uri = "ftp://" + ftpServerIP + "/" + uploadToFolder + "/" + fileInf.Name;
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
reqFTP.Credentials = new NetworkCredential(ftpUserID, ftpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
reqFTP.UseBinary = true;
reqFTP.ContentLength = fileInf.Length;
int buffLength = 2048;
byte[] buff = new byte[buffLength];
int contentLen;
FileStream fs = fileInf.OpenRead();
try
{
Stream strm = reqFTP.GetRequestStream();
contentLen = fs.Read(buff, 0, buffLength);
while (contentLen != 0)
{
strm.Write(buff, 0, contentLen);
contentLen = fs.Read(buff, 0, buffLength);
}
strm.Close();
fs.Close();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
When I execute the code I get a Connection Failed with FTP error 227 in the GetRequestStream() call.
In the exception I can see the connection fails to: 192.168.10.35:52184
I have no idea how it comes up with port 52184.
I specify in the ftpServerIP that it should be port 21.
I have found a few persons with the same issues on google but I haven't found a good example on how this is solved and I still don't understand why it happens.
Anyone know how to handle this issue??
UPDATE:
I have tried to connect to a different FTP account and there it all works fine. Therefore I tested my 192.168.10.35:21 FTP but it works fine in CuteFTP Pro and the likes.
This just makes it even more strange..
My guess would be Windows firewall issues, FTP uses other ports than just port 21 - sometimes changing the FTP mode from active to passive helps to get things working.
reqFTP.UsePassive = false;
Look at this good article on FTP: Active FTP vs. Passive FTP, a Definitive Explanation
Thies got it right, it had to do with passive mode
The fix in the code is so insanely simple :)
reqFTP.UsePassive = false;
And it worked fast and without errors!
It is important to differentiate the COMMAND port and the DATA port. The connection protocol will also change depending if you are in ACTIVE or PASSIVE mode.
ACTIVE MODE :
1) The client initiate a connection from a random unspecified COMMAND port (N > 1023) to the default server COMMAND port (21). The client will specify his DATA port (N+1) and start listening on this port.
2) The server initiate a connection from his default DATA port (20) to specified client DATA port (N+1).
PASSIVE MODE :
1) The client initiate a connection from a random unspecified COMMAND port (N > 1023) to the default server COMMAND port (21) with the PASSIVE command. The server open a random DATA port (P > 1023) and send it to the client.
2) The client initiate a connection from his DATA port (N+1) to the specified server DATA port (P > 1023).
If you use ACTIVE mode, you will most likely need to let your client's firewall accept the connection from the server to your port (N+1 > 1024).
In your example, you were in ACTIVE mode. Your client initiated a connection from his COMMAND port (52183) to the server's default COMMAND port (21) and specified its DATA port (52184 = 52183 + 1). Then the server initiated a connection from its default DATA port (20) to the client's DATA port (52184) which was most likely rejected by the client's firewall.
I hope this helps you solve your problem!

Categories