RabbitMQ C# connection trouble when using a username and password - c#

I am at a loss here so I'm reaching out to the collective knowledge in hope of a miracle.
I have installed RabbitMQ on a Linux box using the defaults.
When I use this code (and the default RabbitMQ installation configuration) everything works nice.
var connectionFactory = new ConnectionFactory();
connectionFactory.HostName = "192.168.0.12";
IConnection connection = connectionFactory.CreateConnection();
But when I add a user to RabbitMQ and try to use the following code (username and password has been changed to protect the innocent. :) )
var connectionFactory = new ConnectionFactory();
connectionFactory.HostName = "192.168.0.12";
connectionFactory.UserName = "user";
connectionFactory.Password = "password";
IConnection connection = connectionFactory.CreateConnection();
the connectionFactory.CreateConnection() method throws the following exception:
BrokerUnreachableException
None of the specified endpoints were reachable
Checking the RabbitMQ logfile I can see it complaining about the credentials:
{amqp_error,access_refused,
"PLAIN login refused: user 'user' - invalid credentials",
'connection.start_ok'}}
The thing is that I am confident about the username and password and I cannot for the love of coding find a solution to this anywhere.
I must be missing something obvious but I can't figure out what it is.
I would be grateful for any helpful pointers.

It seems that I have found a solution to my own problem.
The following code works:
ConnectionFactory factory = new ConnectionFactory();
factory.UserName = "user";
factory.Password = "password";
factory.VirtualHost = "/";
factory.Protocol = Protocols.FromEnvironment();
factory.HostName = "192.168.0.12";
factory.Port = AmqpTcpEndpoint.UseDefaultPort;
IConnection conn = factory.CreateConnection();
Thanks for listening and perhaps this at least could be useful to someone else. :)

Here is how to create a user called agent with password agent, set it to be administrator and give it read and write access to all queues in the vhost /
rabbitmqctl add_user agent agent
rabbitmqctl set_user_tags agent administrator
rabbitmqctl set_permissions -p / agent ".*" ".*" ".*"

The accepted answer didn't work for me (on Windows).
I had to install the management tools:
rabbitmq-plugins enable rabbitmq_management
N.B. rabbitmq-plugins is in C:\Program Files (x86)\RabbitMQ Server\rabbitmq_server-3.3.1\sbin
Then, restart the RabbitMQ service.
I then installed EasyNetQ in Visual Studio in the package manager:
install-package easynetq
With this installed, I could use the admin web site located at:
http://localhost:15672
N.B. The default username and password is: guest
From here, I selected the Admin tab and the cause was clearly displayed in yellow at the top of the screen:
This user does not have permission to access any virtual hosts.
Use "Set Permission" below to grant permission to access virtual hosts.
To fix the issue I just pressed the Set permission button on the same screen et voila
N.B. for this to have worked you need to have added the user using rabbitmqctl add_user username password or similar (rabbitmqctl is also in the directory above).

Related

WinSCP SFTP connection error

While accessing my remote server, from SFTP, I am constantly getting this error
Connection has been unexpectedly closed. Server sent command exit status 0
I have filled same credentials in WinSCP, it is working fine. Where am I lacking?
Also, instead of .ppk file I am using "ssh-rsa 1024 #######################" in my keyfile column in my project's UI.
Thank You,
Pranay
For the problem above, I found that while attempting to "open the session" i.e session.Open(sessionOptions), it will through the exception as the server was not authenticating it.
As my task was to "password less winscp login", i.e i must have to provide:-
1.".ppk" file that is "puTTy private key".
2. Its "ssh key fingerprint".
After all day debugging, finally found that my version of winsscp.dll was old thus was not providing me the [metadata] inbuild properties as
1. SshPrivateKeyPath -> location of our ".ppk" file.
2. SshHostKeyFingerprint
3. passphrase -> only for one time login.
By updating the new version and above now I am able to open session, without any error.
Thank you.
I've also faced the same problem , when i first tried to execute the code mentioned at the below link.
https://winscp.net/eng/docs/library#example
Googled it a lot but i couldn't find any solution regarding the same.
Finally the following i relalized that i'm missing the portnumber in the example
Adding the port number field to my code solved the issue.
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "11.22.33.44",
PortNumber = 2222, /* This is cause of the issue i was facing*/
UserName = "abcdef",
Password = "ghijklmnop",
SshHostKeyFingerprint = "ssh-rsa 2048 aa:bb:cc:dd:ee:ff:gg:hh:ii:jj:kk:ll:mm:nn:oo:pp"
};
If you can connect with WinSCP GUI, but not with .NET assembly, when running both in the same environment (computer), you have most probably missed some settings (like a port number or a host key fingerprint, as the other answers show).
The easiest solution is to have WinSCP GUI generate a code template for you based on its working settings.
If you are running the code on a different machine, check WinSCP FAQ Why does WinSCP not work in a new environment (operating system, machine, user account, network), when it works for me in a different environment already?
While the article is not explicitly about .NET assembly, but about WinSCP in general, it covers issues that you can face with the assembly too.

Access denied when reading / writing to network location as a remote process

