How do I authenticate to a Proxy Server from clj-apache-http? - proxy

I'm trying to get up an running using http://github.com/rnewman/clj-apache-http
(http/get (java.net.URI. url)
:headers {"User-Agent" user-agent}
:parameters (http/map->params
{:default-proxy (http/http-host :host "localhost"
:port 8888)})
:as :string)
Problem is, my proxy (squid) requires authentication. How do I "feed" my username/password into this library?
Thanks!

Adding the following to my headers dictionary did the trick:
"Proxy-Authorization" (str "Basic "
(base64/encode-str "username:password"))
Like Mac said -- this could also be implemented with a filter -- but preemptive-basic-auth-filter won't work because it sends the headers for WWW-Authorization instead of Proxy-Authorization.

clj-apache-http has a preemptive-basic-auth-filter that you can use. It supports combined username / password strings of this form "name:password". Use of the function is not well documented but can be found here. Example (not tested):
(http/get (java.net.URI. url)
:headers {"User-Agent" user-agent}
:parameters (http/map->params
{:default-proxy (http/http-host :host "localhost"
:port 8888)})
:as :string
:filters ((preemptive-basic-auth-filter "name:password")))

Related

Ruby Oauth2.0: client_secret_post not working with ory hydra

I am trying to get a Ruby Oauth2.0 client talking with the Ory Hydra docker-compose 5 minute demo. I am stuck on the client app's authentication code exchange for the token. LOG is below. Looks like the main problem is the following "hashedPassword is not the hash of the given password".
DEBUG LOG FROM HYDRA SERVER
time="2019-06-04T21:32:09Z" level=info msg="started handling request" method=POST remote="172.19.0.2:35482" request=/oauth2/token
hydra_1
time="2019-06-04T21:32:09Z" level=error msg="An error occurred" debug="crypto/bcrypt: hashedPassword is not the hash of the given password" description="Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)" error=invalid_client
hydra_1
time="2019-06-04T21:32:09Z" level=info msg="completed handling request" measure#hydra/public: http://127.0.0.1:4444/.latency=92931900 method=POST remote="172.19.0.2:35482" request=/oauth2/token status=401 text_status=Unauthorized took=92.9319ms
I've read up here and it would appear this 'is' possible.
Here is how I register my client 'test-app9' in hydra:
docker-compose -f quickstart.yml exec hydra hydra clients create --endpoint http://127.0.0.1:4445 --id test-app9 --secret secret--skip-tls-verify --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope profile --callbacks http://127.0.0.1:8088/auth/callback --token-endpoint-auth-method client_secret_post -g client_credentials
I can indeed see the client appearing in the postgres DB from the docker-compose demo. The password 'secret' is hashed in the DB.
Here is my single Sinatra file acting as the Oauth2.0 client:
require 'rubygems'
require 'sinatra'
require 'oauth2'
require 'json'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
# If you add your authentication in the header then use ~Sclient_secret_basic~T
# If you add your authentication details in the post use ~Sclient_secret_post~T
def client
OAuth2::Client.new('test-app9',
'secret',
# 'c2VjcmV0',
:site => "http://127.0.0.1:4445",
:logger => Logger.new('example.log'),
:authorize_url => "http://127.0.0.1:4444/oauth2/auth",
:token_url => "http://hydra:4444/oauth2/token")
end
set :root, File.dirname(__FILE__)
set :views, Proc.new { File.join(root, "views") }
set :run, true
set :port, 80
get "/" do
erb :index
end
get '/auth' do
authorization_url = client.auth_code.authorize_url(:redirect_uri => redirect_uri, :response_type => "code", :scope => "profile", :state => "pqrst1234")
puts "Redirecting to URL: #{authorization_url.inspect}"
redirect authorization_url
end
get '/auth/callback' do
begin
access_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri, :client_id => "test-app9", :client_secret => 'secret', :headers => {'Authorization' => 'basic_auth_header', 'client_id' => 'test-app9', 'client_secret' => 'c2VjcmV0'} )
api_url = "/me.json"
me = JSON.parse(access_token.get(api_url).body)
erb "<p>Your data:\n#{me.inspect}</p>"
rescue OAuth2::Error => e
erb %(<p>Wassup #{$!}</p><p>Retry</p>)
end
end
get '/auth/failure' do
erb "<h1>Authentication Failed:</h1><h3>message:<h3> <pre>#{params}</pre>"
end
def redirect_uri(path = '/auth/callback', query = nil)
uri = URI.parse(request.url)
uri.path = path
uri.query = query
uri.to_s
end
__END__
So some interesting notes:
It apparently does not matter what secret I initiate the OAuth2 client with. I can use 'secret' or the base64 encoded 'c2VjcmV0' string. Either way I get up to the token exchange portion.
I was shotgunning this and ended up putting the client_id and the client_secret in what I believe is the proper way to set in the headers as well as the body.
I have tried many variations of this. Can't seem to get the correct syntax that the author of this apparently succeeded with OR I'm hitting a bug (doubtful).
Anyone able to help here?
UPDATE
Fixed this myself. Problem was syntax issue when creating my client 'app'. This is the corrected version.
docker-compose -f quickstart.yml exec hydra hydra clients create --endpoint http://127.0.0.1:4445 --id test-app10 --secret secret --skip-tls-verify --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope profile --callbacks http://127.0.0.1:8088/auth/callback --token-endpoint-auth-method client_secret_post -g client_credentials

Attempt at authenticated SMTP in Ruby

I've looked at all the SMTP ruby-docs and can't figure out where I'm going wrong:
def send(username, password, data, toAddress, fromAddress)
smtp = Net::SMTP.new('my.smtp.host', 25)
smtp.start('thisisunimportant', username, password, "plain") do |sender|
sender.send_message(data, fromAddress, toAddress)
end
end
send(user, pass, rcpt, "Hey!")
Gives an unexpected kind of error:
/usr/lib/ruby/1.9.1/net/smtp.rb:725:in authenticate': wrong number of arguments (3 for 4) (ArgumentError)
from /usr/lib/ruby/1.9.1/net/smtp.rb:566:indo_start'
from /usr/lib/ruby/1.9.1/net/smtp.rb:531:in start'
from gmx_pop.rb:24:insend'
from gmx_pop.rb:30:in `'
I've tried kicking my computer a couple times but the problem persists.
Here's a description of the Net::SMTP#start call:
http://ruby-doc.org/stdlib-1.9.1/libdoc/net/smtp/rdoc/Net/SMTP.html#method-i-start
the page mentions that you can just do SMTP.start to do everything at once.
Look like you are missing the port parameter. Try port 587 for secure authentication, if that doesn't work, port 25. (check the tutorial mentioned below)
Your call should look like this:
message_body = <<END_OF_EMAIL
From: Your Name <your.name#gmail.com>
To: Other Email <other.email#somewhere.com>
Subject: text message
This is a test message.
END_OF_EMAIL
server = 'smtp.gmail.com'
mail_from_domain = 'gmail.com'
port = 587 # or 25 - double check with your provider
username = 'your.name#gmail.com'
password = 'your_password'
smtp = Net::SMTP.new(server, port)
smtp.enable_starttls_auto
smtp.start(server,username,password, :plain)
smtp.send_message(message_body, fromAddress, toAddress) # see note below!
Important:
Please note that you need to add To: , From: , Subject: headers to your message_body!
the Message-Id: and Date: headers will be added by your SMTP server
Check also:
Tutorial : http://www.java-samples.com/showtutorial.php?tutorialid=1121
the source code for Net::SMTP under ~/.rvm/src/ruby-1.9.1*/lib/net/smtp.rb
(Ruby) Getting Net::SMTP working with Gmail...?
Another way to send emails from Ruby:
You can use the ActionMailer gem from Rails to send emails from Ruby (without Rails).
At first this seems like overkill, but it makes it much easier, because you don't have to format the message body with To: , From: , Subject: , Date: , Message-Id: Headers.
# usage:
# include Email
#
# TEXT EMAIL :
# send_text_email( 'sender#somewhere.com', 'sender#somewhere.com,receiver#other.com', 'test subject', 'some body text' )
# HTML EMAIL :
# send_html_email( 'sender#somewhere.com', 'sender#somewhere.com,receiver#other.com', 'test subject', '<html><body><h1>some title</h1>some body text</body></html>' )
require 'action_mailer'
# ActionMailer::Base.sendmail_settings = {
# :address => "Localhost",
# :port => 25,
# :domain => "yourdomain.com"
# }
ActionMailer::Base.smtp_settings = { # if you're using GMail
:address => 'smtp.gmail.com',
:port => 587,
:domain => 'gmail.com',
:user_name => "your-username#gmail.com"
:password => "your-password"
:authentication => "plain",
:enable_starttls_auto => true
}
class SimpleMailer < ActionMailer::Base
def simple_email(the_sender, the_recepients, the_subject, the_body , contenttype = nil)
from the_sender
recipients the_recepients
subject the_subject
content_type contenttype == 'html' ? 'text/html' : 'text/plain'
body the_body
end
end
# see http://guides.rails.info/action_mailer_basics.html
# for explanation of dynamic ActionMailer deliver_* methods.. paragraph 2.2
module Email
# call this with a message body formatted as plain text
#
def send_text_email( sender, recepients, subject, body)
SimpleMailer.deliver_simple_email( sender , recepients , subject , body)
end
# call this with an HTML formatted message body
#
def send_html_email( sender, recepients, subject, body)
SimpleMailer.deliver_simple_email( sender , recepients , subject , body, 'html')
end
endsubject , body, 'html')
end
end
e.g. the code above works if you want to use Gmail's SMTP server to send email via your Gmail account.. Other SMTP servers may need other values for :port, :authentication and :enable_starttls_auto depending on the SMTP server setup
Try this code
Net::SMTP.smtp.start('my.smtp.host', 25, 'mail.from.domain', username, password, :plain) do |smtp|
smtp.send_message data, fromAddress, toAddress
end

Sinatra - response.set_cookie doesn't work

I need to use a cookie for my Sinatra application. If I use the simpliest method is works:
response.set_cookie('my_cookie', 'value_of_cookie')
but I need some options such as domain and expire date so I try this:
response.set_cookie("my_cookie", {:value => 'value_of_cookie', :domain => myDomain, :path => myPath, :expires => Date.new})
does not work. No cookie is made. I need this so much....
Please help... thanks!
The documentation on http://sinatra-book.gittr.com/#cookies says to use the set_cookie helper, but in newer versions of Sinatra (at least from 1.2.0+ and possibly earlier), you should use response.set_cookie to set cookies.
response.set_cookie("my_cookie", :value => "value_of_cookie",
:domain => myDomain,
:path => myPath,
:expires => Date.new(2020,1,1))
cookie = request.cookies["my_cookie"]
SUMMARY
don't set localhost as a domain for your cookies because you need to set it to "" or FALSE

How do I process a URL in ruby to extract the component parts (scheme, username, password, host, etc)?

I'm trying create a program using ruby (and Net::SSH) to connect to servers and perform some tasks. The details of the server are to be provided as something like:
ssh://user:pass#host:port (for a host that does not yet have SSH keys)
or
user#host
Net::SSH expects the following format:
Net::SSH.start('host', 'user', :password => "password")
Is there are gem/stdlib that can process the URL into this format? Or a simple regex that can match the different parts?
Note: I'm aware of, and use, capistrano but in this case I need lower level control.
Both URI and Addressable::URI can parse URLs and let you break them down into their components.
URI is included in Ruby's Standard Library, which is nice, but Addressable::URI has more features, and is what I use when I have to do a lot of work on URLs.
require 'addressable/uri'
uri = Addressable::URI.parse('ssh://user:pass#www.example.com:81')
uri.host # => "www.example.com"
uri.user # => "user"
uri.password # => "pass"
uri.scheme # => "ssh"
uri.port # => 81
require 'uri'
uri = URI.parse('ssh://user:pass#www.example.com:81')
uri.host # => "www.example.com"
uri.user # => "user"
uri.password # => "pass"
uri.scheme # => "ssh"
uri.port # => 81

setting cookies

Okay, so I'm trying to set cookies using Ruby. I'm in a Rack environment. response[name]=value will add an HTTP header into the HTTP headers hash rack has. I know that it works.
But the following method of setting cookies doesn't work:
def set_cookie(opts={})
args = {
:name => nil,
:value => nil,
:expires => Time.now+314,
:path => '/',
:domain => Cambium.uri #contains the IP address of the dev server this is running on
}.merge(opts)
raise ArgumentError, ":name and :value are mandatory" if args[:name].nil? or args[:value].nil?
response['Set-Cookie']="#{args[:name]}=#{args[:value]}; expires=#{args[:expires].clone.gmtime.strftime("%a, %d-%b-%Y %H:%M:%S GMT")}; path=#{args[:path]}; domain=#{args[:domain]}"
end
Why not? And how can I solve it? Thanks.
It turns out that you can't use an IP address with cookies, at least not with also specifying a port.

Resources