Running a windows command in a wcf rest service - wcf

I have a wcf rest service running the code below:
string command = #"C:\Test.exe";
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
Logger.Write(string.Format("1"), LogType.Error);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
Logger.Write(string.Format("2"), LogType.Error);
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
Logger.Write(string.Format("3"), LogType.Error);
proc.Start();
Logger.Write(string.Format("4"), LogType.Error);
string result = proc.StandardOutput.ReadToEnd();
Logger.Write(string.Format("5"), LogType.Error);
// Display the command output.
Logger.Write(string.Format("Plugin : {0} has started", result), LogType.Error);
It works fine in my development machine. When I publish the service to server, the problem occurs. The latest log in my log file is written by:
Logger.Write(string.Format("4"), LogType.Error);
I think it's a security / permission issue. What can I do to run my code without problem in server too.
Thanks in advance,

Related

SmtpClient send email error "Mailbox unavailable. The server response was: 5.7.1 Client does not have permissions to send as this sender"

I am trying to use SmtpClient send emails in my asp.net core application.
This is the code below:
SmtpClient client = new SmtpClient(_configuration["mail.firm.com"]);
client.UseDefaultCredentials = false;
//client.UseDefaultCredentials = true;
//client.Credentials = new System.Net.NetworkCredential("mydomain\\myadminaccount", "11223344");
MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress(_configuration["noreply#firm.com"]);
// Set email subject, body, to address logic
// ......
// End
try {
client.Send(mailMessage);
return true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
return false;
I found that:
1.On my local machine, debugging mode, running VS as Admin account, it works fine.
2.On my local machine, debugging mode, if I specify credentials, it does not work. give the 5.7.1 error message in exception message.
3.On the test server, debugging mode, running VS as Admin account, it works fine.
4.on the test server, deployed to IIS, IIS pool running as the same Admin account as VS, it does not work.
Can anyone see anything I did wrong or if I am missing anything?

Get AD Users Visual Studio Web App versus Console

I have the following code below.
When I run Debug in Visual Studio with this code in an ASP.NET Core App (so running as IIS Express) this works
When I run Debug in Visual Studio with this code in a ASP.NET hosted process in a Windows Service this return nothing, but also no error messages
I connect from my home laptop via RDP to another laptop where VPN is running, so I think that is probably it. I tried running visual studio as admin, running the compiled exe as admin, /runas with the domain specified, etc but the commandline app will show nothing while the asp.net core app shows the list. So it must be the user it runs under.
But when i run WindowsIdentity.GetCurrent().Name in both cases it gives the same domain and name (me). In task manager the devenv and iis process is me.
public List<AdSecurityGroupDTO> GetAllDomainSecurityGroups(string domain)
{
List<AdSecurityGroupDTO> result = new List<AdSecurityGroupDTO>();
using (var ctx = new PrincipalContext(ContextType.Domain, domain))
{
GroupPrincipal findAllGroups = new GroupPrincipal(ctx, " * ");
PrincipalSearcher ps = new PrincipalSearcher(findAllGroups);
foreach (Principal group in ps.FindAll())
{
AdSecurityGroupDTO adSecurityGroupDTO = new();
adSecurityGroupDTO.Name = group.Name;
adSecurityGroupDTO.Description = group.Description;
adSecurityGroupDTO.DisplayName = group.DisplayName;
adSecurityGroupDTO.DistinguishedName = group.DistinguishedName;
adSecurityGroupDTO.SamAccountName = group.SamAccountName;
result.Add(adSecurityGroupDTO);
}
return result;
}
}

WebSockets not working when application is built

I have got to ASP.NET-Core 2.0 apps communicating via WebSockets.
App A is Server.
Application A is running on a remote server with Ubuntu.
App B is Client
Application B is running on a PC setup in my office.
When I test my applications locally in Debug everything works fine. Client connects to the server and they can exchange information.
However, when I build my Server app, Client can connect to it but when server tries to send a message to the client the message is not received by the client.
public async Task<RecievedResult> RecieveAsync(CancellationToken cancellationToken)
{
RecievedResult endResult;
var buffer = new byte[Connection.ReceiveChunkSize];
WebSocketReceiveResult result;
MemoryStream memoryStream = new MemoryStream();
do
{
if (cancellationToken.IsCancellationRequested)
{
throw new TaskCanceledException();
}
Console.WriteLine("Server Invoke");
// result never finishes when application is build. On debug it finishes and method returns the correct result
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);
if (result.MessageType == WebSocketMessageType.Close)
{
await CloseAsync(cancellationToken);
endResult = new RecievedResult(null, true);
return endResult;
}
memoryStream.Write(buffer, 0, result.Count);
} while (!result.EndOfMessage);
endResult = new RecievedResult(memoryStream, false);
return endResult;
}
This is the part of code where everything hangs.
What I tried was:
Build Server - Build Client => not working
Build Server - Debug Client => not working
Debug Server - Debug Client => working
I need any advice what might be wrong here and where I should look for issues.
Console if free of errors. Everything hangs on:
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancellationToken);

Deploying a WCF service on a remote pc

