Java Compiler ASP.NET - c#

I'm trying to make an online compiler for java using ASP.NET C#
Process p=new Process();
p.StartInfo.FileName = "C:\\Program files\\Java\\bin\\javac.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = "C:\\Hello.java";
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardOutput.ReadToEnd();
p.WaitForExit();
I run javac.exe to compile Hello.java, but the process isn't allowed by ASP.NET to write Hello.class to disk
But on doing it manually through cmd.exe without using ASP.NET or progmatically using C# only it runs perfectly
Can you help me make an online java compiler using ASP.NET or PHP for compiling Algorithmic assignments?

This is a permissions problem - you have two options:
Change the application pool identity to an account that has write permissions
Give write permissions to the current application pool identity account

you should configure the access rights for the ASPNET user, this changes a bit depending on which version of IIS and Windows Server the web application runs.
Consider to store the output data locally on the server's disk on a proper location, not directly C or any system folder. let's say C:\JavaOutput\ then give read/write permissions to the ASPNET user to that folder.

This is a permission problem. You need to allow full permissions to c:\ for the ASP.NET USER\IISUSER. That's obviously a WRONG approach.
Your working directory should be the directory in which your web application sits.

Where on the disk does the compiler try to store Hello.class? Chances are, it's in a folder where the ASP.NET process has no permissions to write.
Some tips:
1) Find out what permissions the ASP.NET worker process has. If using IIS, check out the identity of the ApplicationPool it's running under. Chances are it's running under a limited profile.
2) Find a folder where the ASP.NET worker process can write to. This should probably be in a directory under the application root (~), or in some TEMP folder.
3) Check if the javac command-line allows you to specify an explicit output directory. If not, use p.StartInfo.WorkingDirectory to specify a working folder for the process, which will probably make javac output to the specified folder.

Related

Process on ASP.Net server not running correctly over IIS

I am trying to run an antivirus scan on an uploaded file in an ASP.Net web app. We are using Sophos so have access to their command line API sav32cli. In the code I use:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = #"-remove -nc " + SavedFile;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;
When stepping through the code, when attached to the w3wp process on dev server, the code just jumps from one line to the next seemingly doing nothing at all. When running from code on dev server, it performs as expected scanning file and deleting if it is seen as a virus.
The server is running IIS 8.0, and the app built in .Net Framework 4. I have changed the machine config to allow the process to run as SYSTEM account, in accordance to these instructions. https://support.microsoft.com/en-us/kb/317012#%2Fen-us%2Fkb%2F317012
<processModel userName="SYSTEM" password="AutoGenerate" />
Is there something I'm missing? What is the best practice for this kind of implementation?
EDIT: When called, the Process returns an ExitCode of 2 (Error stopped execution), rather than the expected 0 (Scan worked, no viruses), or 3 (Scan worked, viruses found).
EDIT 2: As per comment below I changed the code to:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe";
proc.StartInfo.Arguments = #"-remove -nc " + SavedFile;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
StringBuilder output = new StringBuilder();
while (!proc.StandardOutput.EndOfStream)
{
string line = proc.StandardOutput.ReadLine();
output.AppendLine(line);
}
proc.WaitForExit();
int exitCode = proc.ExitCode;
ASPxMemo2.Text = exitCode.ToString() + Environment.NewLine + output.ToString();
output is always empty when run over IIS, but is populated correctly when running from code.
EDIT 3: Instead of looking at StandardOutput we looked at StandardError and it revealed this error:
Error initialising detection engine [0xa0040200]
(Possible insufficient user Admin rights.)
For the time being we are going to move to another method of virus checking, but would still like to know a possible solution if anyone has it.
You will need to make sure that the application pool that is running your .NET application inside IIS has execute permissions to your file
"C:\Program Files (x86)\Sophos\Sophos Anti-Virus\sav32cli.exe"
You may also need to add this permission to the folder location where the file to be scanned is uploaded (c:\temp) for example
You may also need to have administrator privileges to run the anti virus scan since IIS8 does not run as an administrator. When you are debugging visual studio uses your current logged in windows user(unless you use runas) so this will explain why it would work when debugging.
Have you tried running your web process in elevated trust?
Configuring .NET Trust Levels in IIS 7
<system.web>
<securityPolicy>
<trustLevel name="Full" policyFile="internal"/>
</securityPolicy>
</system.web>
ASP.NET Trust Levels and Policy Files
Most likely the permissions are not configured correctly on the content being scanned (the uploads folder) or the worker process user doesn't have the full permissions it needs to use Sophos. You know the executable itself is accessible by the worker process because you are getting exit codes and error messages that are specific to Sophos.
Because your process will delete files that are perceived as threats you need to grant the user running the process modify or full control permissions on the folders that store the uploaded files.
By default you could use the IIS_IUSRS group for ApplicationPoolIdentity processes, but you can verify (and modify) the user in IIS Manager > App Pools > Advanced.
This answer has more details
Here are some ideas:
Create the process using a different user with elevated privileges on the folder, see for reference start-a-net-process-as-a-different-user
If the previous suggestion fails, login one time on the server using the credentials used in point 1. It will configure registry entries connected to the user profile, some programs requires it.
Develop a simple .net service running on the server and monitoring the upload folder. The service has more probability running the Sophos scan succesfully. Here is a reference on service creation using .net.
The service may also talk to your web page using DB/file system/ etc.. so the operation may seem synchronous.
These are my 4 cents :-)