I'm currently trying to launch a process on a remote machine using WMI in C#. The process reads and writes to a file that is stored on a separate server.
When I manually login to the remote machine, I can run the process and it all works fine.
However, when I try to launch the process on the remote from my local machine using WMI, I get the following error:
System.UnauthorizedAccessException: Access to the path '\\server\path\input.txt' is denied.
I've tried multiple connection options, but I'm not sure how to re-create the permissions that I seem to have when I login manually... What do I need to do?
Local machine code
static void LaunchRemoteProcess(string remoteMachine, string command)
{
ConnectionOptions connectionOptions = new ConnectionOptions
{
Impersonation = ImpersonationLevel.Impersonate,
EnablePrivileges = true
};
var managementScope = new ManagementScope(string.Format(#"\\{0}\root\cimv2", remoteMachine), connectionOptions);
managementScope.Connect();
var managementPath = new ManagementPath("Win32_Process");
var objectGetOptions = new ObjectGetOptions();
var managementClass = new ManagementClass(managementScope, managementPath, objectGetOptions);
// Launch the command asynchronously
var inParams = managementClass.GetMethodParameters("Create");
inParams["CommandLine"] = command;
var outParams = managementClass.InvokeMethod("Create", inParams, null);
}
Remote machine code
string networkPath = #"\\server\path";
string inputFile = "input.txt";
string inputText = File.ReadAllText(Path.Combine(networkPath, inputFile));
string outputFile = "output.txt";
File.WriteAllText(Path.Combine(networkPath, outputFile), inputText);
Edit 1
I have already tried using the credentials of the user for which the process works if I log on to the remote machine manually and the process still fails with the same error:
ConnectionOptions connectionOptions = new ConnectionOptions
{
Username = "username",
Password = "password",
Authority = "ntlmdomain:COMPANYNAME.CO.UK,
EnablePrivileges = true
};
Am I missing something with regards to the Authority, Authentication, or Impersonation attributes?
Impersonation vs Delegation
Your WMI code uses impersonation, so the server side runs in the security context of the user who calls the code on the client. But this is only valid on the server itself, not for accessing e.g. a remote CIFS share (as in your case).
You have to use delegation.
First, change
Impersonation = ImpersonationLevel.Impersonate,
to
Impersonation = ImpersonationLevel.Delegate,
If you get an exception then, delegation does not yet work in your environment.
Check:
Calling user account: "Account is sensitive and cannot be delegated" must not be checked in the user properties (Active Directory Users and Computers)
server machine account: "Trust this computer for delegation to any service..." must be checked
local security policy on the server: "Enable computer and user accounts to be trusted for delegation" must include the calling user.
See
https://msdn.microsoft.com/en-us/library/aa389288%28VS.85%29.aspx
for further information on this topic.
Added: (see the comments below):
If Delegate is not an option in your environment (e.g. group policies do not allow for this, and you do not have the rights to change them), you may check some alternative ways.
You probably heard of psexec.
Or, what I did some years ago, and which runs in production in a enterprise environment on a few servers for many years very successfull:
I created a scheduled task which starts a program and set the technical user + password for this task. The task was configured for "run once in year 2200 :-)".
Then I wrote commands in a queue (I used a simple command file) and started the task from a remote machine.
Doing it this way, delegation is not required, since the scheduled task itself logs on as the technical user account ("logon as batch" privs are required).
As the reason states, the user id you are using on your PC does not seem to have access for to another computer's location (though it is a server, it is some other computer).
You may get access for your user id or use Impersonation to use an user id that already has access to the location.
Find more details here: https://msdn.microsoft.com/en-us/library/w070t6ka%28v=vs.110%29.aspx
Edited: Add user name password too. That may help.

Invoking Powershell via C# in a web application - issues with app pool identity

I have written some stuff to execute Powershell via C# using RunspaceFactory.
I am loading the default Powershell profile like this:
Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
string scriptText = #". .\" + scriptFileName + "; " + command;
Pipeline pipeline = runspace.CreatePipeline(scriptText);
Command = a function from the profile i know works.
All of this Powershell stuff is wrapped in Impersonator.
For the avoidance of doubt, $profile = C:\Users\Administrator\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
This is a web application running under IIS 7.5
If my IIS app runs under the 'administrator' account, it works. Under any other account it throws the error:
"The term '.\Microsoft.PowerShell_profile.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."
As I am impersonating the 'administrator' account I assumed the location would be correct.
Some logging with an invoked 'get-location' reports the directory is what it should be.
Out of bloody mindedness i tried to force it with:
System.Environment.CurrentDirectory = dir;
... and also an attempt at an invoked 'set-location'. These work, but if I invoke 'get-location' from a runspace it reports the same directory as before (the correct one).
I thought that, perhaps, there might be a problem with the impersonation, so i wrote some tests that touch the file system in ways the app pool shouldn't be able to do. These work.
I also checked this:
string contextUserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Which reports the correct user both when code is 'wrapped' in impersonator, and when it is executed via the app pool identity. Then I got desperate and tried invoke:
#"cmd /c dir"
... (and also get-Childitem). Both commands return:
{}
...when running under the app pool identity (regardless of impersonation), but a full and accurate directory listing of the correct directory when the app pool is running as 'administrator'.
I am sure I am missing something stupid and fundamental here, if anyone could give me some guidance on where I've made a mistake in my thinking (and code), that would be great.
This is kind of a "well known" issue with using PowerShell in ASP.NET when in an impersonated context: it doesn't work the way people think it should work.
The reason for that is because PowerShell, behind the covers, spins up another thread to actually do all of its work. That new thread inside PowerShell does not inherit the impersonated context.
The fix isn't exactly pretty. This MSDN blog post recommends setting ASP.NET to always flow the impersonation policy (so that thread behind the scenes gets the identity):
<configuration>
<runtime>
<legacyImpersonationPolicy enabled="false"/>
<alwaysFlowImpersonationPolicy enabled="true"/>
</runtime>
</configuration>
Another, even uglier approach (though less hacky) is to use WinRM. You can use a loopback PowerShell session (connect to localhost) with PowerShell, and let WinRM handle the impersonation. This requires version 3.0.0.0 of System.Management.Automation.
var password = "HelloWorld";
var ss = new SecureString();
foreach (var passChar in password)
{
ss.AppendChar(passChar);
}
var psCredential = new PSCredential("username", ss);
var connectionInfo = new WSManConnectionInfo(new Uri("http://localhost:5985/wsman"), "http://schemas.microsoft.com/powershell/Microsoft.PowerShell", psCredential);
using (var runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
connectionInfo.EnableNetworkAccess = true;
using (var powershell = PowerShell.Create())
{
This is also a tacky solution because it requires WinRM's Windows Service to be running, and configuring WinRM. WinRM isn't exactly something "that just works", however it gets the job done in the first option isn't suitable.
The URL used in the WSManConnectionInfo is a localhost WinRM endpoint, by default it listens on port 5985 in version 3, and credentials are specified for the connection.

Trying to remotely access through wmi using C#

I have this piece of code:
private ManagementScope CreateNewManagementScope(string server)
{
string serverString = "\\\\" + server + "\\root\\cimv2";
ConnectionOptions options = new ConnectionOptions();
options.Username = "name";
options.Password = "password";
ManagementScope scope = new ManagementScope(serverString, options);
scope.Connect();
return scope;
}
With that code I am trying to remotely access another PC though WMI. The password and the username are 100% correct (I tested them with wmic /node:pc /username:name /password:pwd and this worked) but I am getting access denied
(Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
Any Ideas what I am doing wrong? I am working with Win 7/C#/.NET 4.0
Thanks for any Help!
you can try with admin credential :
string serverString = #"\\" + strIPAddress + #"\root\cimv2"
Check what is logged on the other machines Security eventlog since it will provide you with a clue on what's wrong with access permissions.
I'm quite sure that you can solve the issue after checking the TechNet article "Connecting to WMI Remotely Starting with Windows Vista" and the related one. Specifically this part:
"Setting DCOM Security to Allow a User to Access a Computer Remotely".
Check the code of Services+ (Advanced Windows Service Manager) contains all what you need about WMI Win32_Service.
To Troubleshoot or debug:
Make sure the computer and server are on the same domain
Remove your code credential and make an EXE form your code then Run
the EXE as privileged user.
Use Services+ (mentioned above) or Services.msc to connect to the
server.
Make sure RPC service is running on Remote Server.
Try to trun off the firewall temporary on the server.

Windows Service Choose User or System Account on Install

When installing a windows service, is there a way to let the user installing choose between a specific user account and a computer account, such as LocalSystem? I see how to do this at build time through service installer properties, but not during install.
#Doobi, #Eric, in my experience (Win7Home 64-bit, VS2010Express, not on a domain)
processInstaller.Account = ServiceAccount.LocalService;
processInstaller.Username = null;
processInstaller.Password = null;
will install the service as LocalService without a password prompt.
To install the service as a local user account (and provide a password prompt to enable the user to supply the credentials) I had to use:
this.serviceProcessInstaller.Account =System.ServiceProcess.ServiceAccount.User;
this.serviceProcessInstaller.Password = null;
this.serviceProcessInstaller.Username = null;
The important step I had to take to get the service installed is to put the computer name in the credentials dialog box, ie MYPC\dave instead of dave. I was surprised that I'd have to do this as it's not on a domain. I've added this comment as no other posts I've seen about this mention having to prefix the username with the PC name.
Yes there is, it's on the process installer. I think in the newer frameworks it's a visible property if you select the process installer on the design surface. The last time I did it (.NET 2.0) you have to add something similar to this to the *.designer.cs file:
processInstaller.Account = ServiceAccount.LocalService;
processInstaller.Username = null;
processInstaller.Password = null;
Adding to previous answers, don't forget to append Machine name to Username while entering "Username" Field of password prompt. Otherwise service will not accept the credentials although if you give correct username and pwd. It will keep on pop up prompt to enter credentials. It took me one day to figure out this. Thanks to Badgerspot!

Categories