I am trying to connect from a Windows app to a unix server, to run some commands (automating checks on server status). I am using the ssh.net library, and have this code to connect to the server:
using (SshClient ssh = new SshClient("myserver.univ.edu", "myusername", "My!maginaryPa55wrd"))
{
ssh.Connect();
var result = ssh.RunCommand("df -h");
LogText.Text = result.Result; // puts result of command into multiline textbox
ssh.Disconnect();
}
But when I run this, it times out on the connect. I am guessing this is because the server requires two factor authentication. When I log into it with Putty, it will prompt for username and password, it then prompts for a choice of factors ... enter a passcode or "1" for Duo push to xxx-xxx-1212 or "2" for phone call to xxx-xxx-1212.
The SSH.net library says it supports two-factor authentication, but I have searched all over for a way to do it, and I am coming up empty. Any clues as to how to solve this, I'd appreciate it.
The problem is that you don't have two factor authentication, you have single factor and a bunch of interactive options, which is non-standard and not supported by ssh.net. It's not expecting to have to make choices.
To make this work, you would need to modify the ssh.Net code, or better, setup Public Key Authentication with the remote servers, in which case it won't need a password or 2FA.
Any reasonable size organization almost certainly has PKI setup. You would need to check with the admins and see about getting your Public Key added to the servers you'll be checking.
ssh.Net supports public key auth and would eliminate all the problems you're having.
Related
We are making use of ADLDS for our user management and authentication. We can successfully query the instance without problems. However, trying to perform an operation such as SetPassword will fail or even trying to create a new user if a password is not set, it fails. I can successfully update a user as long as its not password I'm trying to update. I've been reading a lot of different articles relating to this but not finding a resolution. Posting to see if I can get some fresh perspective on this issue, thanks for any input.
EXAMPLE
ContextType ctxType = ContextType.ApplicationDirectory;
string server = "myadldsserver.com";
string usersCN = "CN=Users,..."; // container where users reside
ContextOptions ctxOpts = ContextOptions.SimpleBind;
string uname = "myuser";
string pswrd = "mypass";
using(var ctx = new PrincipalContext(ctxType, server, usersCN, ctxOpts, uname, pswrd)
using(var newUser = new UserPrincipal(ctx)) {
newUser.Name = "newusername";
newUser.Enabled = true;
newUser.UserPrincipalName = "newusername";
newUser.Save();
newUser.SetPassword("newuserpassword");
}
ERROR 1
The first problem I encounter if I try to create a new UserPrincipal and call Save without having set the password like in Example above I get the exception A constraint violation occurred. with an InnerException extend message of 0000052D: AtrErr: DSID-033807D7, #1:0: 0000052D: DSID-033807D7, problem 1005 (CONSTRAINT_ATT_TYPE), data 2246, Att 9005a (unicodePwd)
Because of this error I tried moving the SetPassword before calling Save along with other approaches I found online such as getting the DirectoryEntry from the UserPrincipal and trying to call SetPassword but got a different error.
ERROR 2
Calling SetPassword before calling UserPrincipal.Save, when save is called, results in the error The directory property cannot be found in the cache.
Note that the same error will occur if I trying calling ResetPassword or getting a DirectoryEntry and calling Invoke("SetPassword"... as well
ERROR 3
From my research most seem to indicate this could have to do with needing to access AD LDS using a Secure connection. So, I changed my server to include the port of 636 string server = "myadldsserver.com:636" and I changed the ContextOptions to be ContextOptions.SimpleBind | ContextOptions.SecureSocketLayer.
Making these changes when the PrincipalContext is being constructed I get the following exception The server could not be contacted. with an inner exception of The LDAP server is unavailable., HResult is -2146233087
JAVA and LDP
To add some background to this, we do have similar code written in an older Java application. We are trying to port some of this logic over to .NET side in C#. The code in Java makes use of a Java keystore that contains the certificate that was generated on the AD LDS server. The Java application of course has no issues using the SSL port. We know the server seems to be configured correctly, it's just an issue of how to access it from .NET side.
Is there an equivalent on the .NET side such as the keystore in Java? We know that an SSL connection can be made to server. We have verified this using LDP as well.
GOALS
Be able to create a new user and set their password during creation
Be able to ResetPassword or ChangePassword for a user
Connect to our AD LDS instance from .NET securely
Have you tried using Microsoft Management Console to import the certificate?
Two ways to install the certificate
Either
Open a cmd.exe console and type "MMC"
File > Add/Remove Snap-In...
Select Certificates, click Add
Choose Computer Account and Local Computer when prompted, then OK...
Certificates should now be showing under Console Root
Certificates > Trusted Root Certification Authorities > Certificates > (right-click) > All Tasks > Import Certificate...
Find the certificate you want to import, click Next and choose defaults (Trusted Root Certification Authorities should already be
selected)
Click Next, Finish
(or)
Simply double-click on the .cer file for the certificate in Windows
Explorer, click Install Certificate... > Next > select the option to
"Place all certificates in following store" > Browse... > Select
Trusted Root Certification Authorities. Continue with next until done.
At this point your certificate is installed, and you should be able to communicate securely with your ADLDS server.
I'm currently working with the MQ .NET assemblies and am attempting to read queue depths of various queues for a monitoring application. We have the code working in Java, but our new application is in C# and it would be preferable to keep all this logic in the same application.
From what I've heard online, .NET assemblies ignore MQC.USER_ID_PROPERTY and instead use the user ID of whoever is running the application. Is there really no way to override this? This seems a very strange feature/bug. I know that MQC.TRANSPORT_PROPERTY is supposed to influence how the UserID is inferred, but whether I set to MQC.TRANSPORT_MQSERIES_MANAGED or MQC.TRANSPORT_MQSERIES_CLIENT, I see the same ID going up in Wireshark and get the same error back (MQRC_NOT_AUTHORIZED). Has anyone else found a workaround for this fairly large issue?
properties = new Hashtable();
properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);
properties.Add(MQC.HOST_NAME_PROPERTY, hostName);
properties.Add(MQC.PORT_PROPERTY, port);
properties.Add(MQC.CHANNEL_PROPERTY, channelName);
properties.Add(MQC.USER_ID_PROPERTY, userId);
properties.Add(MQC.PASSWORD_PROPERTY, "");
// create connection
queueManager = new MQQueueManager(queueManagerName, properties);
If you are using MQ .NET client (or for that matter MQ C client also) version prior to v8, the user id set by the application is not sent to the queue manager. Instead logged in user id is passed to queue manager for authentication. This is a known behavior of MQ versions prior v8.
You can develop and use what is known as security exit to perform user authentication. A security exit performs username and password authentication against a repository, such as the local operating system on the MQ server, or an LDAP repository.
You can also use SSL/TLS if that's suitable to you. Otherwise you can move up to use MQ v8 to make use of the out of the box user id/password authentication.
I have installed DB2, and on the same server I'm trying to establish a connection in PowerShell. It seems, however, that I have to provide the username and password in the connection string in plain text. As I am trying to create a scheduled task on a secure system, this is not an ideal situation.
I have checked the old standby, http://connectionstrings.com, but I cannot find any string that does not explicitly include the username and password. Is there such a string? Maybe use a different provider? Below is the code I'm using.
$cn=new-object System.Data.OleDb.OleDbConnection("Provider=IBMDADB2;Database=TLMA;HostName=xxx;Protocol=TCPIP;Port=50000;Uid=xxx;Pwd=xxx;CurrentSchema=DB2")
This is the error I'm getting:
Exception calling "Fill" with "1" arguments(s): " SQL30082N Security processing failed with reason "3" ("PASSWORD MISSING"). SQLSTATE=08001"
I'm open to any idea on how to solve this.
UPDATE: I've discovered that the instance has an Authentication setting. It's currently set to SERVER.
A connection string that looks like this:
$cn=new-object System.Data.OleDb.OleDbConnection("Provider=IBMDADB2;Database=TLMA;HostName=xxx;Protocol=TCPIP;Port=50000;Authentication=KERBEROS;CurrentSchema=DB2")
might work (I'm not sure), but it seems that it would require me to change the Authentication setting to KERBEROS. I don't know if this will break the application that's currently using the uid/pwd model.
I can call db2 commands from PowerShell when I load the profile, and the connection takes as credentials the already authenticated user:
set-item -path env:DB2CLP -value "**$$**"
db2 connect to mydb
However, I do not know how you can then use the connections as a resource.
Take a look at this working example: https://github.com/angoca/log4db2/blob/master/src/main/scripts/install.ps1
Also, try to change the security mechanism in DB2, in order to trust clients.
I am designing a desktop application in C#, which needs to be connected to my online mysql database. I tried to give access in control panel a "%" which means from any IP, but it is not working. May be the hosting provider (bigrock) not allowing that.
Alternatively, I am trying to write some code in online on PHP which will get the "sql" as parameter and returns the output as JSON format using json_encode.
Is there any alternate methods which is better approach.
What error do you get when you try to connect? Timeout = firewalled; Permission denied = permissions not right etc.
One solution is to create a proxy with pre-coded queries (let's call then "stored procedures") - you can then say "Run query 5, parameters A, B and C". As this would be server-server (not public) you just need to add some basic authentication system (e.g. shared rotating key, checksum using parameters etc), but also ensure the queries are not dangerous if any parameters are thrown at it.
Disclaimer: It's a solution, but I'm not actually recommending that I'd do it unless you're very sure it's safe!
Do you have Cpanel ? If yes, then try adding your host in remote MySQL.
Here the link http://www.liquidweb.com/kb/enable-remote-mysql-connections-in-cpanel/ if you are unsure on how to do that.
I'd advise that you do not create a wildcard user that can connect to the database from anywhere using embedded MySQL credentials in your application. This is a bad idea.
It would be extremely easy to determine the credentials used by your application and then a malicious user could directly connect to your DB server and begin issuing queries to your database.
They will be able to issue SELECT statements for any information in your tables, even info they shouldn't see. It then becomes much easier to exploit any known or unknown vulnerabilities in MySQL much easier since now they have console access and can send data directly to the server. If the account has the DELETE privilege, they can erase all the data in your table(s).
Also, having a PHP script that issues queries provided by the application/end-user is not ideal because one can still freely issue queries. While that option is better than giving blanket access to a remote user, it is still a bad idea.
The way to go would be to identify all of the information that the C# application needs to access, and how, and write a simple web service/API that will receive parameters and issue its own queries and return the results using XML, JSON, or even SOAP. Try to abstract the database access as much as possible from the outside world for the best security.
Hope that helps.
I would do the following:
Create a user with the host of your public ip (www.whatismyip.com).
If that doesn't work, create a user with your host as your public ARPA/PTR record:
>nslookup
> set q=ptr
> 8.8.8.8
Non-authoritative answer:
8.8.8.8.in-addr.arpa name = google-public-dns-a.google.com
8.in-addr.arpa nameserver = ns1.Level3.net
8.in-addr.arpa nameserver = ns2.Level3.net
The host would then be set to google-public-dns-a.google.com.
The second worked, and I am not sure why for me on a project I worked on in the past, where you would have thought the IP address to be sufficient.
I am not sure if you have root access or access to my.cfg. If you can edit it, make sure the line "skip-networking" is commented or removed and it contains line "bind-address = *". Restart mysql after editing config.
For security reasons you shouldn't access the database directly over the (public) network.
One way is to write a php script on the database server and access it via HTTP/POST.
You should authenticate the client via username and a hashed password. The data you are sending should be encrypted (eg with the users clear text password). Don't send complete queries, only what you want to do and the parameters. As example, you want the orders for the customer, you can send a post request with the following parameters
user=abc,password=9151440965cf9c5e07f81eee6241c042a7b78e9bb2dd4f928a8f6da5e369cdffdd2b70c70663ee30d02115731d35f1ece5aad9b362aaa9850efa99e3d197212a,data=EncryptedData
You can notice, that the password is an SHA512 Hash.
The data can be json or anything else:
{
"Command": "GetOrder",
"Limit": "10"
}
In your php code you do the following steps:
1. Authenticate the user, if the password is not correct, respond with error code etc
2. Decrypt the data
3. Execute a query
4. Return the result as encrypted data
If you don't want to store the clear text password in your database, you could store in your database the hashed value and use a double hashed value for authentication and single hashed value for encryption.
If you wan't to execute the queries with parameters from the request you should use prepared statements to prevent sql injection.
More information about en/decrypting in php see: http://php.net/manual/de/ref.mcrypt.php
Like some answers suggested, I think you are firewalled by bigrock.
Now if you want to use AJAX/PHP, you need three things:
- your C# class to send requests and receive the result
- your HTML/JS (or jQuery) file to receive the request and hand it over to your PHP. Then send you the result.
- your PHP file to query your DB.
The AJAX seems superfluous to me, you could just send your query passing it through POST or a GET parameter (i.e. example.com/query.php?req='SELECT * FROM clients')
The code would be as follow:
C# using this class made by Ali Ahsan Rana:
//create the constructor with post type and few data
MyWebRequest myRequest = new MyWebRequest("http://www.example.com/query.php","POST","req=");
//use System.Web.Script.Serialization and myRequest.GetResponse();
Some tutorial on System.Web.Script.Serialization.
On the PHP side:
<?php
$request=$_POST['req'];
$dsn = 'mysql:dbname=mydb;host=example.com';
$user = 'ajay';
$password = '0000';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$response = $dbh->query($request);
while ($rep = $response->fetch())
{
$response_array[] = $rep;
}
$response->closeCursor();
$return = json_encode($rep);
return($return);
?>
That's a quick draft but should work AFAIK.
I want to be able to execute openssh with some custom arguments and then be able to automatically login to the server. I want that my script will enter the password if needed and inject 'yes' if I'm prompted to add the fingerprint to the known hosts.
I've found SharpSsh for C# that do that, but I also need to use -D parameter and use ProxyCommand that I define in SSH, and the library is quite lacking for that usage.
Another thing that I've found was pexcept for Python that should do the trick but I couldn't find where to download it, on the offical page I'm being redirectred from sourceforge to some broken link.
Any help would be appreciated,
Bill.
If you use OpenSSH and then have a script to inject password in clear (meaning, you have stored the password unencrypted) it is defeating the purpose of secure shell.
Please strongly consider using public key mechanisms which can be easily and securely automated.
I'll second the recommendation to use public key authentication. Rather than hack around with expect, you might want to consider Paramiko - it's a native SSH client for Python which would greatly simplify the communications process, particularly if you ever need to interact with the remote server and it has support for things like SFTP built-in.
i use pexpect for similar purpose and download also work?
http://sourceforge.net/project/downloading.php?group_id=59762&filename=pexpect-2.3.tar.gz
here is a portion fro my ssh automate script, you can customize it for you usage
it may not run out of the box
import os
import getpass
import pexpect
import glob
import logging
import shutil
import time
class UpdateError(Exception): pass
g_password = None
def runSshCommand(cmd):
global g_password
ssh_newkey = 'Are you sure you want to continue connecting'
# my ssh command line
p=pexpect.spawn(cmd)
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==0:
print "Saying yes to connection.."
p.sendline('yes')
i=p.expect([ssh_newkey,'password:',pexpect.EOF])
if i==1:
while True:
if g_password is None:
g_password = getpass.getpass("password:")
p.sendline(g_password)
i = p.expect(['password:',pexpect.EOF])
if i==0:
g_password = None
print "Wrong password"
else:
break
elif i==2:
raise UpdateError("Got key or connection timeout")
return p.before
There is some excellent documentation on using Putty with generated SSH key authentication. This is an easy and secure way to accomplish your goals. Putty has a great set of features, for a windows SSH app. Even better when you consider that you can get it on the free.
pexpect can't import on Windows. So, I use plink.exe with a Python subprocess to connect to the ssh server.
Another way is to to use openssh and establish a trusted key; if both client and the user account on the server have this key, then openssh does not request a password.
I have a script that automates setup of this - it works under cygwin,
http://mosermichael.github.io/cstuff/all/projects/2011/07/14/ssh-friends.html
I hope Net::SSH::Expect Perl module will be of help to you.