exe file is unable to create txt file from IIS

I have created an WebApi project in which I am calling a exe namely Latlong2XY.exe which takes input file and outputfile as paramreter. And returning me a .txt as output file. When I am executing the application from VS2012 IDE it is successfully creating the required txt file. However when I publish the same application in IIS and running it then it is not able to create the txt file.
it appears IIS Express is creating the txt file while IIS is not.
It appears to be some permission issue. But does not have any clue what to do.
My code is:
int exitCode;
// Prepare the process to run
ProcessStartInfo start = new ProcessStartInfo();
// Enter in the command line arguments, everything you would enter after the executable name itself
start.Arguments = #"D:\RFD\InputFile.txt D:\RFD\Results.txt";
// Enter the executable to run, including the complete path
start.FileName = #"D:\RFD\Latlong2XY.exe";
// Do you want to show a console window?
start.WindowStyle = ProcessWindowStyle.Hidden;
start.CreateNoWindow = true;
// Run the external process & wait for it to finish
using (Process proc = Process.Start(start))
{
proc.WaitForExit();
// Retrieve the app's exit code
exitCode = proc.ExitCode;
}
IIS settings are :
Windows Authentication: disabled;
Forms Authentication: disabled;
Anon auth: enabled;
.Net Impersonation: disabled.
i'm using ASP.NET v4.0 Application pool.
You will need to give the application directory (where the hosted files are on the machine) elevated privileges. (Typically C:\inetpub\wwwroot\YourAppName)
Give the user 'IIS_USR' or something close to that name write access to the folder.
Yes., When you perform these kind of operations from "Visual Studio IDE" It will work because IDE has minimum permission to control your IO operations for (System.Diagnostics.Process.Start).
When you go to Web application hosting from IIS, unfortunately IIS doesn't have these permission settings in built. So you need to set permissions to perform windows native operations.
Note : By using this you are gonna provide your system(server) username and password as encrypted.
You can set windows authentication permission in the Web Config Using Aspnet_setreg.exe. Which will be available in internet with usage notes.
Add the below line in your webconfig:
<authentication mode="Windows"/>
<identity impersonate ="true" userName="registry:HKLM\SOFTWARE\YourAPPName\ASPNET_SETREG,userName" password="registry:HKLM\SOFTWARE\YOURAPPNAME\ASPNET_SETREG,password"/>
The similar problem i have faced during development of "windows service Re-Start from web". The Same permission issues i have resolved and got worked on this way.
This answer may not be perfect. But this is also one way to achieve the solution

run shell command (manage-bde) as administrator from C#

I need to run "manage-bde" shell command from C# code.
The main application process is already running as administrator and is Elevated.
I used code from : UAC self-elevation example on MS website for confirming the app process is elevated.
(http://code.msdn.microsoft.com/windowsdesktop/CSUACSelfElevation-644673d3)
However, when I try to run manage-bde from the C# code, I get "System can't find file specified".
Process p = new Process();
p.StartInfo.FileName = "C:\\Windows\\System32\\manage-bde.exe";
p.StartInfo.UseShellExecute = true;
p.Start();
As a workaround, I tried to create a batch file that runs the command.
string batchFileName = DateTime.Now.Ticks + ".bat";
StreamWriter writer = new StreamWriter(batchFileName);
writer.WriteLine("manage-bde");
writer.Flush();
writer.Close();
Process p = new Process();
p.StartInfo.FileName = batchFileName;
p.StartInfo.UseShellExecute = true;
p.Start();
The batch file is written , and executed successfully; However, the command "manage-bde" is not recognized.
I changed the code to use the verb "runas" and use admin password and that works, but I want the batch file to work without the need for providing the admin password. The current logged in user is already administrator on the computer but the batch file is not getting executed with the existing admin privileges . I need the batch file to execute and manage-bde to run successfully.
Your help or advice will be very highly appreciated :)
ps: some commands other than manage-bde work fine without need for admin runas.
The reason of the behavior I encountered was the Windows File System Redirector.
In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64
https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx
My application build was 32 bits. Whenever it tried to access System32 windows automatically redirected it to SysWow64 which does not contain "manage-bde.exe". I changed the build to 64 bits and then the application could access manage-bde.exe from System32
Even if you're running as the Administrator user, you're not fully elevated if UAC is running. Meaning that you'll have either the UAC prompt come up or you'll be prompted for a password.
The only real way you could get around that is to run your application elevated first, or to write a service that runs with elevated permissions to start your new process.
The alternative of course is to disable UAC, but that is undesirable in most situations.

Executing batch file from C# Permission issue