I have a WCF web service, which I have hosted in IIS on my PC. This I have added as Service Reference in a Visual Studio Project and I am able to invoke it successfully in a web service in this VS Project.
Now I am trying to deploy this web services on a remote PC, which doesn't have Visual Studio installed. For this purpose I copied the .svc and web.config files and bin folder of this web services to a folder on the remote PC. Then I hosted the services on IIS pointing to the respective folder. Now when I browse the web service using the .svc link I am able to access the web service from my PC. I added this web service as a service reference in my Visual Studio project and everything looks OK, I am able to see the separate methods and their parameters in the Object browser. The problem appears when I try to invoke methods from this web services.
I am able to invoke one method and then when I invoke the second one I get the following error (The absolutely same web service and all its methods work perfectly if hosted in IIS on my PC.):
Object reference not set to an instance of an object.
Here is a part of the method where I invoke the web service (the web service name is TFSWS):
public void ImportRequirements(string username, string password)
{
TFSWS.TFSWSClient obj = new TFSWS.TFSWSClient();
string projects = obj.GetTFSProjects(username, password, TFS_URI);
string list = obj.GetAllWorkItems(ProjectName2, username, password, TFS_URI, WItypes);
Here is the code of the first method which I am able to invoke successfully from TFSWS:
public string GetTFSProjects(string userName, string password, string Uri)
{
StringWriter MyStringWriter = new StringWriter();
NetworkCredential cred = new NetworkCredential(userName, password);
TfsTeamProjectCollection _tfs = new TfsTeamProjectCollection(new Uri(Uri), cred);
_tfs.Authenticate();
ICommonStructureService tfsProjectService = (ICommonStructureService)_tfs.GetService(typeof(ICommonStructureService));
ProjectInfo[] projects = tfsProjectService.ListAllProjects();
string[] proj = new string[projects.Length];
for (int i = 0; i < projects.Length; i++)
{
proj[i] = projects[i].ToString();
}
DataTable ProjectsDT = GetDataTableFromArray(proj);
...
}
Here is the code of the second method that I invoke from TFSWS and that throws the error message (When I debug I can see that all parameters are assigned correctly):
public string GetAllWorkItems(string projectName, string username, string password, string URI, string[] WItypes)
{
StringWriter MyStringWriter = new StringWriter();
NetworkCredential cred = new NetworkCredential(username, password);
TfsTeamProjectCollection _tfs = new TfsTeamProjectCollection(new Uri(URI), cred);
_tfs.Authenticate();
WorkItemStore _witStore =(WorkItemStore)_tfs.GetService(typeof(WorkItemStore));
DataTable myData = new DataTable();
string project = projectName;
string[] m_columns;
Hashtable context = new Hashtable();
Project proj = _witStore.Projects[project];
}
string myQuery = "SELECT [System.Id], [System.Title], [System.WorkItemType], [System.State] FROM WorkItems WHERE ...";
WorkItemCollection result = _witStore.Query(myQuery, context);
DisplayFieldList fieldList = result.Query.DisplayFieldList;
...
}
You can debug remotely to figure out the issue the code is experiencing on the target machine, without installing all of Visual Studio on it. You just need to deploy debug instead of release mode assemblies, and have the remote debugger service running on it.
Remote Debugging Setup

WCF selfhosted service, installer class and netsh

I have a selfhosted WCF service application which I want to deploy by a msi installer package. The endpoint uses http port 8888. In order to startup the project under windows 2008 after installation I have to either run the program as administrator or have to edit the http settings with netsh:
"netsh http add urlacl url=http://+:8888/ user=\Everyone"
I want to edit the http settings from my installer class. Therefore I call the following method from the Install() method:
public void ModifyHttpSettings()
{
string parameter = #"http add urlacl url=http://+:8888/ user=\Everyone";
System.Diagnostics.ProcessStartInfo psi =
new System.Diagnostics.ProcessStartInfo("netsh", parameter);
psi.Verb = "runas";
psi.RedirectStandardOutput = false;
psi.CreateNoWindow = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process.Start(psi);
}
This method will work for english versions of windows, but not for localized versions (The group Everyone has different names in localized versions). I have also tried to use Environment.UserName to allow access at least for the current logged on user. But this does also not work, because the installer class is run by the msi service which runs under the user SYSTEM. Hence Enviroment.UserName returns SYSTEM and that is not what I want. Is there a way to grant access to all (or at least for the current logged on) user to my selfhosted WCF service from a msi installer class?
My aproach to a solution:
public void ModifyHttpSettings()
{
string everyone = new System.Security.Principal.SecurityIdentifier(
"S-1-1-0").Translate(typeof(System.Security.Principal.NTAccount)).ToString();
string parameter = #"http add urlacl url=http://+:8888/ user=\" + everyone;
ProcessStartInfo psi = new ProcessStartInfo("netsh", parameter);
psi.Verb = "runas";
psi.RedirectStandardOutput = false;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
Process.Start(psi);
}
The SID "S-1-1-0" is a wellknown SID and stands for the "Everyone" account. The SID is the same for all localizations of windows. The method Translate of SecurityIdentifier class returns the localized name of the Everyone account.