Ruby hidden input password - ruby

I wrote a Ruby script that's trying to connect to a Postgres database hosted on Heroku.
If I use a hardcoded password, or if I load the password using gets, everything works fine.
However, if I load the password using IO.noecho, I get the following exception:
storing.rb:11:in `initialize': FATAL: password authentication failed for user "***" (PG::ConnectionBad)
FATAL: no pg_hba.conf entry for host "****", user "***", database "***", SSL off
from storing.rb:11:in `new'
from storing.rb:11:in `create_conn'
from fetch_currencies.rb:11:in `<main>'
Here's my code:
def create_conn(password)
conn = PGconn.connect(
:host => '***',
:port => 5432,
:dbname => '***',
:user => '***',
:password => password)
return conn
end
puts 'Postgres DB password:'
pass = STDIN.noecho(&:gets)
conn = create_conn(pass)
I tried printing the password after loading it, as well as checking whether it's a String, and everything seems to be fine. What could be the problem?

The problem, of course, was that I didn't chomp the input, so I guess the terminating new line character was also passed as part of the password.
The right way to go is then
pass = STDIN.noecho(&:gets).chomp

Related

Ruby Datamapper connection with SSL to MariaDB on Amazon RDS

How do I establish a ruby Datamapper connection to MariaDB on Amazon RDS with SSL?
Here's what I did:
A non-SSL connection works when testing with:
uri = 'mysql://user:pass#host:port/db_name'
connection = DataObjects::Connection.new(uri)
=> #<DataObjects::Mysql::Connection:0x000056179a3a5921
connection.secure?
=> false
According to the MySQL datamapper wiki, an ssl connection requires the following options: :ssl_ca, :client_key, and :client_cert.
This would result in the following code:
uri = 'mysql://user:pass#host:port/db_name?'
ssl_opts = 'ssl[ssl_ca]=file&ssl[client_key]=file&ssl[client_cert]=file'
connection = DataObjects::Connection.new(uri + ssl_opts)
connection.secure?
=> false
However the only files get is the RDS combind CA bundle, refered from the RDS docs
I do not have a client_cert at all.
Connecting with the mysql client on cli works with SSL:
mysql --ssl -h host -u user -p pass db_name
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 1638
Server version: 10.1.26-MariaDB MariaDB Server
In doc
https://github.com/datamapper/do/wiki/MySQL
It also says
as tested only ca_cert was required to connect to RDS.
So try adding only ca_cert path and do a test
There's only one parameter required: :ssl => {:ca_cert => 'pem_file'}.
However it looks like using uri string for configuration does not work. The reason is a limitation in Addressable::Uri. It cannot handle query strings which aim to represent hashes with more than 1 level.
The good news is that it works using DataMapper.setup with a config Hash:
DataMapper.setup(:default,
:adapter => 'mysql',
:user => 'user',
:database => 'db_name',
:host => 'host',
:password => 'pass',
:ssl => {
:ca_cert => '/path/to/rds-combined-ca-bundle.pem'
}
)

Sending a command via ssh with a publish ssh key, with no password

I can send a command via ssh to a server with login and password like this:
Net::SSH.start("1.2.3.4", "user_name", password: "1234") do |ssh|
res = ssh.exec!("ls")
end
But if I want to avoid providing a password and if I've added my public ssh key to that server, how can I get rid of the password? Should I just remove it from the function call or should I somehow let the server know that I want to be authenticated by a ssh public key?
Net::SSH.start("1.2.3.4", "user_name", keys: ['~/.ssh/id_rsa.pub']) do |ssh|
res = ssh.exec!("ls")
end
If the above won’t work for you, do:
Net::SSH.start("1.2.3.4", "user_name",
keys: ['~/.ssh/id_rsa.pub'],
# host_key: "ssh-rsa", # default value
# encryption: "blowfish-cbc", # default value
verbose: :debug
) do |ssh|
res = ssh.exec!("ls")
end
to see what’s wrong.

Ruby Net::SCP download asking for password then failing

I'm trying to download a file to an in-memory buffer from a unix box then upload the file to another unix box, but when I try to download the file it asks for my password then fails even if I put it in. I've tried both:
data = Net::SCP.download!("remote.host.com", "username", "/remote/path", :password => password)
and
data = Net::SCP::download!("remote.host.com", "username", "/remote/path", :password => password)
but I get:
Active Directory Password:
Then when I enter my password:
Net::SCP::Error: SCP did not finish successfully (1)
ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mingw32]
net-scp (1.0.4)
Try to use it like this:
require 'net/scp'
data = nil
Net::SCP.start("remote.host.com", "username", :password => "password") do |scp|
data = scp.download!("/remote/path")
end
puts data
EDIT: I only tried this on ruby ruby-1.9.3, sorry
Looks like Net::SFTP will be what I'm actually going to use, its not much more and is probably what I'd end up with anyway since I didn't realize I need to 'write' the #data before putting it on another server.
data = nil
Net::SFTP.start('remoteHost1', 'username', :password => 'password') do |sftp|
data = sftp.download!("filepath1")
end
Net::SFTP.start('remoteHost2', 'username', :password => 'password') do |sftp|
sftp.file.open("filePath2", "w") do |f|
f.puts data
end
end

