SSL Error in net::HTTP.get - ruby

I'm trying to use ruby to do a search based on account 1234, but I keep getting an SSL_connect returned=1 errno=0 certificate error. The site is signed, but for some reason Ruby doesn't like it. The certificate is properly signed, so I'm not sure why it's rejecting it.
require 'net/http'
uri = URI("https://secure.domain.com/api/account/1234?api_key"+key)
response = Net::HTTP.get(uri)
puts response.body #this must show the JSON contents
Based on another suggestion I also tried, but received the same error.
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Get.new uri
response = http.request request # Net::HTTPResponse object
end

Turns out the error was due to Windows not having support for something like OpenSSL built in. After installing the appropriate binaries onto the system it worked without error.

Related

Rest-Client gem RoR, Getting SSL wrong version error

I want to build a cli ruby app which sends requests to Rails API server. I wanted to use rest-client gem to do that. Every time i use
RestClient.post
I get the following error
SSL_connect returned=1 errno=0 state=error: wrong version number (OpenSSL::SSL::SSLError)
Is there anything i can do for it to run from the console? The code is pretty simple, I just wanted to test out the feature, so don't worry, that's not final.
I am running rails 6.0.3, ruby 2.6.3.
require "tty-prompt"
prompt = TTY::Prompt.new
require 'rest-client'
if prompt.yes? "Do you have an account ?"
email = prompt.ask('What is your email?') do |q|
q.validate(/\A\w+#\w+\.\w+\Z/, 'Invalid email address')
end
pass = prompt.mask('password:')
puts email
puts pass
RestClient.post "https://localhost:3000/auth/sign_in", "email: #{email},password:#{pass}"
puts response.code
else
RestClient.post "https://localhost:3000/auth", "email: #{email},password:#{pass}"
end
I would like for the cli app to send a request to API, That's it, rest-client doesn't want to cooperate with me. Thank You :D
Likely the port 3000 you access is only http:// and not https://. Accessing a plain http:// port with https:// will cause the client to interpret the servers HTTP error message (since the beginning of the TLS handshake sent by the client was not valid HTTP) wrongly as HTTPS which can result in strange errors like invalid packet length or also wrong version number.

How do I make HTTParty ignore SSL?

I'm using a local server to test an application, and make requests to that server from my own machine.
The test server's SSL is bad, and HTTParty throws errors because of that. From what I read, HTTParty should ignore SSL by default, but when I try to do this:
HTTParty.get( "#{ #settings.api_server }#{ url }" ).parsed_response
It throws this error:
OpenSSL::SSL::SSLError at /
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
How do I make it ignore the SSL?
In the latest HTTParty, you can use the verify option to disable SSL verification;
HTTParty.get( "#{ #settings.api_server }#{ url }", :verify => false ).parsed_response
To make HTTParty always skip SSL cert verification, and not have to specify this in every call:
require 'httparty'
HTTParty::Basement.default_options.update(verify: false)
HTTParty.get("#{#settings.api_ssl_server}#{url1}")
HTTParty.get("#{#settings.api_ssl_server}#{url2}")
HTTParty.get("#{#settings.api_ssl_server}#{url3}")
# ...
You can also do this scoped to a class when including HTTParty as a module:
require 'httparty'
class Client
include HTTParty
default_options.update(verify: false)
end
Client.get("#{#settings.api_ssl_server}#{url1}")
Client.get("#{#settings.api_ssl_server}#{url2}")
Client.get("#{#settings.api_ssl_server}#{url3}")
Or
require 'httparty'
module APIHelpers
class Client
include HTTParty
default_options.update(verify: false)
end
end
World(APIHelpers)
Client.get("#{#settings.api_ssl_server}#{url1}")
Client.get("#{#settings.api_ssl_server}#{url2}")
Client.get("#{#settings.api_ssl_server}#{url3}")
If you want to still send your certificates, use this flag:
verify_peer: false
This may be totally off base, as I'm new to Ruby, but this is what worked for me when other solutions wouldnt
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
Additional ways of doing this, if you get a 'dynamic constant assignment' (pulled from here)
OpenSSL::SSL.const_set(:VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE)

Net::HTTP doesn't start downloading file after post request

I am trying to make POST request with Net::HTTP to specific website, and start downloading file after response is returned.
I tested this first with wget, and it worked fine.I also tried with httpi and unirest gems and it went fine . However, because Net::HTTP is low-level API and I need more control(for example, tracking downloading progress), I'll stick with it.
The problem is, downloading just won't start.So here's the code:
require 'net/http'
require 'tempfile'
uri = URI.parse("http://mywebsite.com")
req = Net::HTTP::Post.new(uri.path)
req.set_form_data({'filed' => 'data'})
response = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req) do |response|
temp_file = Tempfile.new("new_file")
response.read_body do |chunk|
temp_file << chunk
end
end
}
I figured that the problem must be in response, what I get is not Net::HTTPOK
but HTTPSeeOther and here's more info about it
#<Net::HTTPSeeOther:0x91f2670>
{"server"=>["nginx"], "date"=>["Sat, 21 Dec 2013 22:32:14 GMT"],
"content-type"=>["text/html"], "transfer-encoding"=>["chunked"],
"connection"=>["keep-alive"], "pragma"=>["no-cache"],
"cache-control"=>["no-cache, must-revalidate"],
"expires"=>["Sat, 26 Jul 1997 05:00:00 GMT"],
"location"=>["http://mywebsite.com/path/to/file.rar"]}
The other 2 gems I mentioned knew how to start download automatically and I don't know what to do with HTTPSeeOther .
It appears that you're getting a redirect response from the server, which wget, curl, and high-level libraries will follow automatically. With Net::HTTP, you'll need to start a new GET request to that location.