I have a batch file to execute a VB script. While executing the batch file by double clicking will work, But when I have done the same with C# its working on my local environment but not in the staging server (windows server 2008r2), Is there any permission level i need to apply for this execution. From the staging server I can double click and execute the batch file...
I have logged in to the server with Administrator account and browsed the application as localhost.
Is there anything I'm missing on the execution of batch file from C#,
I don't think there is any problem with my C# code as its working fine on my local environment, anyway following is my C# code,
if (File.Exists(FileName*))
{
System.Diagnostics.ProcessStartInfo p = new System.Diagnostics.ProcessStartInfo(FileName);
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = FileName;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
}
else
{
lblMsg.Text = "Sorry unable to process you request";
}
*FileName is the path to batch file. Also I have set full permission to the folders that containg both batch file and vbs files.
For this to work your app pool needs to be run as a user who has access to the batch file.
Check how to change your app pool identity for IIS 7 or IIS 6.
To expand on what Kartheek said:
In IIS 7 application pools run as a app pool account, IISAPPPOOL\AppPoolName
In IIS 6 application pools run as Network Service
In either case, these accounts don't have any access a user's documents folder and (by default) can only read from common data stores.
Generally you want to keep the app pool account because it helps segregate the data -- so what I would do is just make sure you grant read+execute permissions on the bat file you need for the app pool account. You'll also need proper permissions on any filles/folders the bat needs to read/write from.
You do not need to change anything in your app to correct this problem, unless you want to IIS app to masquerade around as the user who is actually sitting at the website (it only really works if you use some form of authentication.) Generally this a bad idea anyway -- so it's best to just adjust the permissions.
As a general rule of thumb, when working on a web server you want to keep the permissions/execution levels as low/restrictive as possible.

Why can't my ASP.NET web service kick off a process, but my .NET console app can?

This is code from a class library:
proc.StartInfo = new ProcessStartInfo(CmdPath, "+an -b");
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
This works perfectly as I would expect when called from a console test app. When I take the same library and call the method from an ASP .NET web service it just hangs.
Is there something I am missing here, perhaps permissions? The ASPNET service has access to the folder where the EXE is, and I see it running in Task Manager, though it isn't doing anything.
If anyone could tell me what I'm doing wrong, I would appreciate it. Thanks.
EDIT: Sorry for the lack of information. CmdPath goes to the command line interface for our scheduling software. I'm passing in commands based on the documentation they provided. I have one method to get a list of jobs, and another method to run a job. ...hmm idea. The client normally uses Active Directory to login, I think impersonation is going to be necessary. Going to test now.
EDIT 2: Ok, now the client is blowing up with AccessViolation issues. This is obviously a permissions thing. If the software uses integrated AD authorization, and I impersonate my AD account, will that be sufficient? I'm doing impersonation using the tag in web.config.
I think you will face a lot of problems launching an executable server side using the ASPNET identity, have you tried impersonating an identity with appropriate priveleges (this does work btw), but again launching an executable on the server side is probably not a good idea to begin with.
The ASP.Net user account probably doesn't have permissions to execute. Can you give a bit more information as to why you are trying to do this as there may be a better way of doing it.
It could be a permissions issue. The ASPNET service may have permissions to the executable, but does it have permissions for everything the executable does.
For example, if the executable copies files, does the ASPNET account have full rights to the source and destination paths of those files? The same questions need to be asked of everything the executable does.
If you need to get around this, you can use impersonation, or assign the web site to run under a different account in IIS, but those are not recommended practices, and more trouble than they're worth in most cases.
By default the ASP.NET worker process has less security than most local account (certainly an account that a developer uses or the logged in account on a server.)
There are two main ways to move forward:
Give the asp.net process more priviledges. See This Link for a good explanation of how to do that.
Have asp.net run under an account with more priviledges. See This Link for a good explanation and how to get that process running under a different account.
Either will work for you.
When you redirect standard output don't you need to use ReadToEnd to read the response from StandardOutput?
You probably should check what is your executable performs, cos ASP.NET works under user with limited rights (NETWORK SERVICE on IIS 6.0) and you executable also gets this rights and runs under same user. As far as you waiting on until it finishes its work, probably something wrong in the executable you are trying to run. I suggest you to make a simple experiment - switch your WebApplication to build-in in VS web server, called "Casini" and check your code behavior. By means of this you can prove yourself that it's not ASP.NET's fault. If I am right the only thing you will need to do is to investigate problems of you executable and determine what rights it needs.
Instead of Impersonation or giving Asp.net more privileges, how about launching the process under different credentials.
In the sample below, UserWithVeryLimitedRights would be a new account that you create with just enought rights to run the app.
Doing so may minimize the security risks.
ProcessStartInfo StartInfo = new ProcessStartInfo();
SecureString ss = new SecureString();
string insecurePassword = "SomePassword";
foreach(char passChar in insecurePassword.ToCharArray()) {
ss.AppendChar(passChar);
}
StartInfo.RedirectStandardInput = true;
StartInfo.RedirectStandardError = true;
StartInfo.RedirectStandardOutput = true;
StartInfo.CreateNoWindow = true;
StartInfo.UseShellExecute = false;
StartInfo.Password = ss;
StartInfo.UserName = #"UserWithVeryLimitedRights";
StartInfo.FileName = #"c:\winnt\notepad.exe";
Process.Start(StartInfo);

Categories