ruby net-ssh calling bash script with interactive prompts

I have a problem that I hope you can help me with
I’m trying to use ruby to ssh onto a machine and run a bash script, this part is fairly easy but the bash script requires me to entry a username and password interactively and this is where I’m stuck
So if I run the script manually I see:-
./run_file.sh
Enter username:
Enter password:
So at the enter Username prompt I have to enter the username etc
I’ve got a simple method I use to make the connection and my idea was to pass in an array made up of
[‘command to run’, ‘username’, ‘password’]
but I don’t know how to extend the Net::SSH call to respond to the prompts
# ssh conectivity method
def command_ssh(host, cmd)
require 'net/ssh'
user = LocalConfig::SSH_DETAILS[:user]
pass = LocalConfig::SSH_DETAILS[:pass]
Net::SSH.start(host, user, :password => pass, :paranoid => false, :auth_methods => ['password'], :timeout => 10 )do |ssh |
output = (ssh.exec!(cmd[0]))
return output
end
end
anyone got any ideas
managed to fix this by using the channel function, here's the method I use now
def connect(host,command)
require 'rubygems'
require 'net/ssh'
user = LocalConfig::SSH_DETAILS[:user]
pass = LocalConfig::SSH_DETAILS[:pass
o = ""
Net::SSH.start(host, user, :password => pass, :paranoid => false, :auth_methods => ['password'], :timeout => 30 )do |ssh |
channel = ssh.open_channel do |ch|
ch.exec(command) do |ch2, success|
ch2.send_data "myUserName\n"
ch2.send_data "mPassWord\n"
ch.on_data do |ch2, data|
o += data
end
end
end
channel.wait
return o.to_s
end
end

How to check for user credentials using active directory and a ruby script

I'm trying write a Ruby script that checks if user credentials are valid using an active directory server. Here's what I've tried so far:
require 'rubygems'
require 'net-ldap'
host = '10.4.1.6'
port = 389
username = 'username'
password = 'password'
ldap = Net::LDAP.new
ldap.host = host
ldap.port = port
ldap.auth "CN=#{username},CN=Users,DC=companyname,DC=ad", password
if ldap.bind
puts 'YES!'
puts ldap.get_operation_result.message
else
puts 'NO :-('
puts ldap.get_operation_result.message
end
If I enter a non existing username and an empty string as a password, the bind operation succeeds. If I enter a valid username and a valid/invalid/empty password, the bind operation fails with error message 'Invalid Credentials'.
I've looked at other threads and read the net-ldap documentation but I can't figure out what I'm doing wrong.
Can someone give me some ideas on how to achieve this?
Thanks in advance for any replies :-)
Edit:
As #StuartEllis suggested, the problem was with the user identifier. To figure out the correct DN, I used the following script (taken from the net-ldap documentation):
ldap.auth "CN='adminUser',CN=Users,DC=companyname,DC=ad", 'adminUserPwd'
ldap.bind
treebase = "DC=companyname,DC=ad"
filter = Net::LDAP::Filter.eq( "mail", "username#companyname.com" )
attrs = ["mail", "cn", "sn","objectclass"]
ldap.search( :base => treebase, :filter => filter, :attributes => attrs, :return_result => false ) do |entry|
puts entry._dump 0
end
I then retried using my original script (above) with the obtained DN and voila!
I would guess that your LDAP account details aren't correct, but your LDAP server accepts anonymous binds, which is why it works when you don't specify a valid username and password. LDAP user identifiers are very fiddly, so I'd suggest double-checking the whole thing, including the case of the parts.
Here is sample code I use with the net-ldap gem to verify user logins from the ActiveDirectory server at my work:
def name_for_login( email, password )
email = email[/\A\w+/].downcase # Throw out the domain, if it was there
email << "#mycompany.com" # I only check people in my company
ldap = Net::LDAP.new(
host: 'ldap.mycompany.com', # Thankfully this is a standard name
auth: { method: :simple, email: email, password:password }
)
if ldap.bind
# Yay, the login credentials were valid!
# Get the user's full name and return it
ldap.search(
base: "OU=Users,OU=Accounts,DC=mycompany,DC=com",
filter: Net::LDAP::Filter.eq( "mail", email ),
attributes: %w[ displayName ],
return_result:true
).first.displayName.first
end
end

Resources