sslv3 alert illegal parameter using Net::HTTP in Ruby on Linux

I am attempting to use a remote system for user authentication. This chunk of code gets a response when I run it on MacOSX, but fails on my machine:
def create
uri = URI.parse('https://ourclient.example.com/')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new('/login.jsp')
request.set_form_data({'login_name' => params[:login], 'password' => params[:password]})
response = http.request(request)
puts "Response BODY: #{response.body.inspect}"
end
Turning verify off gets rid of a warning on the Macs. On my machine, the http.request raises this exception:
OpenSSL::SSL::SSLError (SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: sslv3 alert illegal parameter):
app/controllers/sessions_controller.rb:16:in `create'
I get the same behavior using IRB without Rails. I did a clean install of Fedora 14 yesterday, installed the required development tools and libraries. I'm using Ruby 1.9.2-p180, and Rails 3.0.4. I thought I might have had my libraries misconfigured (I had Fedora 12 that had been upgraded a few times), but this is now a new install.
The remote system is probably Microsoft's IIS, but I'm not certain of that. Perhaps I can use an older SSL protocol, but my Google-fu can't find the incantation.
I would appreciate any tips on resolving this issue. Thanks,
Chris
how was created the ssl cert on the server? self-signed or ca-signed?
which is the error you receive if you remove the VERIFY_NONE?
use Mechanize gem for it
gem install mechanize
and try
require 'mechanize'
page = Mechanize.new{|a| a.ssl_version, a.verify_mode = 'SSLv3', OpenSSL::SSL::VERIFY_NONE}.get "**YOUR HTTPS LINK HERE**"

How do I get an HTTPS request with SSL client cert to work with Ruby EventMachine?

I am trying to access an HTTPS web service that uses SSL cert authentication using Ruby EventMachine but I am not getting it to work.
I have written the following simple code block to test it end-to-end:
require 'rubygems'
require 'em-http'
EventMachine.run do
url = 'https://foobar.com/'
ssl_opts = {:private_key_file => '/tmp/private.key',
:cert_chain_file => '/tmp/ca.pem',
:verify_peer => false}
http = EventMachine::HttpRequest.new(url).get :ssl => ssl_opts
http.callback do
p http.response_header.status
p http.response_header
p http.response
EventMachine.stop
end
http.errback do
EventMachine.stop
fail "Request failed"
end
end
Running the above outputs <SSL_incomp> followed by the raised RuntimeError message. I have tried running with :verify_peer set to both true and false and it gives me the same error. Running EventMachine::HttpRequest#get without the :ssl option does the same.
I have also tried sending the request to GMail (https://mail.google.com) without the :ssl option (i.e. plain HTTPS without cert) and that works, outputting status code 200, the headers and the body.
I have tried doing the same request to the web service with curl and that works:
curl --silent --cert /tmp/private.key --cacert /tmp/ca.pem https://foobar.com/
I am thinking that I am either using the em-http-request gem or EventMachine incorrectly or that the SSL files are in a format that works with curl but not EventMachine.
I someone knows how to solve the example above or provide a similar example using EventMachine directly would be much appreciated!
The file passed to curl's --cert contains both the cert and the key (unless you pass in a --key separately). Just use /tmp/private.key as the argument to both :private_key_file and :cert_chain_file
See http://github.com/eventmachine/eventmachine/issues/#issue/115 for more details about the issue and a patch that exposes the underlying error (instead of just printing out SSL_incomp).

Resources