Ruby SSLserver closes on SSLERROR - ruby

I have a simple SSL server in ruby:
require "socket"
require "openssl"
tcp_server = TCPServer.new("0.0.0.0", 8443)
ctx = OpenSSL::SSL::SSLContext.new
ctx.key = OpenSSL::PKey::RSA.new File.read params["ssl-key"]
ctx.cert = OpenSSL::X509::Certificate.new File.read params["ssl-cert"]
server = OpenSSL::SSL::SSLServer.new(tcp_server, ctx)
#client handling code
loop do
client = server.accept
client.puts("Hello!")
client.close
end
When I start the server, it works as expected and I can connect to it using a client that uses SSL properly, but when I connect to it with a client using a normal tcp socket, I get OpenSSL::SSL::SSLError and the program quits. I can rescue the exception and the program does not exit, but I can not connect to the server from any type of client.

Not quite sure, this is weird. Possibly, you could try to start a new server and kill the old one? I think the server is still running, but is inactive.

Related

Ruby not connecting to IMAP account

I’m trying to write a Ruby script that goes through an IMAP server, and I have set this up as test case. For some reason, though, I can’t get it to actually find the port. I’ve even tried running getaddrinfo, with no luck. It simply won’t acknowledge the server’s existence.
require 'net/imap'
test = File.new "test.txt", 'w'
imap = Net::IMAP.new('imap.google.com', 993, usessl=true, certs=nil, verify=false)
imap.authenticate('LOGIN', 'user', 'pass')
imap.examine('Mail')
imap.search(["SMS"]).each do |msg|
test << msg
end
The server is imap.gmail.com or imap.googlemail.com

SSL Reuse error when using ruby mechanize gem

I had my mechanize script running for roughly 3 hours before I got the following error:
C:/Ruby193/lib/ruby/gems/1.9.1/gems/net-http-persistent-
2.7/lib/net/http/persistent/ssl_reuse.rb:29:in `initialize':
A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because
connected host has failed to respond. - connect(2) (Errno::ETIMEDOUT)
I'm assuming it's due to the fact that it's been running for 2-3 hours but was wondering if anyone had any special insight about the error
Here is my script
require 'rubygems'
require 'mechanize'
def next_button(web_page)
web_page.page.search('.next a').each do |next_button|
web_page.click(next_button)
web_page.page.search('.listing_content').each |info|
get_info(info)
end
next_button(web_page)
end
end
def get_info(info)
infos = info.at_css('.url').text.strip
address = info.css('.street-address').text.strip
city = info.css('.locality').text.strip
state = info.css('.region').text.strip
zip = info.css('.postal-code').text.strip
end
web_page = Mechanize.new
web_page.user_agent_alias = "Linux Firefox"
web_page.get(HOME_URL)
web_page.page.search('.page-navigation a').each do |pagination_link|
web_page.page.search('.categories-list a').each do |link|
web_page.click(link)
web_page.page.search('.listing_content').each do |info|
get_info(info)
end
next_button(web_page, worksheet)
end
web_page.click(pagination_link)
end
Thanks for any help in advance.
In my opinion persistent connections are more trouble than they're worth. When this happens to me I check to make sure I have the latest version of mechanize, and if it still happens, I fall back to mechanize 1.0.0 which doesn't use persistent connections.

Quick FTP server

I'm looking for a quick, configuration-less, FTP server. Something exactly like Serve or Rack_dav, but for FTP, which can publish a folder just by running a command.
Is there a gem or something to do such thing?
Solution
Based on Wayne's ftpd gem, I created a quick and easy-to-use gem called Purvey.
The ftpd gem supports TLS, and comes with a file system driver. Like em-ftpd, you supply a driver, but that driver doesn't need to do much. Here's a bare-minimum FTP server that accepts any username/password, and serves files out of a temporary directory:
require 'ftpd'
require 'tmpdir'
class Driver
def initialize(temp_dir)
#temp_dir = temp_dir
end
def authenticate(user, password)
true
end
def file_system(user)
Ftpd::DiskFileSystem.new(#temp_dir)
end
end
Dir.mktmpdir do |temp_dir|
driver = Driver.new(temp_dir)
server = Ftpd::FtpServer.new(driver)
server.start
puts "Server listening on port #{server.bound_port}"
gets
end
NOTE: This example allows an FTP client to upload, delete, rename, etc.
To enable TLS:
include Ftpd::InsecureCertificate
...
server.certfile_path = insecure_certfile_path
server.tls = :explicit
server.start
Disclosure: I am ftpd's author and current maintainer
take a look at this gem, a Lightweight FTP server framework built on the EventMachine
https://github.com/yob/em-ftpd

Automatically adding proxy to all HTTP connections in ruby

I have an application that initiates multiple HTTP connections and I would like to add a proxy to all connections.
The application is using net/HTTP, TCP sockets and open-uri so ideally I would like to be able to patch all connections initiated from those libraries instead of adding it manually to each and every location in the code that initiates a connection.
Is there a way to accomplish that (on Ruby 1.9.2)?
Open URI uses the HTTP_PROXY environment variable
Here is an article on how to use it on both windows and unix variants.
http://kaamka.blogspot.com/2009/06/httpproxy-environment-variable.html
you can also set it directly in ruby using the ENV hash
ENV['HTTP_PROXY'] = 'http://username:password#hostname:port'
the net/http documentation says not to rely on the environment and set it each time
require 'net/http'
require 'uri'
proxy_host = 'your.proxy.host'
proxy_port = 8080
uri = URI.parse(ENV['http_proxy'])
proxy_user, proxy_pass = uri.userinfo.split(/:/) if uri.userinfo
Net::HTTP::Proxy(proxy_host, proxy_port,
proxy_user, proxy_pass).start('www.example.com') {|http|
# always connect to your.proxy.addr:8080 using specified username and password
:
}
from http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/HTTP.html
Yes and mechanize does too (this is for the 1.0.0 verison)
require 'mechanize'
url = 'http://www.example.com'
agent = Mechanize.new
agent.user_agent_alias = 'Mac Safari'
agent.set_proxy('127.0.0.1', '3128')
#page = agent.get(:url => url)

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