Skip to content

Instantly share code, notes, and snippets.

@haslo
Last active August 24, 2020 21:10
Show Gist options
  • Save haslo/72c3453e93bf51a239518719fabdeb27 to your computer and use it in GitHub Desktop.
Save haslo/72c3453e93bf51a239518719fabdeb27 to your computer and use it in GitHub Desktop.
Proxy for Tabletop Simulator's Unity HTTPS problems

What's this?

The Tabletop Simulator uses Unity, which doesn't quite work on Mac OS when it comes to TLS connections - due to using SSLv2, which is insecure and blocked everywhere.

http://www.berserk-games.com/forums/showthread.php?2628-Linux-amp-OSX-make-requests-for-assets-via-SSLv3-and-fail

There's this solution, but it didn't work for me because I didn't find the modules in question.

https://www.reddit.com/r/tabletopsimulator/comments/4qwww5/i_wrote_a_perl_script_for_osx_and_linux_users/

Proxy

The solution was, of course, to write a little Proxy. paste.ee requires the hostname in the request, so to avoid hacking my own request from scratch I just juggle the hosts file (with delays, to make sure Ruby picks up the change) and let Webrick do the heavy lifting.

This proxy receives requests from Tabletop Simulator, forwards them to paste.ee, and returns them. Because the Unity guys are lenient with other bits of security, too, and only check the hostname in the certificate and not whether there's a valid certificate chain, I can just set my self-signed certificate to "I'm paste.ee, honest!", and they'll believe me.

Howto

How to use, given Ruby and the webrick gem (gem install webrick):

  1. copy your /etc/hosts to /etc/hosts_with_bypass and /etc/hosts_without_bypass
  2. add this as last line to /etc/hosts_with_bypass

127.0.0.1 paste.ee

Then, simply run:

sudo ruby unity_proxy.rb

sudo becuase you're listening to port 443, and only root is allowed to do that. Stop with Ctrl-C after you're done - this will also clean up the hosts file again.

If you use other modules with other hosts, you'll have to rewrite /etc/hosts differently, and change the URI and the certificate's host name. It doesn't always work, but most of the time (just ignore the handshake error messages when it's loading models).

#!/bin/ruby
require 'uri'
require 'net/https'
require 'webrick'
require 'webrick/https'
cert_name = [ %w[CN paste.ee] ]
server = WEBrick::HTTPServer.new(:Port => 443, :SSLEnable => true, :SSLCertName => cert_name)
trap 'INT' do
`cp /etc/hosts_without_paste /etc/hosts`
server.shutdown
end
class SimpleProxy < WEBrick::HTTPServlet::AbstractServlet
def do_GET request, response
sleep 1
`cp /etc/hosts_without_bypass /etc/hosts`
sleep 1
uri = URI.parse("https://paste.ee#{request.path}")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
data = http.get(uri.request_uri)
`cp /etc/hosts_with_bypass /etc/hosts`
sleep 1
response.status = 200
response['Content-Type'] = 'text/plain'
response.body = data.body
end
end
server.mount '/', SimpleProxy
`cp /etc/hosts_with_bypass /etc/hosts`
server.start
@lancedjack
Copy link

Hey! This appears to search for a hosts_with_paste file whereas in your GIST you've indicated to rename it to hosts_with_bypass

@haslo
Copy link
Author

haslo commented Mar 22, 2017

Gee, thanks @lancedjack, and sorry for the veeery slow reply. Yes, you're right; it's fixed now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment