From 7d4142abc2a9b873ba99b4987e2efd1bfff5bb01 Mon Sep 17 00:00:00 2001 From: Martin Lensment Date: Thu, 19 Jun 2014 16:58:43 +0300 Subject: [PATCH] Apache SSL configuration, basic tests for Registry app via mod_epp --- Gemfile | 10 +++ Gemfile.lock | 38 ++++++--- README.md | 94 +++++++++++++++------- app/controllers/epp/sessions_controller.rb | 6 +- app/views/epp/sessions/login.xml | 14 ---- app/views/epp/sessions/login.xml.builder | 12 +++ config/routes.rb | 3 +- spec/epp/requests/login.xml | 23 ++++++ spec/epp/session_spec.rb | 27 ++++++- spec/support/epp.rb | 9 +++ 10 files changed, 172 insertions(+), 64 deletions(-) delete mode 100644 app/views/epp/sessions/login.xml create mode 100644 app/views/epp/sessions/login.xml.builder create mode 100644 spec/epp/requests/login.xml create mode 100644 spec/support/epp.rb diff --git a/Gemfile b/Gemfile index 9f9e12904..2d3a56e59 100644 --- a/Gemfile +++ b/Gemfile @@ -49,12 +49,19 @@ group :development do end group :development, :test do + #EPP client + gem 'epp', '~> 1.4.0' + + # Replacement for fixtures gem 'fabrication', '~> 2.11.3' # Library to generate fake data gem 'faker', '~> 1.3.0' + #For XML parsing + gem 'nokogiri', '~> 1.6.2.1' + # For debugging gem 'pry' gem 'pry-byebug' @@ -64,4 +71,7 @@ group :development, :test do # Additional matchers for RSpec gem 'shoulda-matchers', '~> 2.6.1', require: false + + # For unique IDs (used by the epp gem) + gem 'uuidtools', '~> 2.1.4' end diff --git a/Gemfile.lock b/Gemfile.lock index 5b63e8b77..3d3303e1c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -29,9 +29,9 @@ GEM tzinfo (~> 1.1) arel (5.0.1.20140414130214) builder (3.2.2) - byebug (1.1.1) - columnize (~> 0.3.6) - debugger-linecache (~> 1.2.0) + byebug (2.7.0) + columnize (~> 0.3) + debugger-linecache (~> 1.2) coderay (1.1.0) coffee-rails (4.0.1) coffee-script (>= 2.2.0) @@ -40,9 +40,12 @@ GEM coffee-script-source execjs coffee-script-source (1.7.0) - columnize (0.3.6) + columnize (0.8.9) debugger-linecache (1.2.0) diff-lcs (1.2.5) + epp (1.4.0) + hpricot + libxml-ruby erubis (2.7.0) execjs (2.2.0) fabrication (2.11.3) @@ -56,8 +59,9 @@ GEM haml (>= 3.1, < 5.0) railties (>= 4.0.1) hike (1.2.3) + hpricot (0.8.6) i18n (0.6.9) - jbuilder (2.1.0) + jbuilder (2.1.1) activesupport (>= 3.0.0, < 5) multi_json (~> 1.2) jquery-rails (3.1.0) @@ -66,22 +70,26 @@ GEM json (1.8.1) kgio (2.9.2) libv8 (3.16.14.3) + libxml-ruby (2.7.0) mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) method_source (0.8.2) mime-types (1.25.1) - minitest (5.3.4) + mini_portile (0.6.0) + minitest (5.3.5) multi_json (1.10.1) + nokogiri (1.6.2.1) + mini_portile (= 0.6.0) pg (0.17.1) polyglot (0.3.5) - pry (0.10.0) - coderay (~> 1.1.0) - method_source (~> 0.8.1) + pry (0.9.12.6) + coderay (~> 1.0) + method_source (~> 0.8) slop (~> 3.4) - pry-byebug (1.0.1) - byebug (~> 1.1.1) - pry (>= 0.9.10) + pry-byebug (1.3.2) + byebug (~> 2.7) + pry (~> 0.9.12) rack (1.5.2) rack-test (0.6.2) rack (>= 1.0) @@ -156,24 +164,27 @@ GEM coffee-rails tzinfo (1.2.1) thread_safe (~> 0.1) - uglifier (2.5.0) + uglifier (2.5.1) execjs (>= 0.3.0) json (>= 1.8.0) unicorn (4.8.3) kgio (~> 2.6) rack raindrops (~> 0.7) + uuidtools (2.1.4) PLATFORMS ruby DEPENDENCIES coffee-rails (~> 4.0.0) + epp (~> 1.4.0) fabrication (~> 2.11.3) faker (~> 1.3.0) haml-rails (~> 0.5.3) jbuilder (~> 2.0) jquery-rails + nokogiri (~> 1.6.2.1) pg pry pry-byebug @@ -187,3 +198,4 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) unicorn + uuidtools (~> 2.1.4) diff --git a/README.md b/README.md index a1827e7c1..2c6ec27ed 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,71 @@ index d8c463e..7f6e320 100644 * `sudo apxs2 -a -c -i mod_epp.c` * `sudo a2enmod cgi` -* `sudo a2enmod authn_file` +* `sudo a2enmod authn_file` (Will be used for non implicit authentication URIs, can be removed in the future) * `sudo a2enmod proxy_http` -* `sudo htpasswd -c /etc/apache2/htpasswd test` +* `sudo htpasswd -c /etc/apache2/htpasswd test` (can be removed in the future) * Type "test" when prompted * `cd /usr/lib/cgi-bin` * `mkdir epp` -* Copy the files from $mod_epp/examples/cgis to /usr/lib/cgi-bin/epp (this is just for now) -* `cd /etc/apache2/sites-available` -* `nano epp.conf` +* Copy the files from $mod_epp/examples/cgis to /usr/lib/cgi-bin/epp (once in production, majority of these scripts will not be needed (maybe only double the error script for failover)) +* sudo mkdir /etc/apache2/ssl +* sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache.key -out /etc/apache2/ssl/apache.crt +* `sudo nano /etc/apache2/sites-available/epp_ssl.conf` + +For development configuration, add: +```apache + + + Options ExecCGI + SetHandler cgi-script + + + Listen 700 + + SSLEngine on + SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL + SSLCertificateFile /etc/apache2/ssl/apache.crt + SSLCertificateKeyFile /etc/apache2/ssl/apache.key + + SSLVerifyClient optional_no_ca + + EPPEngine On + EPPCommandRoot /proxy/command + EPPSessionRoot /proxy/session + ProxyPass /proxy/ http://localhost:8080/epp/ + + EPPErrorRoot /cgi-bin/epp/error + EPPAuthURI implicit + EPPReturncodeHeader X-EPP-Returncode + + +``` + +For plain TCP EPP configuration, see below (may be useful for debugging purposes). + +* `sudo a2ensite epp_ssl` +* `sudo service apache2 restart` + +Try it out: + +* Fire up your appserver (This setup is tested with Unicorn) +* `cd $mod_epp` +* `./epptelnet.pl localhost 1701` + +You should receive the greeting from the registry server. +Wait for the greeting message on the STD, then send EPP/TCP frame: + +```xml + + + test + test + + sample1trid + +``` + +Configuration on plain TCP EPP is as follows: Add: ```apache @@ -81,29 +137,7 @@ Add: ``` -* `sudo a2ensite epp` -* `sudo service apache2 restart` - -Try it out: - -* Fire up your appserver (I tested this setup with Unicorn) -* `cd $mod_epp` -* `./epptelnet.pl localhost 1701` - -You should receive the greeting from the registry server. -Wait for a complete paragraph of text on STDIN before sending EPP/TCP frame. - -```xml - - - test - test - - sample1trid - -``` - -Alternative virtual host config is as follows: +For debugging purposes, standalone CGI scripts can be used: This needs a static greeting file, so you will have to make /var/www writable. ```apache @@ -120,11 +154,9 @@ This needs a static greeting file, so you will have to make /var/www writable. EPPCommandRoot /cgi-bin/epp/command EPPSessionRoot /cgi-bin/epp/session EPPErrorRoot /cgi-bin/epp/error - # we can redirect to static pages. + Alias /cgi-bin/epp/session/hello /var/www/html/epp/session-hello - - # or to specialized scripts Alias /cgi-bin/epp/session/login /usr/lib/cgi-bin/epp/session-login Alias /cgi-bin/epp/session/logout /usr/lib/cgi-bin/epp/session-logout Alias /cgi-bin/epp/error/schema /usr/lib/cgi-bin/epp/error-schema diff --git a/app/controllers/epp/sessions_controller.rb b/app/controllers/epp/sessions_controller.rb index 468e8f167..5f8baf88a 100644 --- a/app/controllers/epp/sessions_controller.rb +++ b/app/controllers/epp/sessions_controller.rb @@ -1,13 +1,15 @@ class Epp::SessionsController < ApplicationController protect_from_forgery with: :null_session - def greeting; end - def proxy send(params[:command]) end private + def hello + render 'greeting' + end + def login render 'login' end diff --git a/app/views/epp/sessions/login.xml b/app/views/epp/sessions/login.xml deleted file mode 100644 index de3af441e..000000000 --- a/app/views/epp/sessions/login.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - User test was authenticated. Welcome. - - - sample1trid - - - diff --git a/app/views/epp/sessions/login.xml.builder b/app/views/epp/sessions/login.xml.builder new file mode 100644 index 000000000..52b3545c0 --- /dev/null +++ b/app/views/epp/sessions/login.xml.builder @@ -0,0 +1,12 @@ +xml.instruct! +xml.epp('xmlns' => 'urn:ietf:params:xml:ns:epp-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd') do + xml.response do + xml.result('code' => '1000') do + xml.msg('User test was authenticated. Welcome.', 'lang' => 'en') + end + end + + xml.trID do + xml.clTRID 'sample1trid' + end +end diff --git a/config/routes.rb b/config/routes.rb index 00446ca88..d251ff636 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,6 @@ Rails.application.routes.draw do namespace(:epp) do - get 'session/hello', to: 'sessions#greeting', defaults: { format: :xml } - post 'session/:command', to: 'sessions#proxy', defaults: { format: :xml } + match 'session/:command', to: 'sessions#proxy', defaults: { format: :xml }, via: [:get, :post] end # The priority is based upon order of creation: first created -> highest priority. diff --git a/spec/epp/requests/login.xml b/spec/epp/requests/login.xml new file mode 100644 index 000000000..44ea0eabd --- /dev/null +++ b/spec/epp/requests/login.xml @@ -0,0 +1,23 @@ + + + + + test + test + + 1.0 + en + + + http://www.nic.cz/xml/epp/contact-1.6 + http://www.nic.cz/xml/epp/nsset-1.2 + http://www.nic.cz/xml/epp/domain-1.4 + http://www.nic.cz/xml/epp/keyset-1.3 + + http://www.nic.cz/xml/epp/enumval-1.2 + + + + wgyn001#10-02-08at13:58:06 + + diff --git a/spec/epp/session_spec.rb b/spec/epp/session_spec.rb index c2f32300b..b00cb43a2 100644 --- a/spec/epp/session_spec.rb +++ b/spec/epp/session_spec.rb @@ -1,5 +1,28 @@ require 'rails_helper' -describe "EPP Session" do - it "greets client upon connection" +describe 'EPP Session', type: :epp do + let(:server) { server = Epp::Server.new({server: 'localhost', tag: 'test', password: 'test'}) } + + context 'when not connected' do + it 'greets client upon connection' do + response = Nokogiri::XML(server.open_connection) + expect(response.css('epp svID').text).to eq('EPP server (DSDng)') + server.close_connection + end + end + + context 'when connected' do + before(:each) { server.open_connection } + after(:each) { server.close_connection } + + it 'logs in epp user' do + response = Nokogiri::XML(server.send_request(read_body('login.xml'))) + + result = response.css('epp response result').first + expect(result[:code]).to eq('1000') + + msg = response.css('epp response result msg').text + expect(msg).to eq('User test was authenticated. Welcome.') + end + end end diff --git a/spec/support/epp.rb b/spec/support/epp.rb new file mode 100644 index 000000000..1e30a9deb --- /dev/null +++ b/spec/support/epp.rb @@ -0,0 +1,9 @@ +module Epp + def read_body(filename) + File.read("spec/epp/requests/#{filename}") + end +end + +RSpec.configure do |c| + c.include Epp, type: :epp +end