I want to perform file copying from local HDD to a server
- to access the server it require to insert username and password,
at manual when I write the server name: \neoserver a window popup and after inserting username and password all the server's file appeared.
to perform the copying I use the command: File.copy(source path, destination path)
how can I write the server's path in a way it won't require user#pass???
You can use Process.Start to call the copy command line executable with the right credentials and parameters.
For best control, use ProcessStartInfo to supply all the information needed:
ProcessStartInfo startInfo = new ProcessStartInfo("copy");
startInfo.Arguments = "source dest";
startInfo.UserName = myUser;
startInfo.Password = myPassword;
Process.Start(startInfo);
Related
I need to write a file while impersonated as another user John (Member of administrator).
What happens:
File is written and created, then all Access Control is removed and added (Full Control).
No matter where in this process i try to Encrypt file access is denied
using FileOptions
Using File.Encrypt.
my worked around to at least encrypt was with opening another impersonation later on.
But No matter what i do, i can't Decrypt or even read the encrypted Text file.
If file is encrypted reading or decrypting fails, even though i can read or write just fine while impersonated.
In some scenarios Everything works fine, But after a system restart or logout, again fails with access denied.
For impersonation i used this answers Impersonation
using (impersonate = new ImpersonateUser(ImpersonationType.WinIdentity, Domain, User, SecurePassword))
{
System.Diagnostics.Debug.WriteLine($"Before Impersonation: {Environment.UserName}");
done = impersonate.RunImpersonated(() =>
{
System.Diagnostics.Debug.WriteLine($"After Impersonation: {Environment.UserName}");
//if (Util.IsWindowsEncrypted(ConfigFullPath)) File.Decrypt(ConfigFullPath);
var json = File.ReadAllText(ConfigFullPath);
var configFile_data = SerializationUtil.Deserialize<Config>(json);
//if (!Util.IsWindowsEncrypted(ConfigFullPath)) File.Encrypt(ConfigFullPath);
});
}
A working repository to reproduce is available here Repository containing full sample,
See CreateConfig or ReadConfig method in Config.cs
(if you were able to create and read a encrypted file, check if after
restart it is the same)
A Workaround i just found was to create a Process before doing any impersonation.
using (Process cmd = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c",
UseShellExecute = false,
UserName = user,
Password = pass,
LoadUserProfile = true
};
cmd.StartInfo = startInfo;
cmd.Start();
}
I would like to check if State is DISABLED or ENABLED.
I opened the file D:\TOOLS\Security.bat and run it.
In addition i must insert password in CMD to continue program
and I want to C# write that password. Is that possible?
How can I insert password into open process in CMD?
The file must be opened with D:\TOOLS\Security.bat
Process process = new Process();
process.StartInfo.FileName = "D:\\TOOLS\\Security.bat";
process.StartInfo.CreateNoWindow = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
process.StandardInput.WriteLine("password");
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
Console.WriteLine(process.StandardOutput.ReadToEnd());
Here is Security.bat file:
runas /user:Administrator c:\utility\info.bat
cls
Here is info.bat file:
ewfmgr c:
pause
When I write password in CMD I got that data.
From that data I would like to get State value.
But I don not know how to save this console data to string.
How can I get all data from last console call?
Here is my code for get state data.
string check= #"State(.)*DISABLED";
if (Regex.IsMatch(output, check)) {
// SECURE IS OFF
}
Thanks for help.
No, it's not possible to insert the password into the command prompt. it's specifically designed to prevent that.
What you CAN do is save the password in the credential cache on that particular machine. You do this with the runas command by using the /savecred switch. After you enter your password, it will no longer ask for it when you runas this app as that user.
when i run copy command in my c# code it produce no error or exception because it is not finding the parts path i do not know how to give full directory path or path of every part which i am joining.actually i am merging file parts to a single file using coy/b by using this code...
string strCmdText;
strCmdText = "/C copy/b test.txt.10485760.0000.part" +
"test.txt.10485760.0001.part" +
"test.txt.10485760.0002.part" +
"test.txt.10485760.0003.part" +
"test.txt.10485760.0004.part" +
"test.txt.10485760.0005.part test.txt";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
You can specify the path of your files as the working path of the process. For example:
var startInfo = new System.Diagnostics.ProcessStartInfo
{
WorkingDirectory = #"THE\PATH\OF\FILES",
WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal,
FileName = "cmd.exe",
Arguments = "YOUR COMAND HERE";
};
Process process = Process.Start(startInfo);
For your command, note that you can copy all files into one using a wildcard for the parts:
copy *.part test.txt
/b is for binary data, so i think is not needed in your case.
You can also set other properties for a process, for more info check the doc: ProcessStartInfo.
For such a complex task, I would use the process as a bash rather then just an execution tool.
Create a Process
Redirect it's streams (Input, Output)
With a StreamReader and StreamWriter u can now access the cmd
Now just control it the way u need it, like setting the working directory to the path and do ur command.
If this is not what u want, u can allways set the working directory on the ProcessStartInfor -> Link
Process myProcess = new Process();
ProcessStartInfo remoteAdmin =
new ProcessStartInfo(Environment.GetFolderPath(Environment.SpecialFolder.System) + #"\iisreset.exe /restart");
remoteAdmin.UserName = username;
remoteAdmin.Password = pwd;
remoteAdmin.Domain = domain;
myProcess.StartInfo = remoteAdmin;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.Start(); --- ERROR HERE
Can not find the file specified.
But when I try to run iisreset on the local machine by cmd it's working.
Unless I'm missing something, (Environment.GetFolderPath(Environment.SpecialFolder.System) will get back the local machine (Where the code is running) special folder. So it's expecting the file C:\Windows\System\iisreset.exe to be located on your machine. The only method I could see to get around this, is to drop the C:\ and instead add in the device's name \\DeviceName\C$\ and then the filepath. This is assuming the special folder system is located in the same place on your machine and the remote machine.
The only other method, to get the remote machines system directory is to get it via WMI or via a reg entry reading.
So if using WMI:
"SELECT * FROM Win32_OperatingSystem"
Once done, you would then need to build the folder string yourself from that.
There is no file called C:\Windows\System\iisreset.exe /restart (assuming that Environment.GetFolderPath(Environment.SpecialFolder.System) returns C:\Windows\System\
So you would want
ProcessStartInfo remoteAdmin =
new ProcessStartInfo(Environment.GetFolderPath(Environment.SpecialFolder.System) + "iisreset.exe");
remoteAdmin.Arguments = "/restart";
But Environment.GetFolderPath(Environment.SpecialFolder.System) probably returns something like C:\Windows\System (note no trailing slash), and there is definitely no file called c:\windows\systemiisreset.exe
So you would actually want
ProcessStartInfo remoteAdmin =
new ProcessStartInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "iisreset.exe"));
remoteAdmin.Arguments = "/restart";
iisreset.exe supports remote calls, so instead of using WMI to get remote directory you can actually just do:
iisreset {servername}
I have to start a command line program with System.Diagnostics.Process.Start() and run it as Administrator.
This action will also be run by a Scheduled Task every day.
I've just try to use :
Process p = new Process();
p.StartInfo.Verb = "runas";
this works fine if I'm running my program as Administrator, but when the Scheduled Task runs it, it doesn't take the 'runas' in consideration I think.
A better secure option to run a process with login and password is use the SecureString class to encrypt the password. Here a sample of code:
string pass = "yourpass";
string name ="login";
SecureString str;
ProcessStartInfo startInfo = new ProcessStartInfo();
char[] chArray = pass.ToCharArray();
fixed (char* chRef = chArray)
{
str = new SecureString(chRef, chArray.Length);
}
startInfo.Password = str;
startInfo.UserName = name;
Process.Start(startInfo);
You must allow unsafe code in your project properties.
Hope this help.
If you are using scheduled tasks, you can set the user and password for the task to run under.
Use the administrator credentials on the task and you will be fine.
With Process.Start, you need to supply the UserName and Password for the ProcessStartInfo:
Process p = new Process("pathto.exe");
p.StartInfo.UserName = "Administrator";
p.StartInfo.Password = "password";
p.Start();
Be aware that storing a password in clear text in a program is never secure as long as someone can peruse the application and see what is in it. Using SecureString to convert a stored password into a SecureString password does not make it more secure, because the clear text password would still be present.
The best way to use SecureString is to pass a single character for conversion at a time in someway that does not require having the complete unencrypted password anywhere in memory or on the hard drive. After that character is converted, the program should forget it, and then go on to the next.
This could be done I think only by passing characters through for translation as they are being typed into the console by the user.
I found it, I need to set the Scheduled Task to run the application with highest privileges in General settings.